创建更新触发器以基于table2中的值更新table1中的列

时间:2018-05-07 04:12:18

标签: sql-server tsql database-trigger

在此帖子的底部更新

我在SQL Server中有两个表,下面是每个表的简化视图。

表1

| ObjectID | Name | Email |
+----------+------+-------+
| 1        | Ben  |       |
| 2        | Tom  |       |

表2

| ObjectID  | Name |     Email     |
+-----------+------+---------------+
| 52        | Ben  | ben@email.com |
| 53        | Tom  | tom@email.com |

我想在数据库中创建一个更新table1的触发器,当我更新名称字段时,触发器会触发,并插入可以在table2中找到的电子邮件地址。

注意:两个表都有更多列

注意2:当一行插入表1时,它只接收一个ObjectID,然后在用户添加名称的地方进行更新。

用户添加此名称后,我希望数据库运行并查看table2,找到匹配的名称,然后返回table1并在其中写入数据。

我已经写了(不成功)下面的代码,我尝试过使用update()和其他一些东西,但我觉得我的方法不合适:

CREATE TRIGGER "acc_insert_email" 
ON TABLE1
AFTER UPDATE
AS
BEGIN
    INSERT INTO TABLE1(email)
        SELECT i.email 
        FROM TABLE1 t 
        INNER JOIN TABLE2 i ON t.email = i.email
END

有人能指出我正确的方向吗?

提前致谢。

所以我测试了@Ezlo提供的答案,但没有运气......我稍微修改了它而不是在列中插入单词TEST,看它是否会这样做,但是这也没有影响。这是我目前的代码,请注意我使用了实际的表名和列名:

CREATE TRIGGER "gisadmin"."acc_UpdateOfficerDetails" ON NOXIOUS_WEED_INSPECTION_POINT AFTER UPDATE
AS
BEGIN

    IF UPDATE(authorised_officer_email)
    BEGIN

        UPDATE T SET
            authorised_officer_email = 'TEST'
        FROM
            inserted AS I
            INNER JOIN NOXIOUS_WEED_INSPECTION_POINT AS T ON I.authorised_officer = T.authorised_officer
            LEFT JOIN AUTH_DB.authlive.dbo.acc_weave_emp_details AS N ON I.authorised_officer = N.cus_idd

    END
END

authorised_officercus_idd是工作人员用户名(我已成功完成这两个字段的简单连接,它运行正常,因此我排除了两种不同的数据类型是问题)

所以我很困惑为什么这个触发器甚至没有插入简单的测试'给我发短信。

有什么想法吗?

以下是回答我原始问题的最终代码,效果很棒!谢谢@EzLo

CREATE TRIGGER "gisadmin"."acc_UpdateOfficerDetails" ON NOXIOUS_WEED_INSPECTION_POINT AFTER
UPDATE AS BEGIN IF
UPDATE
    (authorised_officer) BEGIN
UPDATE
    T
SET
    authorised_officer_email = A.mto_lst
FROM
    inserted AS I
INNER JOIN
    NOXIOUS_WEED_INSPECTION_POINT AS T
ON
    I.authorised_officer = T.authorised_officer
LEFT JOIN
    AUTH_DB.authlive.dbo.acc_weave_emp_details AS A
ON
    I.authorised_officer = A.cus_idd
END
END

1 个答案:

答案 0 :(得分:1)

您可以使用以下内容。

CREATE TRIGGER tr_UpdateTable1Email ON TABLE1 AFTER UPDATE
AS
BEGIN

    IF UPDATE(Name)
    BEGIN

        UPDATE T SET
            Email = N.Email
        FROM
            inserted AS I
            INNER JOIN TABLE1 AS T ON I.Name = T.Name
            LEFT JOIN TABLE2 AS N ON I.Name = N.Name

    END
END

触发器将在TABLE1更新时执行,只有在原始更新语句包含name列时才会执行内部更新。 inserted是一个特殊的触发器表,用于保存已更新的跟踪表(在本例中为TABLE1)的行。加入inserted TABLE1以更新正确的电子邮件,然后搜索电子邮件以更新为TABLE2

让我提一下你有非规范化数据,这会导致维护问题(如果有人更新TABLE2的姓名或电子邮件会发生什么?} TABLE1的记录会不同步。您应该将名称和电子邮件(以及其他相关数据)保存在一个位置,因此只需要进行一次更新。

编辑:更新超过1列(无需括号)。

ALTER TRIGGER "gisadmin"."acc_UpdateOfficerDetails" ON NOXIOUS_WEED_INSPECTION_POINT AFTER UPDATE 
AS 
BEGIN 
    IF UPDATE (authorised_officer) 
    BEGIN

        UPDATE
            T
        SET
            authorised_officer_email = A.mto_lst,
            authorised_officer_phone = A.bus_mob
        FROM
            inserted AS I
        INNER JOIN
            NOXIOUS_WEED_INSPECTION_POINT AS T
        ON
            I.authorised_officer = T.authorised_officer
        LEFT JOIN
            AUTH_DB.authlive.dbo.acc_weave_emp_details AS A
        ON
            I.authorised_officer = A.cus_idd

    END
END