如何修改SQL代码实现仅遍历一次Schema执行操作?
问题分析
- 原代码用
ALTER SCHEMA ... TRANSFER是移动表,每次执行后旧Schema的表数量减少,循环会自然终止; - 改成
INTO是错误用法(ALTER SCHEMA不支持INTO语法),且复制表不会减少旧Schema的表,导致WHILE EXISTS条件永远成立,陷入无限循环; - 要实现仅遍历一次旧Schema的表,核心是先获取初始的旧Schema表列表,再基于这个固定列表循环,而非每次循环都查询当前的旧Schema表。
可行修改方案
先把旧Schema的所有表名存入表变量,再遍历这个表变量执行复制操作,这样只会遍历初始的表列表一次,不会无限循环。同时修正复制表的正确语法(用SELECT ... INTO实现表结构和数据的复制):
DECLARE @sql VARCHAR(8000), @table VARCHAR(1000), @oldschema VARCHAR(1000), @newschema VARCHAR(1000) SET @oldschema = 'Live' SET @newschema = 'Test' -- 创建表变量存储旧Schema的所有初始表名 DECLARE @OldTables TABLE (TableName VARCHAR(1000)) INSERT INTO @OldTables SELECT name FROM sys.tables WHERE schema_name(schema_id) = @oldschema -- 遍历表变量执行复制 WHILE EXISTS(SELECT * FROM @OldTables) BEGIN -- 获取当前要复制的表名 SELECT TOP 1 @table = TableName FROM @OldTables -- 构造复制表的SQL(SELECT ... INTO会在新Schema创建表并复制数据) SET @sql = 'SELECT * INTO [' + @newschema + '].[' + @table + '] FROM [' + @oldschema + '].[' + @table + ']' EXEC(@sql) -- 从表变量中移除已处理的表,避免重复处理 DELETE FROM @OldTables WHERE TableName = @table END
关键说明
- 用表变量
@OldTables存储旧Schema的初始表列表,确保只遍历一次初始的表集合; - 替换错误的
ALTER SCHEMA ... INTO为正确的SELECT ... INTO语法,实现表的复制; - 每次处理完一个表后从表变量中删除,保证循环会正常终止。
如果需要仅复制表结构(不复制数据),可以修改SQL为:
SET @sql = 'SELECT TOP 0 * INTO [' + @newschema + '].[' + @table + '] FROM [' + @oldschema + '].[' + @table + ']'
内容的提问来源于stack exchange,提问作者zypher
相关产品推荐
相关产品推荐

