SQL: Return Column names where column contains a given Value

后端 未结 2 719
无人及你
无人及你 2021-01-17 03:52

i was wondering if there was a command/stored proc i can run in SQL Server that will give me the names of columns that contain given data within a table.

So if i was

相关标签:
2条回答
  • 2021-01-17 04:06
    -- 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;
    

    When you are happy with the output, uncomment the EXEC.

    So let's consider a simple table:

    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());
    

    Now, a stored procedure based on the above code:

    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
    

    Sample usage:

    EXEC dbo.FindStringInAnyColumn @table = N'floob', @value = '75';
    

    Output:

    Cols: a, b
    
    0 讨论(0)
  • 2021-01-17 04:18

    I agree with the above comments that it sounds like you have a suboptimal schema design. You will probably run into performance issues if you try to do this on a large data set.

    That said, you could unpivot the columns to convert them to rows. Here is an example lifted verbatim from the Using PIVOT and UNPIVOT article on Technet. Instead of 75, I used 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;
    

    This yields the following result:

    +--+----------------------------------------+
    |  | VendorID        Employee        Orders |
    +--+----------------------------------------+
    |  | 1               Emp1            4      |
    |  | 1               Emp4            4      |
    |  | 1               Emp5            4      |
    +--+----------------------------------------+
    
    0 讨论(0)
提交回复
热议问题