Reputation: 149
I want to duplicate all my tables in SQL Server, all table names would have had "temp" added at the beginning. And all of them would have had added an extra column (the same to all). I don't need whole code, just general idea how to do it.
Upvotes: 0
Views: 50
Reputation: 3905
A straightforward way to go:
You already have a solution with a cursor. This is one without a cursor:
DECLARE @script VARCHAR(MAX) = '';
SELECT @script = @script + 'SELECT * INTO [temp'+ TABLE_NAME +'] FROM [' + TABLE_NAME + '];' + CHAR(13) + CHAR(10) FROM INFORMATION_SCHEMA.TABLES
EXEC (@script);
Remark: The CHAR(13) + CHAR(10) is not necessary; just added for readability if you want to check the script first (using PRINT instead EXEC).
Edit:
An additional question in the comments to add a checksum value in the resulting tables could be done as follows:
DECLARE @script VARCHAR(MAX) = '';
SELECT @script = @script + 'SELECT CHECKSUM(*) AS [__checksum], * INTO [temp'+ TABLE_NAME +'] FROM [' + TABLE_NAME + '];' + CHAR(13) + CHAR(10) FROM INFORMATION_SCHEMA.TABLES
EXEC (@script);
Using HASHBYTES instead of CHECKSUM is probably better, but it accepts only two parameters: the hash algorithm and a single value to hash. So in that case, you probably need to pass a string value by manually concatenating all the fields of your tables, and that may be somewhat troublesome to add in a dynamic query like mine. It would probably result in something more complex than just three lines...
Well, something like this, actually:
DECLARE @script NVARCHAR(MAX) = N'';
WITH
[Columns] AS
(
SELECT
TABLE_NAME AS [TableName],
COLUMN_NAME AS [ColumnName],
ROW_NUMBER() OVER (PARTITION BY TABLE_NAME ORDER BY ORDINAL_POSITION) AS [ColSeq]
FROM
INFORMATION_SCHEMA.COLUMNS
),
[Tables] AS
(
SELECT
[TableName],
CAST(N'[' + [ColumnName] + N']' AS NVARCHAR(MAX)) AS [ColumnList],
[ColSeq]
FROM
[Columns] AS C
WHERE
[ColSeq] = (SELECT MAX([ColSeq])
FROM [Columns]
WHERE [TableName] = C.[TableName])
UNION ALL
SELECT T.[TableName], N'[' + C.[ColumnName] + N'], ' + T.[ColumnList], C.[ColSeq]
FROM
[Tables] AS T
INNER JOIN [Columns] AS C ON C.[TableName] = T.[TableName] AND C.[ColSeq] = T.[ColSeq] - 1
)
SELECT @script = @script + N'SELECT HASHBYTES(''md5'', CONCAT(N'''', ' + [ColumnList] + N')) AS [__checksum], * INTO [temp' + [TableName] + N'] FROM [' + [TableName] + N'];' + NCHAR(13) + NCHAR(10)
FROM [Tables]
WHERE [ColSeq] = 1;
EXEC (@script);
Remarks:
[Tables]
, which is used for concatenating the column names of each table in a comma-separated string value, I started at the last column and moved backwards to ease the filter condition in my main query.N''
to the CONCAT
calls in the resulting @script
contents, since the CONCAT
function requires at least 2 arguments, which would be troublesome in this case when processing tables with just one column.In this case, despite the somewhat worse performance, it might be clearer and easier to fall back to using a cursor, like @HasanMahmood suggested in his answer...
Upvotes: 1
Reputation: 978
try this code:
get all the table name form information schema and run a dynamic sql to create tables
DECLARE @script varchar(max)
DECLARE db_cursor CURSOR FOR
SELECT script = 'Select * Into [temp'+ TABLE_NAME +'] From ' + QUOTENAME(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @script
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC(@script)
--PRINT @script
FETCH NEXT FROM db_cursor INTO @script
END
CLOSE db_cursor
DEALLOCATE db_cursor
Upvotes: 1