【发布时间】:2011-02-08 04:26:14
【问题描述】:
我有一个客户端应用程序,它创建一个临时表,对临时表执行批量插入,然后在删除之前使用该表执行一些 SQL。
伪代码:
open connection
begin transaction
CREATE TABLE #Temp ([Id] int NOT NULL)
bulk insert 500 rows into #Temp
UPDATE [OtherTable] SET [Status]=0 WHERE [Id] IN (SELECT [Id] FROM #Temp) AND [Group]=1
DELETE FROM #Temp WHERE [Id] IN (SELECT [Id] FROM [OtherTable] WHERE [Group]=1)
INSERT INTO [OtherTable] ([Group], [Id]) SELECT 1 as [Group], [DocIden] FROM #Temp
DROP TABLE #Temp
COMMIT TRANSACTION
CLOSE CONNECTION
这会失败并在 DROP 语句中出现错误:
无法删除表“#Temp”,因为它不存在或您没有权限。
如果不先发生其他事情,我无法想象这种故障是如何发生的,但我没有看到在此之前发生任何其他故障。
有什么我遗漏的东西可能导致这种情况发生吗?
【问题讨论】:
-
一个建议,将创建、批量插入和删除语句移到事务块之外。没有理由也不需要锁定它,因为没有其他连接可以访问它。
-
@Philip Kelley:这不是一个坏主意,我会看看我是否可以这样做来限制交易的长度,但我看不出这将如何导致这个问题
-
该错误似乎出现在空白处。 ;) 一个完整的复制脚本会更清楚地说明这一点。
-
是的,它会使交易更短/更紧,是的,这对您的问题没有影响。我会支持 Andomar:为什么要尝试删除临时表,因为它会在事务关闭时被删除?实际使用该表的查询都没有失败,是吗? (是的,很高兴知道发生了什么,但正如所展示的那样,它最终与您的流程无关。)
-
真的有人找出错误发生的原因吗?我收到与具有系统管理员的登录相关的相同错误。所有那些说你不需要放弃桌子的人都是完全没有帮助的。事实是该命令是有效的 SQL,并且给定了一个有效的创建表 #Whatever (...),无论您在技术上是否需要将其放入,它都应该工作。如果问题是“我的内部连接给出了一个语法错误”,那么响应是否会是“你不必说'内部'你可以说'加入'”?正确但无关紧要,因为它应该再次工作,因此不会解决 OPs 问题。
标签: sql-server temp-tables sql-drop