T-SQL和事务流-从第一个到最后一个

T-SQL和事务流-从第一个到最后一个,sql,sql-server,tsql,transactions,Sql,Sql Server,Tsql,Transactions,假设我有一个带有列的tableTabA: col1-主键(但不是标识) col2-外键 col3-具有唯一约束 col4-带检查约束 col5-具有非空约束 另外,TabA有两个触发器: 而不是INSERT-这一个取消了插入到TabA(当然),但是在它自己的代码中,将新行插入到TabA。保证新行中所有列的值都正确 插入后-这一个只是打印字符串 现在,我已经准备好将新行插入TabA(插入TabA值(…)。显然,我们必须预料到一些事件: 必须检查col1的值的唯一性且不为NULL(主键) 必

假设我有一个带有列的tableTabA

  • col1-主键(但不是标识)

  • col2-外键

  • col3-具有唯一约束

  • col4-带检查约束

  • col5-具有非空约束

另外,TabA有两个触发器:

  • 而不是INSERT-这一个取消了插入到TabA(当然),但是在它自己的代码中,将新行插入到TabA。保证新行中所有列的值都正确

  • 插入后-这一个只是打印字符串

现在,我已经准备好将新行插入TabA(插入TabA值(…)。显然,我们必须预料到一些事件:

  • 必须检查col1的值的唯一性且不为NULL(主键)

  • 必须检查col2的值是否符合父表(外键)

  • 必须检查col3的值的唯一性

  • 必须根据检查约束检查col4的值

  • 必须检查col5的值是否为NOTNULL

  • 而不是必须执行触发器

  • 之后必须执行触发器

  • 我想要的是重新排列这个列表(1-7),使数字1出现在第一个发生的事件上,2=第二个发生的事件,…,7出现在最后一个事件上

    另外,如果事件X产生错误(例如,col5=NULL),这是否意味着事件X+1、X+2。。不会发生吗


    谢谢你的帮助

    插入、更新、删除语句的一般执行顺序:

    • 强制执行所有表级和行级约束。请注意,您对检查这些约束的顺序没有控制权
    • 如果正在执行的语句存在INSTEAD OF触发器,请执行它
    • 以未定义的顺序执行所有适当的AFTER触发器,但以下情况除外:
      • 如果after触发器被指定为通过
        sp_settriggerorder
        执行的第一个或最后一个触发器,则在适当的点执行这些触发器,剩余的触发器按未定义的顺序执行
    您可能只有1个而不是触发器(每个操作:插入、更新或删除)。该触发器总是在任何AFTER触发器之前执行,因为它在相应的INSERT、UPDATE或DELETE语句中执行

    奇怪的是,AFTER触发器总是在数据修改语句执行之后执行


    注意:如果您有一个INSTEAD OF触发器,我就不清楚了,因为我没有花太多时间在INSTEAD OF触发器上,也不清楚在执行INSTEAD OF触发器之前是否执行了表/行约束。这是您可能想要尝试的东西。

    通过设置测试表(如触发器中的print语句所述)并简单地尝试插入无效值,可以很容易地进行测试。这样做给了我很大的帮助

  • 代替触发器
  • 检查PK的空值
  • 检查第5列的NULL
  • 检查PK约束的唯一性
  • 检查唯一约束的唯一性
  • 检查第4列的检查约束
  • 检查FK约束
  • 触发后开火
  • 据我所知,1、7和8的顺序是有保证的。其余的都是武断的。任何错误都将停止后续步骤


    这很容易通过设置测试表进行测试,如print所述 语句,并尝试插入无效值

    当然,我做到了!并且同意你的观点-从1到8得到相同的结果。而令我尴尬的是引用了《微软SQL Server 2008圣经》(Paul Nielsen著)一书中的话。即(第637页):

    每一笔交易都会通过 顺序如下:

  • 身份插入检查
  • 零性约束
  • 数据类型检查
  • 而不是触发执行。如果存在INSTEAD OF触发器,则 DML的执行在此停止。而不是触发器 递归的。因此,如果插入触发器执行另一个DML 命令,则第二次将忽略替代触发器 大约(本章后面将介绍递归触发器)
  • 主键约束
  • 检查约束
  • 外键约束
  • DML执行和事务日志更新
  • 触发执行后
  • 提交事务

  • 所以,正如你所看到的,这个IT专业人士不同意你和我。例如,他给出的触发器编号为4,而我们给出的触发器编号为1。这句话让我很困惑

    这与我在实验中发现的顺序不同。
    代替触发器
    消息即使违反了约束也会被打印出来,并出现在任何约束错误消息之前。正如我所说:没有对代替触发器进行过太多的研究,它们如何与表/行级约束交互对我来说是个谜。听起来您的INSTEAD OF触发器实际上是对表进行插入的,这会导致触发表/行级别的约束,因此表/行级别的约束与表上的物理插入/更新/删除操作相关联。是。但你刚才让我检查了一些东西。使用代码<代码>打印“而不是触发器”;插入到选项卡中,从插入中选择*;打印“而不是触发器2”第二条消息出现在
    after Trigger
    消息的末尾,因此基本上,整个事件好像在
    的子范围内运行,而不是在
    Trigger中运行。