插入和删除的伪表存储在哪里?

时间:2017-12-05 17:55:53

标签: sql sql-server

SQL Server触发器允许访问two special tablesINSERTED -  带有“after”值,DELETED带有“before”值。

这些存放在哪里?它们是否出现在tempdb或与正在采取行动的表格相同的数据库中?

2 个答案:

答案 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 

返回类似

的内容

enter image description here

答案 1 :(得分:0)

这是疯狂的谈话。对于交易范围,这些表存在 in memory *

使用触发器非常糟糕,不要试图搞乱INSERTED和DELETED表。如果你想要它很糟糕,你可以在触发器内用它的数据填充另一个(临时?)表。

触发器几乎在任何情况下都被认为是反模式,它不是普通的日志。通常,您可以首先使用触发触发器的数据,并保持简洁且易于维护的业务逻辑。

内存中的

* :大多数时候SQL引擎会尝试让RAM内存中的所有内容,如果由于任何原因它需要更多内存,那么可用页面就会开始使用磁盘的平均值tempBD但它完全透明且无法控制。

修改

马丁史密斯的答案是一个很好的答案。我知道可以为临时表做类似的事情,但从未尝试过触发器表。我只是想指出实现任何需要直接操纵对象的东西,这可能会引起对错误方向的实施的怀疑。

这里有一些我的“咆哮”来源(使用不当)触发

Are database triggers evil?

When are database triggers bad?