SQL Server触发器允许访问two special tables。 INSERTED
-
带有“after”值,DELETED
带有“before”值。
这些存放在哪里?它们是否出现在tempdb
或与正在采取行动的表格相同的数据库中?
答案 0 :(得分:4)
在SQL Server 2005之前的版本中,这些表were read from the transaction log when needed。
自SQL Server 2005起,构成after触发器的插入和删除伪表的行都存储在the version store中(总是在tempdb
的页面中 - 这些页面可能或者可能不存在于记忆中。)
您可以从下面清楚地看到这一点(在快照隔离和RCSI关闭的数据库中运行)
CREATE TABLE T1 (X BINARY(10));
GO
--B = Before
INSERT INTO T1
VALUES (0xBBBBBBBBBBBBBBBBBBBB);
GO
CREATE TRIGGER TR ON T1 AFTER UPDATE
AS
PRINT 'Trigger called'
GO
DECLARE @mtsn INT = ISNULL(MAX(transaction_sequence_num), 0)
FROM sys.dm_tran_version_store
WHERE database_id = DB_ID();
UPDATE T1
SET X = 0xAAAAAAAAAAAAAAAAAAAA; --A = After
SELECT transaction_sequence_num,
version_sequence_num,
record_image_first_part,
CASE
WHEN CHARINDEX(0xBBBBBBBBBBBBBBBBBBBB, record_image_first_part) > 0
THEN 'Before'
WHEN CHARINDEX(0xAAAAAAAAAAAAAAAAAAAA, record_image_first_part) > 0
THEN 'After'
END
FROM sys.dm_tran_version_store
WHERE database_id = DB_ID()
AND transaction_sequence_num > @mtsn;
DROP TABLE T1
返回类似
的内容答案 1 :(得分:0)
这是疯狂的谈话。对于交易范围,这些表存在 in memory * 。
使用触发器非常糟糕,不要试图搞乱INSERTED和DELETED表。如果你想要它很糟糕,你可以在触发器内用它的数据填充另一个(临时?)表。
触发器几乎在任何情况下都被认为是反模式,它不是普通的日志。通常,您可以首先使用触发触发器的数据,并保持简洁且易于维护的业务逻辑。
内存中的* :大多数时候SQL引擎会尝试让RAM内存中的所有内容,如果由于任何原因它需要更多内存,那么可用页面就会开始使用磁盘的平均值tempBD但它完全透明且无法控制。
修改强>
马丁史密斯的答案是一个很好的答案。我知道可以为临时表做类似的事情,但从未尝试过触发器表。我只是想指出实现任何需要直接操纵对象的东西,这可能会引起对错误方向的实施的怀疑。这里有一些我的“咆哮”来源(使用不当)触发