【问题标题】:How to loop through all columns in all tables in SQL server database and return column names juxtaposed with column values?如何遍历 SQL Server 数据库中所有表中的所有列并返回与列值并列的列名?
【发布时间】:2014-05-12 13:45:03
【问题描述】:

我需要遍历我的 sql server 数据库中的所有表,对于每个表,我需要返回所有行的值,但棘手的是我需要将列名元数据与该列的值并排返回.

例如,

column1 collumn2 column3
A   B   C
AA  BB  CC

为了这张表,我需要返回

column1     A   collumn2    B   column3 C
column1     AA  collumn2    BB  column3 

抄送

我有脚本使用光标循环遍历所有表并在每个表中返回所有列的名称(但不返回值)。

我也有脚本一一返回列名和值,如

column1 A
column1 AA
column2 B
column2 BB
column3 C
column3 CC

但我需要为每一行数据返回一行列元数据 + 列值。有没有人有任何见解?我还在四处闲逛。谢谢!

编辑: 我终于让脚本工作了

drop table #results
CREATE TABLE #Results (TypeColumnName nvarchar(100), TypeColumnValue int, CodeValueName nvarchar(100), CodeValueValue nvarchar(100), DescriptionName nvarchar(100), DescriptionValue nvarchar(1024) )

    SET NOCOUNT ON

    DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @sql nvarchar(max), @sql0 nvarchar(max)
    SET  @TableName = ''


    WHILE @TableName IS NOT NULL
    BEGIN

        SET @ColumnName = ''
        set @sql=''
        SET @TableName = 
        (
            SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
            FROM    INFORMATION_SCHEMA.TABLES
            WHERE       TABLE_TYPE = 'BASE TABLE'
            and table_schema = 'test'
            and table_name like 'sales%'
                AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
        )

        WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)
        BEGIN

            SET @ColumnName =
            (
                SELECT MIN(QUOTENAME(COLUMN_NAME))
                FROM    INFORMATION_SCHEMA.COLUMNS
                WHERE       TABLE_SCHEMA    = PARSENAME(@TableName, 2)
                    AND TABLE_NAME  = PARSENAME(@TableName, 1)
                    AND QUOTENAME(COLUMN_NAME) > @ColumnName
            )
            IF @ColumnName IS NOT NULL
            BEGIN
                --select @columnname
                set @sql = @sql + '''' + @TableName + '.' + @ColumnName + ''',' + @ColumnName + ', '

            END
            ELSE
            begin
            SET @sql = left(rtrim(@sql),Len(rtrim(@sql))-1) 
            set @sql = 'SELECT ' + @sql +   ' FROM ' + @TableName + ' (NOLOCK) ' 

    select @sql 
    INSERT INTO #Results
                EXEC sp_executesql @sql 
    end


END

end

【问题讨论】:

  • 你用什么语言编程?你希望你的输出去哪里?到文件?到屏幕上?
  • 也许如果你说你在用数据做什么,我们可以提供更好的建议。
  • T-SQL。我希望输出转到全局临时表。谢谢!
  • @cometbill,我需要这个输出,因为我将遍历这个输出并使用列名和值构造 CASE WHEN 语句。谢谢

标签: sql-server


【解决方案1】:

这能让你开始吗?

select t.name, c.name, c.system_type_id , c.max_length 
         ,Case c.system_type_id
         when 167 then 'VarChar'
         When 231 then 'nVarChar'
         when 4 then 'Integer'
         when 56 then 'int'
         when 61 then 'DateTime'
         else 'Unknown'
         End 
   from sys.tables t
 inner join sys.columns c
    on c.object_id = t.object_id 
 order by t.name, c.column_ID

我拼凑的这个 T-SQL 在 SQL Server 2008 R2 中工作

您可以使用 sp_help 找出其他“未知”列类型,并自己将它们添加到 case 语句中。

【讨论】:

  • 非常感谢@cometbill - 不幸的是,这只是给了我元数据,而除了列名之外,我还需要查看列的实际值,以便我可以构造 case 语句。这主要用于查找表,例如具有代码和描述列,因此我可以将 case 语句构建为 case when [code column name] = 'code value' then [description column name] = 'description value'
  • @Wendy 你想要元数据和数据吗?一旦您拥有包含一些数据的字段,您就可以确定字段类型。我不确定为什么仅当代码值是某个代码时才要设置描述值。我很困惑。
【解决方案2】:

使用 UNPIVOT 功能:

SELECT col1, colval FROM ( SELECT col1, col2, col3 FROM table1 ) UNPIVOT ( colval for colname IN (col2, col3) ) as unpiv

您可以根据需要在不同位置添加连接和 where 子句以进行过滤。在我的一个应用程序中,我过滤并加入了第一个查询,然后将最终结果加入到更多的表中,等等......

您也可以以非常相似的方式使用 PIVOT 功能执行相反的操作。查看联机丛书了解这两个功能...我认为它们会为您解决问题。

【讨论】:

  • 约翰,我忘记了 UNPIVOT 函数 - 我只是对它进行了一些试验,但它仍然无法解决我的问题,因为我还需要提取列名。但是有这个方便是很好的。非常感谢!
  • 当我运行它时,我得到列名和相应的值。所以基本上它把我的宽桌子变成了一张高桌子。我认为,如果您继续尝试,它将满足您的需求。
猜你喜欢
  • 1970-01-01
  • 2021-02-11
  • 1970-01-01
  • 2011-02-13
  • 1970-01-01
  • 2020-06-18
  • 2018-02-07
  • 1970-01-01
  • 2018-10-28
相关资源
最近更新 更多