[英]SQL: Return Column names where column contains a given Value
我想知道是否可以在SQL Server中运行一个命令/存储的proc,它将为我提供包含表中给定数据的列的名称。
因此,如果要查询,请给我该表中所有包含值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
。
因此,让我们考虑一个简单的表:
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
我同意以上评论,听起来您的方案设计不理想。 如果尝试对大型数据集执行此操作,则可能会遇到性能问题。
就是说,您可以取消透视列以将其转换为行。 这是Technet上“ 使用PIVOT和UNPIVOT”一文的逐字逐句示例。 而不是75,我使用了4:
--Create the table and insert values as portrayed in the previous example.
CREATE TABLE pvt (VendorID int, Emp1 int, Emp2 int,
Emp3 int, Emp4 int, Emp5 int);
GO
INSERT INTO pvt VALUES (1,4,3,5,4,4);
INSERT INTO pvt VALUES (2,4,1,5,5,5);
INSERT INTO pvt VALUES (3,4,3,5,4,4);
INSERT INTO pvt VALUES (4,4,2,5,5,4);
INSERT INTO pvt VALUES (5,5,1,5,5,5);
GO
--Unpivot the table.
SELECT VendorID, Employee, Orders
FROM
(SELECT VendorID, Emp1, Emp2, Emp3, Emp4, Emp5
FROM pvt) p
UNPIVOT
(Orders FOR Employee IN
(Emp1, Emp2, Emp3, Emp4, Emp5)
)AS unpvt
WHERE VendorID = 1 AND orders = 4;
这将产生以下结果:
+--+----------------------------------------+ | | VendorID Employee Orders | +--+----------------------------------------+ | | 1 Emp1 4 | | | 1 Emp4 4 | | | 1 Emp5 4 | +--+----------------------------------------+
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.