选择具有指定值的列名称

时间:2014-05-05 21:11:39

标签: sql sql-server

我们正在接收相当大的文件,我们无法控制其格式,这些文件通过SSIS批量加载到SQL Server表中,以便稍后导入到我们的内部结构中。这些文件可以包含800多个列,通常列名称无法立即识别。

因此,我们有一个大表,表示文件内容超过800 Varchar列。

问题是:我知道我在这个数据中寻找的具体值,但我不知道哪个列包含它。并且通过观察数据以找到所述列既不高效也不理想。

我的问题是:是否可以通过某个值N搜索表并返回具有该值的列名?我发布了一些我尝试过的代码,但我真的不知道从哪里开始...或者甚至可能。

例如:

A   B   C   D   E   F   G   H   I   J   K   L   M   N   ...
------------------------------------------------------------
'a' 'a' 'a' 'a' 'a' 'b' 'a' 'a' 'a' 'b' 'b' 'a' 'a' 'c' ...

如果我要在此表中搜索值'b',我会想要取回以下结果:

Columns
---------
F
J
K

这样的事可能吗?

3 个答案:

答案 0 :(得分:2)

此脚本将搜索所有表和所有字符串列以查找特定字符串。您可以根据自己的需要进行调整:

DECLARE @tableName sysname
DECLARE @columnName sysname
DECLARE @value varchar(100)
DECLARE @sql varchar(2000)
DECLARE @sqlPreamble varchar(100)

SET @value = 'EDUQ4' -- *** Set this to the value you're searching for *** --

SET @sqlPreamble = 'IF EXISTS (SELECT 1 FROM '

DECLARE theTableCursor CURSOR FAST_FORWARD FOR 
    SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
     WHERE TABLE_SCHEMA = 'dbo' AND TABLE_TYPE = 'BASE TABLE' 
       AND TABLE_NAME NOT LIKE '%temp%' AND TABLE_NAME != 'dtproperties' AND TABLE_NAME != 'sysdiagrams'
     ORDER BY TABLE_NAME

OPEN theTableCursor
FETCH NEXT FROM theTableCursor INTO @tableName

WHILE @@FETCH_STATUS = 0 -- spin through Table entries
BEGIN
    DECLARE theColumnCursor CURSOR FAST_FORWARD FOR
        SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
         WHERE TABLE_NAME = @tableName AND (DATA_TYPE = 'nvarchar' OR DATA_TYPE = 'varchar')
         ORDER BY ORDINAL_POSITION

    OPEN theColumnCursor
    FETCH NEXT FROM theColumnCursor INTO @columnName

    WHILE @@FETCH_STATUS = 0 -- spin through Column entries
    BEGIN
        SET @sql = @tableName + ' WHERE ' + @columnName + ' LIKE ''' + @value + 
                   ''') PRINT ''Value found in Table: ' + @tableName + ', Column: ' +  @columnName + ''''
        EXEC (@sqlPreamble + @sql)
        FETCH NEXT FROM theColumnCursor INTO @columnName
    END
    CLOSE theColumnCursor
    DEALLOCATE theColumnCursor

    FETCH NEXT FROM theTableCursor INTO @tableName
END
CLOSE theTableCursor
DEALLOCATE theTableCursor

答案 1 :(得分:1)

您拥有的一个选择是在SQL Server中使用XML进行创作。

使用交叉应用和查询在第二次交叉应用中具有特定值的节点,一次将一行转换为XML。

最后输出不同的节点名称列表。

declare @Value nvarchar(max)

set @Value= 'b'

select distinct T3.X.value('local-name(.)', 'nvarchar(128)') as ColName
from YourTable as T1
  cross apply (select T1.* for xml path(''), type) as T2(X)
  cross apply T2.X.nodes('*[text() = sql:variable("@Value")]') as T3(X) 

SQL Fiddle

答案 2 :(得分:0)

如果您有权访问这些文件,那么RegEx必须比在SQL中执行通用搜索更快。

如果你被迫使用SQL @ pmbAustin,那么答案是要走的路。请注意,它不会很快跑。