SQL:如何使用Information_schema中的Table_Name和Pivoted Column_Name构建选择查询

时间:2015-04-17 01:10:08

标签: sql sql-server sql-server-2008

我已经编写了一些查询的SQL查询,我稍后在Cursors中使用它来运行每一行。他们利用了Information_Schema,Table_Name,Column_name,我最近刚刚从论坛中了解了如何做。下面是一个用于从多个表中删除带有条件的行的查询示例。我遗漏了游标代码,因为我只专注于尝试构建选择查询。

DECLARE @devCodeDELETE varchar(20);
SET @devCodeDELETE = '001e';

SELECT 'DELETE FROM ' + TABLE_NAME + ' WHERE devCode = '''+ @devCodeDELETE +''';'
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME like 'DEV_%';

上面的输出然后通过游标代码运行:

DELETE FROM DEV_assembly WHERE devCode = '001e';
DELETE FROM DEV_comments WHERE devCode = '001e';
DELETE FROM DEV_costhistory WHERE devCode = '001e';
DELETE FROM DEV_dates WHERE devCode = '001e';
DELETE FROM DEV_master WHERE devCode = '001e';
etc...

这对于构建针对多个表的批量更新查询非常有效,因为所有表都与列“devCode”连接。

我似乎无法弄清楚如何使用Table_Name,Column_Name和Information_Schema来编写一个选择查询,该查询将使用它的源表来旋转(它是一个数据库吗?)列名。甚至不确定是否可能。

我现在想要实现的输出是:

table1 table1.c1 table1.c2 table1.c3, etc
table2 table2.c1 table2.c2 table2.c3, table2.c4, table2.c5,etc
table3 table3.c1 table3.c3 table2.c3, table2.c4,etc
etc....

我用不同数量的列显示每一行,以说明每个具有不同列数的表。 如果我能做到这一点,我会进行必要的更改,使每一行成为一个查询。

非常感谢任何帮助。提前谢谢。

-UPDATE ----

感谢下面的Brian,我对我的架构进行了编辑:

declare @TableName as varchar(256)
declare @ColumnName as varchar(256)
declare @str as varchar(max)
declare @outstring as varchar(max)

select TABLE_NAME, COLUMN_NAME 
into #temp
from INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME LIKE 'DEV_%' AND COLUMN_NAME <> 'devCode' AND COLUMN_NAME NOT LIKE 'ID%'

select distinct TABLE_NAME, CONVERT(varchar(max),'') outstring 
into #tempout
from #temp

Declare TableNames cursor FORWARD_ONLY FOR
select * from #tempout
for update of outstring

open TableNames

fetch Next From TableNames into @TableName, @outstring
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @outstring = ''
    SELECT @outstring = @outstring + ', ' + COLUMN_NAME
    FROM #temp
    WHERE TABLE_NAME = @TableName

    UPDATE #tempout 
    SET outstring = @outstring
    WHERE CURRENT OF TableNames 

    fetch Next From TableNames into @TableName, @ColumnName
END

close TableNames
deallocate TableNames

select 'INSERT INTO ' + TABLE_NAME + '(devCode' + outstring + ') SELECT ''newCode'',' + SUBSTRING(outstring,2,99999) +' FROM ' + TABLE_NAME + ' WHERE devCode = ''oldCode'';' from #tempout

输出符合要求!那将进入另一个游标来运行每一行。

INSERT INTO DEV_assembly(devCode, asmNote, asmUser) SELECT 'newCode', asmNote, asmUser FROM DEV_assembly WHERE devCode = 'oldCode';
INSERT INTO DEV_comments(devCode, comComment, comDate, comStatus, comExternal) SELECT 'newCode', comComment, comDate, comStatus, comExternal FROM DEV_comments WHERE devCode = 'oldCode';
INSERT INTO DEV_costhistory(devCode, costDate, costQuote, costFactory, costNote, costTimeStamp, costSelect) SELECT 'newCode', costDate, costQuote, costFactory, costNote, costTimeStamp, costSelect FROM DEV_costhistory WHERE devCode = 'oldCode';
INSERT INTO DEV_dates(devCode, datesRecord, datesNote, datesDue, datesStatus, datesComplete) SELECT 'newCode', datesRecord, datesNote, datesDue, datesStatus, datesComplete FROM DEV_dates WHERE devCode = 'oldCode';
INSERT INTO DEV_dimensions(devCode, dimNote, dimDimension) SELECT 'newCode', dimNote, dimDimension FROM DEV_dimensions WHERE devCode = 'oldCode';
etc....

1 个答案:

答案 0 :(得分:1)

如果不事先知道列,就不能执行SQL数据透视表...除非你做一些动态SQL。即使这样,列数也是固定的,因此你有一个庞大的列列表,一列用于整个数据库中的每个列标题。

你可以做的是在所有表中运行游标以构建一个包含你需要的所有列的字符串......例如:

declare @TableName as varchar(256)
declare @ColumnName as varchar(256)
declare @str as varchar(max)
declare @outstring as varchar(max)

select TABLE_NAME, COLUMN_NAME 
into #temp
from INFORMATION_SCHEMA.COLUMNS

select distinct TABLE_NAME, CONVERT(varchar(max),'') outstring 
into #tempout
from #temp

Declare TableNames cursor FORWARD_ONLY FOR
select * from #tempout
for update of outstring

open TableNames

fetch Next From TableNames into @TableName, @outstring
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @outstring = ''
    SELECT @outstring = @outstring + ' ' + COLUMN_NAME
    FROM #temp
    WHERE TABLE_NAME = @TableName

    UPDATE #tempout 
    SET outstring = @outstring
    WHERE CURRENT OF TableNames 

    fetch Next From TableNames into @TableName, @ColumnName
END

close TableNames
deallocate TableNames

select * from #tempout