I've written some SQL queries of queries that I later use in Cursors to run each line. They take advantage of Information_Schema,Table_Name,Column_name, which I recently just picked up how to do from forums. Below is an example of one Query I use to delete rows from multiple tables with a criteria. I've left out the cursor code as I'm only focused on trying to build the select query.
DECLARE @devCodeDELETE varchar(20);
SET @devCodeDELETE = '001e';
SELECT 'DELETE FROM ' + TABLE_NAME + ' WHERE devCode = '''+ @devCodeDELETE +''';'
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME like 'DEV_%';
The above Outputs which is then run through cursor code:
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...
This has been effective for building batch update queries against multiple tables, since all tables join with column "devCode".
I can't seem to figure out how to write a select query that will pivot (is it a pivot?) column names with it's source table, using Table_Name, Column_Name and Information_Schema. Not even sure if it is possible.
The output I'm trying to achieve for now would be :
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....
I displayed each line with different numbers of columns to illustrate each tables having different number of columns. If I can get this far, I make the necessary changes to make each line into a query.
Any help would be much appreciated. Thanks in advance.
-UPDATE----
Thanks to the Brian from below I made edits pertaining to my schema:
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
And the output was as desired! That'll go into a another cursor to run each line.
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....
You can't do a SQL pivot without knowing the columns in advance... unless you do some dynamic SQL. Even then the number of columns is fixed so you'd have an enormous list of columns, one for every column title in the entire database.
What you can do is run a cursor though all the tables to build up a string with all the columns you need... such as:
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.