【问题标题】:Using Instead-Of SQL triggers to insert or update a view使用 SQL 触发器插入或更新视图
【发布时间】:2014-03-09 08:31:56
【问题描述】:

我想给视图写一个触发器,VW_BANKBRANCH:

  • 如果插入的行包含表中存在的bankcode,则更新 bName 插入数据的银行表列
  • 如果没有,请在银行表中插入行以反映新信息。

但是我的触发器不起作用..

我的桌子

CREATE TABLE bank(
  code VARCHAR(30) PRIMARY KEY,
  bName VARCHAR(50)
);

CREATE TABLE branch(
  brNum INT PRIMARY KEY,
  brName VARCHAR(50),
  braddress VARCHAR(50),
  bcode VARCHAR(30) REFERENCES bank(code)
);

CREATE VIEW VW_BANKBRANCH
AS
  SELECT code,bname,brnum,brName
  FROM bank ,branch
  WHERE code=bcode

我的触发器

CREATE TRIGGER tr_VW_BANKBRANCH_INSERT ON VW_BANKBRANCH
INSTEAD OF INSERT
AS
BEGIN
  DECLARE @insertedBankCode INT
    @insertedbname varchar
    @insertedbrnum int
    @insertedbrName varchar

SELECT @insertedBankCode = code
FROM INSERTED

IF(@insertedBankCode=code)
  SET code=@insertedBankCode
bname=@insertedbname
    brnum=@insertedbrnum
    brName=@insertedbrName
ELSE
    insert(code,bname,brnum,brName)
END

【问题讨论】:

  • 究竟是什么不起作用?根本不会跑?它不会产生预期的结果?不会编译? ...?
  • 是的,它不会产生预期的结果

标签: sql-server tsql triggers


【解决方案1】:

我已经在下面的视图中调整了而不是触发器 - 我假设您想相应地更新银行和分行(尽管请注意,分行地址当前不在视图中)。

也就是说,我会小心(ab)在 INSERT 上使用而不是触发器来执行 upserts - 这对读者来说可能并不完全直观。

另外,请记住,INSERTED 伪表可能包含一组行,因此需要相应地调整为基于设置的方法。

CREATE TRIGGER tr_VW_BANKBRANCH_INSERT ON VW_BANKBRANCH
INSTEAD OF INSERT
AS
BEGIN
    SET NOCOUNT ON;

    UPDATE b
        SET bname = i.bname
        FROM bank b
            INNER JOIN inserted i
            ON i.code = b.code;

    UPDATE br
        SET
            br.brName = i.brName,
            br.braddress = NULL -- TODO add this to the view
        FROM branch br
            INNER JOIN inserted i
            ON br.bcode = i.code
            AND br.brNum = i.brNum;

    INSERT INTO bank(code, bname)
        SELECT code, bname
        FROM inserted i
        WHERE NOT EXISTS
            (SELECT 1 FROM bank b WHERE b.code = i.Code);

    INSERT INTO Branch(brNum, brName, braddress, bcode)
        SELECT brNum, brName, NULL, code
        FROM inserted i
        WHERE NOT EXISTS
            (SELECT 1 
                     FROM branch br 
                     WHERE br.bcode = i.Code AND br.brNum = i.brNum);

END;
GO

SqlFiddle here - 我还调整了视图以使用 JOIN,而不是旧样式的 WHERE 连接。

如果您有 SqlServer 2008 或更高版本,您还可以使用 MERGE 而不是单独的插入和更新。

【讨论】:

  • 很高兴我能帮上忙!我希望你不介意 - 我改变了你的问题的标题 - 可能这会在未来对其他人有所帮助。
猜你喜欢
  • 2021-05-01
  • 1970-01-01
  • 2013-09-07
  • 2015-09-01
  • 1970-01-01
  • 2013-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多