循环内将查询结果插入临时表报错:对象'#TT'已存在
解决WHILE循环内SELECT INTO临时表的报错问题
错误原因
报错提示“数据库中已存在名为'#TT'的对象”,核心原因是SELECT * INTO #TT语句的作用是创建新表并插入查询结果。如果循环执行多次,第一次循环会成功创建#TT,后续循环再执行SELECT INTO时,由于表已存在就会触发错误。
另外你原代码中@V_START初始值为1,第一次循环后加10变为11,不满足@V_START < 4的条件,循环实际只执行一次。如果仍出现报错,大概率是当前会话中之前已经创建过#TT临时表。
解决方案
根据你的需求选择以下两种写法:
需求1:将每次循环的结果追加到临时表
先提前创建临时表结构,再用INSERT INTO向表中追加数据:
DECLARE @V_START INT = 1; -- 预定义临时表结构(需与Table表的列完全匹配) CREATE TABLE #TT ( Column INT, -- 补充Table表的其他列... ); WHILE(@V_START < 4) BEGIN INSERT INTO #TT SELECT * FROM Table WHERE Column = @V_START; SET @V_START = @V_START + 10; END SELECT * FROM #TT; DROP TABLE #TT;
如果不想手动定义列,可以先执行一次查询创建表,后续循环用INSERT INTO追加:
DECLARE @V_START INT = 1; -- 第一次查询创建临时表 SELECT * INTO #TT FROM Table WHERE Column = @V_START; SET @V_START = @V_START + 10; -- 后续循环追加数据 WHILE(@V_START < 4) BEGIN INSERT INTO #TT SELECT * FROM Table WHERE Column = @V_START; SET @V_START = @V_START + 10; END SELECT * FROM #TT; DROP TABLE #TT;
需求2:每次循环覆盖临时表数据(仅保留最后一次结果)
每次循环前先检查并删除已存在的临时表,再重新创建:
DECLARE @V_START INT = 1; WHILE(@V_START < 4) BEGIN -- 检查临时表是否存在,存在则删除 IF OBJECT_ID('tempdb..#TT') IS NOT NULL DROP TABLE #TT; SELECT * INTO #TT FROM Table WHERE Column = @V_START; SET @V_START = @V_START + 10; END SELECT * FROM #TT; DROP TABLE #TT;
补充说明
- 会话级临时表
#TT会在会话结束后自动删除,但显式执行DROP TABLE是更规范的做法。 SELECT INTO仅适用于创建新表,若要向已存在的表插入数据,必须使用INSERT INTO ... SELECT语法。
内容的提问来源于stack exchange,提问作者Lim
相关产品推荐
相关产品推荐

