简体   繁体   English

T-SQL和事务流-从头到尾

[英]T-SQL and transaction flow - from first to last

Let's say I have table TabA with columns: 假设我有带有列的表TabA

  • col1 - primary key (but not identity) col1-主键(但不包括身份)

  • col2 - foreign key col2-外键

  • col3 - with unique constraint col3-具有唯一约束

  • col4 - with check constraint col4-具有检查约束

  • col5 - with NOT NULL constraint col5-具有非空约束

Also, TabA has 2 triggers: 此外, TabA具有2个触发器:

  • INSTEAD OF INSERT - this one cancel insert into TabA (of course), but in it's own code insert new row into TabA . INSTEAD OF INSERT-这个取消插入到TabA中 (当然),但是在它自己的代码中,将新行插入TabA中 The values for all column in this new row are guaranteed correct 保证此新行中所有列的值正确

  • AFTER INSERT - this one just print string 插入后-此仅打印字符串

Now, I am ready insert new row into TabA (INSERT INTO TabA VALUES(...)). 现在,我准备将新行插入TabA (INSERT INTO TabA VALUES(...))。 Obviously, we have to expect some events: 显然,我们必须期待一些事件:

  1. value for col1 must be checked for uniqueness and NOT NULL(primary key) 必须检查col1的值是否唯一,并且NOT NULL(主键)

  2. value for col2 must be checked for conformity to the parental table(foreign key) 必须检查col2的值是否与父母表格(外键)相符

  3. value for col3 must be checked for uniqueness 必须检查col3的值是否唯一

  4. value for col4 must be checked against check constraint 必须对照检查约束检查col4的值

  5. value for col5 must be checked for NOT NULL 必须为col5的值检查NOT NULL

  6. INSTEAD OF trigger must be executed 必须执行INSTEAD OF触发器

  7. AFTER trigger must be executed 必须执行AFTER触发器

What I want is reorder this list(1-7) so that number 1 be on event that will happen first, 2=event that will happen second, ..., and 7 for the last event. 我想要的是重新排序此列表(1-7),以使数字1出现在首先发生的事件上,2 =发生在第二发生的事件上,...,以及发生在最后一个事件上的7。

Also, if event X produce error (col5=NULL, for example) - does this mean that events X+1,X+2.. will NOT happen? 另外,如果事件X产生错误(例如,col5 = NULL)-这是否意味着事件X + 1,X + 2 .. 不会发生?

Thanks for you help! 感谢您的帮助!

General order of execution for INSERT, UPDATE, DELETE statements: INSERT,UPDATE,DELETE语句的一般执行顺序:

  • Enforce all table- and row-level constraints. 强制执行所有表级和行级约束。 Note that you have zero control over the order in which these constraints are checked. 请注意,您对检查这些约束的顺序具有零控制权。
  • If an INSTEAD OF trigger exists for the statement being executed, execute it. 如果要执行的语句存在INSTEAD OF触发器,请执行它。
  • Execute all apropriate AFTER triggers, in undefined order, with the following exceptions: 以未定义的顺序执行所有适当的AFTER触发器,但以下情况除外:
    • IF an after trigger has been specified as the first or last to be executed via sp_settriggerorder , execute those at the appropriate point, with any remaining triggers executed in undefined order. 如果已通过sp_settriggerorder将after触发器指定为要执行的第一个或最后一个sp_settriggerorder ,则在适当的位置执行这些触发器,其余所有触发器sp_settriggerorder未定义的顺序执行。

You may have only 1 INSTEAD OF trigger (per action: INSERT, UPDATE or DELETE). 您可能只有1个INSTEAD OF触发器(每个操作:INSERT,UPDATE或DELETE)。 That trigger will always get executed before any AFTER triggers, since it executes in lieue of the corresponding INSERT, UPDATE or DELETE statement. 该触发器将始终在任何AFTER触发器之前执行,因为它在相应的INSERT,UPDATE或DELETE语句中执行。

AFTER triggers are always executed, oddly enough, AFTER the data modification statement executes. 总是在数据修改语句执行之后执行AFTER触发器,这很奇怪。

NOTE: If you have an INSTEAD OF trigger, it is unclear to me, not having spent any real amount of time fussing with INSTEAD OF triggers, whether or not table/row constraints are enforced prior to execution of the INSTEAD OF trigger. 注意:如果您有一个INSTEAD OF触发器,则对我来说还不是很清楚,是否没有花费任何真正的时间对INSTEAD OF触发器进行大惊小怪,无论在执行INSTEAD OF触发器之前是否强制执行表/行约束。 That's something you might want to experiment with. 您可能想尝试一下。

This is easy to test by setting up test tables as described with print statements in the triggers and simply trying to insert invalid values. 通过按照触发器中的print语句设置测试表并简单地尝试插入无效值,可以很容易地进行测试。 Doing so gave for me 这样做给了我

  1. Instead Of Trigger 代替触发
  2. Checks NULL of PK 检查PK的NULL
  3. Checks NULL of column 5 检查第5列的NULL
  4. Checks uniqueness of PK constraint 检查PK约束的唯一性
  5. Checks uniqueness of unique constraint 检查唯一约束的唯一性
  6. Checks check constraint of column 4 检查第4列的检查约束
  7. Checks FK constraint 检查FK约束
  8. Fires After Trigger 触发后触发

As far as I know the order of 1,7, and 8 are guaranteed. 据我所知,保证1,7和8的顺序。 The rest are arbitrary. 其余都是任意的。 Any error will stop succeeding steps. 任何错误将停止后续步骤。

This is easy to test by setting up test tables as described with print statements in the triggers and simply trying to insert invalid values. 通过按照触发器中的print语句设置测试表并简单地尝试插入无效值,可以很容易地进行测试。

Of course, I did it! 当然,我做到了! And agree with you - get the same result from 1 to 8. And what is embarrass for me is the quote from "Microsoft SQL Server 2008 Bible" book (by Paul Nielsen). 并同意您的要求-从1到8得到相同的结果。令我感到尴尬的是“ Microsoft SQL Server 2008圣经”一书(保罗·尼尔森撰写)的引文。 That is (on page 637): 即是(第637页):

Every transaction moves through the various checks and code in the following order: 每笔交易按以下顺序进行各种检查和编码:

  1. IDENTITY INSERT check 身份插入检查
  2. Nullability constraint 可空性约束
  3. Data-type check 数据类型检查
  4. INSTEAD OF trigger execution. 代替执行触发器。 If an INSTEAD OF trigger exists, then execution of the DML stops here. 如果存在INSTEAD OF触发器,则DML的执行在此处停止。 INSTEAD OF triggers are not recursive. INSTEAD OF触发器不是递归的。 Therefore, if the INSERT trigger executes another DML command, then the INSTEAD OF trigger will be ignored the second time around (recursive triggers are covered later in this chapter). 因此,如果INSERT触发器执行另一个DML命令,则第二次将忽略INSTEAD OF触发器(本章后面将介绍递归触发器)。
  5. Primary-key constraint 主键约束
  6. Check constraints 检查约束
  7. Foreign-key constraint 外键约束
  8. DML execution and update to the transaction log DML执行并更新到事务日志
  9. AFTER trigger execution 触发执行后
  10. Commit transaction 提交交易

So, as you see, this IT-Pro disagree with you and me. 因此,正如您所看到的,此IT-Pro与您和我不同意。 He, for example, give INSTEAD OF trigger number 4 whereas we give to it number 1. This quote just baffle me! 例如,他给INSTEAD OF触发器编号4,而我们给它编号1。这句话让我感到困惑!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM