我已经编写了一些查询的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....
答案 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