首页 文章

SQL Server在循环内部或外部禁用触发器?

提问于
浏览
0

我应该禁用然后在循环中启用触发器,以便它为每个项禁用它们,然后更新,然后重新启用,或者我应该在脚本开始时禁用它们一次并在结束时重新启用它们一次脚本?

对于一个基本的例子,让我们说为了参数我有两个表:

table_A有字段 firstnamesurnameid

table_B有字段 firstnamesurname

对于本练习, table_Aid 字段是从1开始的顺序整数,没有跳过的数字 .

以下SQL将遍历 table_A 中的每条记录,并将 firstnamesurname 插入 table_B

DECLARE   @Counter INT, 
      @RowCount INT

SET @Counter = 1
SET @RowCount = (SELECT COUNT(*) FROM table_A)

WHILE @Counter <= @RowCount BEGIN   

    INSERT INTO table_B (firstname,surname)
    SELECT firstname,surname
    FROM table_A
    WHERE id = @Counter

    SET @Counter = @Counter + 1

END

如果 table_B 上定义了触发器并且我想禁用那些触发器,我看到它有两个选项:我可以在脚本开始时禁用一次触发器,在结束时或在 insert 之前和之后立即禁用触发器 . 是否有最好的做法,我认为我应该通过在 while ... end 循环中禁用它们来最小化它们被禁用的总时间,因为许多其他人和客户可能是同时使用数据库?

1 回答

  • 1

    除非您有充分的理由使用循环进行更新,否则我会在脚本开头禁用触发器,将插入/更新作为基于单个集的查询进行处理,然后再次启用触发器 .

    对于你的 INSERT 陈述,你可以做到

    INSERT INTO table_B (id, firstname, surname)
    SELECT id, firstname, surname FROM table_A
    

    但是从您的评论中,您不仅要将行从一个表复制到另一个表,还需要更新存在的行并插入不存在的行 . 为此,您可以使用MERGEinsert, update or delete data .

    [Merge]根据与源表的连接结果对目标表执行插入,更新或删除操作 . 例如,您可以根据在另一个表中找到的差异,通过在一个表中插入,更新或删除行来同步两个表 .

    对于您可以使用的示例语句

    MERGE table_B 
    USING (SELECT firstname, surname FROM table_A)
      ON table_B.id = table_A.id
    WHEN MATCHED THEN UPDATE
      SET table_B.firstname = table_A.firstname,
          table_B.surname = table_A.surname
    WHEN NOT MATCHED THEN
      INSERT(id, firstname, surname)
      VALUES(table_A.id, table_A.forename, table_A.surname);
    

相关问题