3

我在 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

4 回答 4

7

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

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

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

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

SELECT * INTO #tmp
FROM inserted

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

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

于 2015-12-09T17:37:19.957 回答
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

(老实说,我不确定您是否可以从外部范围访问临时表,并且没有方便的实例来测试它。但是,即使可以,它也会导致非常脆弱的触发器)

于 2012-11-14T15:47:40.260 回答
0

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

于 2013-05-22T16:05:36.877 回答
0

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

于 2014-12-15T12:37:08.413 回答