sql - 修改现有触发器的程序

标签 sql sql-server database

我想创建修改现有触发器的过程。触发器负责阻止使用特定 ID 更新的行。我试过类似的东西:

CREATE PROCEDURE Change_trigger
    @List_of_ids varchar(8000)
AS 
ALTER TRIGGER blocks
ON ttt
INSTEAD OF update 
AS
BEGIN
    If (SELECT Id_ttt FROM inserted) IN (@List_of_ids)
      BEGIN
          raiserror('You cannot modify this record.', 12, 1)
          RETURN
      END

    UPDATE ttt
    SET
    field1 = INSERTED.field1
    FROM INSERTED
    WHERE INSERTED.Id_ttt = ttt.Id_ttt
END

参数 @List_of_ids 将是这样的:2,3,4,5,9,52。但是,当我尝试创建此过程时出现错误:

Msg 156, Level 15, State 1, Procedure Change_trigger, Line 4
Incorrect syntax near the keyword 'TRIGGER'.

触发器已创建。

最佳答案

这是我写过的触发器。

ALTER TRIGGER blocks
ON ttt
INSTEAD OF update 
AS
BEGIN
    SET NOCOUNT ON

    UPDATE t
    SET
    field1 = i.field1
    FROM INSERTED i
            inner join
         ttt t
            on i.Id_ttt = t.Id_ttt
            left join
         ttt_blocked on tb
            on
               i.Id_ttt = tb.Id_ttt
    WHERE
        tb.Id_ttt is null
END

请注意,此触发器不再为被阻止的更新抛出错误,但它确实允许发生混合更新(一些行被阻止,一些行没有)。没有一种干净的方法可以在仍然部分应用触发器中的更新的同时引发错误。

然后我会有一个表(上面引用):

CREATE TABLE ttt_blocked (
   Id_ttt int not null,
   constraint PK_ttt_blocked PRIMARY KEY (Id_ttt)
)

然后,如有必要,我将创建一个过程来维护此,而不是不断更改数据库架构:

CREATE PROCEDURE Change_blocking
  @BlockedIDs xml
AS
    --Better option would be table-valued parameters
    --but I've chosen to do XML today

    --We expect the XML to be of the form
    --<blocks>
    --  <id>10</id>
    --  <id>15</id>
    --</blocks>

    MERGE INTO ttt_blocked t
    USING (select x.id.value('text()[1]','int')
           from @BlockedIDs.nodes('/blocks/id') x(id)) s(Id_ttt)
    ON
      t.Id_ttt = s.Id_ttt
    WHEN NOT MATCHED THEN INSERT (Id_ttt) VALUES (s.Id_ttt)
    WHEN NOT MATCHED BY SOURCE THEN DELETE;

正如我在上面提到的,我通常会推荐 Table-Valued Parameters而不是 XML(它们中的任何一个都在 varchar 之前,因为它们被设计以保存多个值)但它会为此答案添加更多代码。

关于sql - 修改现有触发器的程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35147997/

相关文章:

sql - UPDATE = DELETE(标记为) + INSERT吗?

sql-server - 在 sql 函数中使用设置语言

sql-server - ssis 中的意外终止错误

mysql - 构建一个 SQL 来计算与父项相关的行数

c# - SqlCommand 还是 SqlDataAdapter?

sql - 选择具有不同值的行的百分比

ruby-on-rails - 运行 rake db :seed multiple times without creating duplicate records?

mysql - 如果另一个子查询中不存在表别名,那么创建它们有什么意义呢?

mysql - EXISTS 和 JOIN 检查记录是否存在的区别

sql - Jetbrains Datagrip 2017.1.3,将数据转储到 sql 插入文件时强制导出列