我想复制我在SQL Server中的所有表,所有表名都应该在开头添加“ temp”。并且所有这些都将添加一个额外的列(全部相同)。我不需要完整的代码,而只是一般性的想法。
答案 0 :(得分:1)
尝试此代码:
获取所有表名形式的信息模式并运行动态sql创建表
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
答案 1 :(得分:1)
一种直接的方法:
您已经有了使用光标的解决方案。这是没有光标的一个:
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);
备注:CHAR(13)+ CHAR(10)不是必需的;如果您想首先检查脚本(使用PRINT而不是EXEC),则只是为了提高可读性而添加。
编辑:
注释中的一个附加问题可以在结果表中添加校验和值,如下所示:
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);
使用HASHBYTES代替CHECKSUM可能更好,但是它仅接受两个参数:哈希算法和要哈希的单个值。因此,在这种情况下,您可能需要通过手动连接表的所有字段来传递字符串值,而在像我这样的动态查询中添加它可能有些麻烦。这可能会导致事情复杂,而不仅仅是三行...
嗯,实际上是这样的:
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);
备注:
[Tables]
(用于以逗号分隔的字符串值连接每个表的列名)中,我从最后一列开始,并向后移动以缓解主查询中的过滤条件。N''
的{{1}}调用中添加了一个附加的第一个参数CONCAT
,因为@script
函数需要至少2个参数,这很麻烦在这种情况下,只处理一列的表。在这种情况下,尽管性能稍差,但使用游标可能更清晰,更容易,如@HasanMahmood在其答案中建议的那样...