在一个事务中运行SQL对于单独运行具有不同的结果

时间:2017-02-02 11:52:44

标签: sql-server sql-server-2014

我无法弄清楚为什么会这样,但如果我跑:

BEGIN TRANSACTION
    ALTER TABLE [TABLE NAME] DISABLE TRIGGER [TRIGGER NAME];

    -- Some query

    ALTER TABLE [TABLE NAME] ENABLE TRIGGER [TRIGGER NAME];
COMMIT TRANSACTION

哪些'某些查询'取决于被禁用的触发器,我收到错误(因为触发器未成功禁用)。

但是,如果我单独运行alter语句,那很好。

我已尝试使用DISABLE TRIGGER语法,并且我已尝试BEGINEND而不是BEGIN TRANSACTION等。

我在这里误解了什么?为什么这些改变陈述似乎没有及时改变?

修改

我想重新解释这个问题,以支持清晰度来陪伴赏金:

为什么我们必须分批DDL和DML批次?

2 个答案:

答案 0 :(得分:2)

由于您在同一个批处理/语句中执行它们,因此您在更改表后,SQL Server已编译您的sql语句。

  1. SQL Server编译您的语句(包括所有单独的DDL) 和批处理中的DML命令)
  2. SQL Server更改您的TABLE以禁用触发器
  3. SQL Server运行您的“查询”,但它被编译为假设存在 触发器在那里运行。
  4. SQL Server改变您的TABLE以启用触发器
  5. 要解决此问题,您仍然可以在事务中执行此操作,但您需要将其分成批处理。如果从SSMS或类似工具运行,则在每个语句之间插入“GO”,或者如果从代码调用则调用单独的SQL语句。

答案 1 :(得分:-1)

不建议在事务中混合使用DDL和DML,因为它会产生不希望的结果:

#child1{
    width:100%;
}