我正在创建一个处理临时表(#attributeType)的触发器。由于触发器可以多次调用,我想确定并检查临时表#attributeType是否仍在那里。
这是我在触发器体中检查临时表的代码:
IF OBJECT_ID('tempdb..#attributeType') IS NOT NULL
BEGIN
DROP TABLE #attributeType
SELECT * INTO #attributeType
FROM attributeType
PRINT 'IN IF'+ CAST(OBJECT_ID('tempdb..#attributeType') AS NVARCHAR(80))
END
ELSE
BEGIN
SELECT * INTO #attributeType
FROM attributeType
PRINT 'IN ELSE'+ CAST(OBJECT_ID('tempdb..#attributeType') AS NVARCHAR(80))
END
当我通过F5选择代码来测试代码时,我收到此错误消息,指出#attributeType临时表存在:
Msg 2714, Level 16, State 1, Line 11
There is already an object named '#attributeType' in the database.
我知道在存储过程中,一旦sp结束就会删除#tempTables,但我仍然无法理解为什么我的代码错了?
N.B。 当我注释掉ELSE块时代码可以工作。
答案 0 :(得分:10)
您对OBJECT_ID('tempdb..#attributeType')
的测试运行正常。您可以单独运行它,而不是同一批中的drop
和create
来测试它。
问题是SQL Server在运行它之前解析整个批处理。如果它知道#attributeType
存在,则会给出错误:
SELECT * INTO #attributeType
即使您将表格放在上一行中。
一种解决方案是将表放在另一批中:
IF OBJECT_ID('tempdb..#attributeType') IS NOT NULL
DROP TABLE #attributeType
GO -- new batch
SELECT * INTO #attributeType ...
另一种解决方案是在不同的范围内创建表:
IF OBJECT_ID('tempdb..#attributeType') IS NOT NULL
DROP TABLE #attributeType
exec ('SELECT * INTO #attributeType ...')
答案 1 :(得分:0)
如果您不需要在IF..ELSE语句中执行任何其他操作,您的代码可以简化为以下内容:
IF OBJECT_ID('tempdb..#attributeType') IS NOT NULL
BEGIN
DROP TABLE #attributeType
END
SELECT *
INTO #attributeType
FROM attributeType
在这种情况下,您可以避免There is already an object named...
错误,但仍然有临时表。