SQL在触发器中使用临时表

时间:2012-11-13 07:54:46

标签: sql sql-server triggers sql-server-2008-r2 hashtable

我在MSSQL Server 2008R2中有一个触发器:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[trg_HosFile_Delete] 
    ON [dbo].[hosfile] FOR DELETE 
AS 
    insert into #pys(pyGuid)
    SELECT EntryGuid AS pyGuid FROM er000 AS er

    insert into t2(C1) select pyGuid from #pys

触发器执行后,t2表为空。它为什么空?

如果我在没有触发器的情况下执行上述查询,则会填充t2表。

在触发器中使用临时表有什么问题吗?

4 个答案:

答案 0 :(得分:4)

Damien的答案是正确的:你可以在触发器中使用临时表,但强烈建议在那里定义它们,因为触发器可以在各种上下文中触发。

如果在触发器中使用临时表,请检查临时表的存在,因为您不控制上下文并且它可能已存在:

IF OBJECT_ID('tempdb..#pys') IS NOT NULL
    DROP TABLE #pys

此外,可以动态创建临时表:

SELECT * INTO #tmp
FROM inserted

当触发器包含需要访问在动态SQL范围中不可见的插入或删除的特殊表的动态SQL时,这尤其有用。

避免使用## tmp(全局临时变量),因为它们是全局可见的,并且当多个SPID触发时会导致问题。

答案 1 :(得分:3)

使用临时表没有问题,只要它们在触发器触发时就在范围内。

鉴于触发器可以随时触发,在任何连接上,唯一有意义的范围是在触发器的主体内:

ALTER TRIGGER [dbo].[trg_HosFile_Delete] 
    ON [dbo].[hosfile] FOR DELETE 
AS 
    CREATE TABLE #pys (pyGuid uniqueidentifier not null/*I'm guessing*/)

    insert into #pys(pyGuid)
    SELECT EntryGuid AS pyGuid FROM er000 AS er

    insert into t2(C1) select pyGuid from #pys

(说实话,我不确定你是否可以从外部范围访问一个临时表,并且没有一个实例可以方便地进行测试。但是,即使你可以,它也会很有用。脆弱的触发器)

答案 2 :(得分:0)

如果您使用## pys(注意双#符号),它将在创建后全局可用。这可能对你的情况有所帮助。

答案 3 :(得分:0)

尝试使用SELECT INTO来创建和填充临时表。在触发器中使用临时表时存在一些限制。