我在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
表。
在触发器中使用临时表有什么问题吗?
答案 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来创建和填充临时表。在触发器中使用临时表时存在一些限制。