我想知道是否可以在SQL Server中运行一个命令/存储的程序,该程序将为我提供包含表中给定数据的列的名称。
因此,如果我要查询,请给我该表中所有包含值75的列。我不希望该行。只是表中的列名…这可能吗?
-- input parameters (guessing on type for @value): DECLARE @schema SYSNAME = N'dbo', @table SYSNAME = N'z', @value VARCHAR(64) = '75'; -- now, inside the procedure body: DECLARE @sql NVARCHAR(MAX) = N'SELECT ''cols:'' + STUFF('''''; SELECT @sql += N' + CASE WHEN EXISTS (SELECT 1 FROM ' + QUOTENAME(@schema) + '.' + QUOTENAME(@table) + ' WHERE TRY_CONVERT(VARCHAR(64), ' + QUOTENAME(c.name) + ') = @value) THEN '', ' + c.name + ''' ELSE '''' END' FROM sys.tables AS t INNER JOIN sys.columns AS c ON t.[object_id] = c.[object_id] INNER JOIN sys.schemas AS s ON t.[schema_id] = s.[schema_id] WHERE t.name = @table AND s.name = @schema; SET @sql += N', 1, 1, '''');' PRINT @sql; --EXEC sp_executesql @sql, N'@value VARCHAR(64)', @value;
当您对输出感到满意时,请取消注释EXEC。
EXEC
因此,让我们考虑一个简单的表:
CREATE TABLE dbo.floob ( a INT, b VARCHAR(32), c VARBINARY(22), d DATE, e DATETIME, f ROWVERSION ); INSERT dbo.floob(a,b,c,d,e) VALUES ( 75, 'foo', 0x00, GETDATE(), GETDATE()), ( 21, '75', 0x00, GETDATE(), GETDATE());
现在,基于上述代码的存储过程:
CREATE PROCEDURE dbo.FindStringInAnyColumn @schema SYSNAME = N'dbo', @table SYSNAME, @value VARCHAR(64) AS BEGIN SET NOCOUNT ON; DECLARE @sql NVARCHAR(MAX) = N'SELECT ''cols:'' + STUFF('''''; SELECT @sql += N' + CASE WHEN EXISTS (SELECT 1 FROM ' + QUOTENAME(@schema) + '.' + QUOTENAME(@table) + ' WHERE TRY_CONVERT(VARCHAR(64), ' + QUOTENAME(c.name) + ') = @value) THEN '', ' + c.name + ''' ELSE '''' END' FROM sys.tables AS t INNER JOIN sys.columns AS c ON t.[object_id] = c.[object_id] INNER JOIN sys.schemas AS s ON t.[schema_id] = s.[schema_id] WHERE t.name = @table AND s.name = @schema; SET @sql += N', 1, 1, '''');' EXEC sp_executesql @sql, N'@value VARCHAR(64)', @value; END GO
用法示例:
EXEC dbo.FindStringInAnyColumn @table = N'floob', @value = '75';
输出:
Cols: a, b