【问题标题】:trigger and transactions on temporary tables临时表上的触发器和事务
【发布时间】:2011-07-14 19:45:23
【问题描述】:

我们可以在临时表上创建触发器和事务吗?

当用户插入数据时,如果它被提交,那么触发器将被触发,并且该数据将从临时表进入实际表。

当 SQL 服务停止或服务器关闭时,临时表将被自动删除。

或者我应该使用另一个实际表,首先将插入数据,然后如果提交,则触发触发器并将数据发送到主表,然后我将执行截断查询从接口表中删除数据,从而删除重复数据。

【问题讨论】:

    标签: sql sql-server sql-server-2005 triggers temp-tables


    【解决方案1】:

    我认为您不了解触发器 - 触发器触发与它们相关的语句相关联,而不是事务提交时。两个脚本:

    脚本 1:

    create table T1 (
        ID int not null,
        Val1 varchar(10) not null
    )
    go
    create table T2 (
        ID int not null,
        Val2 varchar(10) not null
    )
    go
    create trigger T_T1_I
    on T1
    after insert
    as
        insert into T2 (ID,Val2) select ID,Val1 from inserted
    go
    begin transaction
    insert into T1 (ID,Val1)
    select 10,'abc'
    go
    RAISERROR('Run script 2 now',10,1) WITH NOWAIT
    WAITFOR DELAY '00:01:00'
    go
    commit
    

    脚本 2:

    select * from T2 with (nolock)
    

    打开两个到同一个数据库的连接,在每个连接中放置一个脚本。运行脚本 1。当它显示消息“立即运行脚本 2”时,切换到另一个连接。您将看到您能够从 T2 中选择未提交的数据,即使该数据是由触发器插入的。 (这也意味着脚本 1 在 T2 上持有适当的锁,直到触发器提交为止)。


    由于这意味着您要求的等价物是插入基表并保持您的事务处于打开状态,因此您可以这样做。

    如果您想对用户隐藏表格的实际形状,请创建一个 视图 并在其上编写触发器以更新基表。如上所述,一旦您对视图执行了 DML 操作,触发器就会被触发,并且您将持有对基表的锁。根据其他连接的事务隔离级别,它们可能会看到您的更改,或者在事务提交之前被阻止。

    【讨论】:

      【解决方案2】:

      无法在临时表上创建触发器。但这样做是不寻常的要求。

      临时表可以是事务的一部分,但表变量不能。

      正如@Damien 指出的那样,触发器不会在提交事务时触发,而是在具有相应触发器的表上的操作(INSERT、UPDATE、DELETE)发生时触发。

      【讨论】:

      • 实际上正在使用临时表,因为我想从最终用户那里抽象出我的实际表
      • 我希望首先将数据插入到某个中介中,然后再进入实际的表中。然后中介会被清空
      【解决方案3】:

      或者创建一个可以插入数据的视图。它将写回表,然后触发器将触发。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-11
        • 1970-01-01
        • 1970-01-01
        • 2013-11-19
        • 2014-04-01
        • 1970-01-01
        相关资源
        最近更新 更多