事务中#temp表DROP命令是否需提交生效?重复用临时表报错咨询
你的问题根源不是事务提交,是SQL的编译机制!
先给你吃个定心丸:事务中的DROP TABLE #Temp命令是立即生效的,完全不需要等到事务提交。你碰到的“对象已存在”错误,和事务提交一点关系都没有,问题出在SQL Server对整个批处理的编译逻辑上。
为啥会报错?
SQL Server在编译整个包含事务的脚本批处理时,会提前做对象存在性校验:
- 它看到第一个
SELECT ... INTO #Temp,会判定这个操作会创建#Temp临时表; - 接着看到后面又出现
SELECT ... INTO #Temp,哪怕中间有DROP TABLE #Temp,编译阶段根本不会考虑代码的运行顺序,直接认定#Temp已经存在,于是抛出那个讨厌的错误。
给你几个可行的解决方案
方案1:用动态SQL绕开编译检查
把后面的SELECT ... INTO和DROP包在EXEC里,这部分代码会在运行时动态编译,此时前面的DROP已经实实在在把临时表删掉了,自然不会触发编译时的冲突:
BEGIN TRY BEGIN TRANSACTION SELECT myfield1, myfield2 INTO #Temp FROM MyTable -- 这里写你对#Temp的操作逻辑 DROP TABLE #Temp -- 用EXEC执行第二部分逻辑 EXEC(' SELECT myfield3, myfield4 INTO #Temp FROM MyTable2 -- 这里写你对#Temp的操作逻辑 DROP TABLE #Temp ') COMMIT TRANSACTION END TRY BEGIN CATCH ROLLBACK TRANSACTION -- 这里加你的错误处理代码 END CATCH
方案2:预先建表,用INSERT INTO替代SELECT INTO
先手动创建临时表的结构,之后每次用TRUNCATE TABLE清空数据再插入,避免反复创建删除临时表:
BEGIN TRY BEGIN TRANSACTION -- 先创建临时表,字段类型要和后续查询匹配 CREATE TABLE #Temp ( myfield1 INT, -- 替换成你实际的字段类型 myfield2 VARCHAR(100) ) -- 第一组数据插入 INSERT INTO #Temp (myfield1, myfield2) SELECT myfield1, myfield2 FROM MyTable -- 对#Temp执行操作 TRUNCATE TABLE #Temp -- 清空数据,保留表结构 -- 第二组数据插入(注意字段要对应上) INSERT INTO #Temp (myfield1, myfield2) SELECT myfield3, myfield4 FROM MyTable2 -- 对#Temp执行操作 DROP TABLE #Temp COMMIT TRANSACTION END TRY BEGIN CATCH ROLLBACK TRANSACTION -- 错误处理逻辑 END CATCH
方案3:用不同命名的临时表(备选)
如果上面两个方案都不适合你的场景,再考虑用#Temp1、#Temp2这类不同的表名——这是最直接但有点繁琐的办法,尽量优先用前两个方案。
内容的提问来源于stack exchange,提问作者Legion
相关产品推荐
相关产品推荐

