【问题标题】:Create Trigger on 2 tables from 2 differents bases在来自 2 个不同基础的 2 个表上创建触发器
【发布时间】:2017-07-19 13:30:50
【问题描述】:

您好,我正在研究触发器。此触发器能够比较从基 F 插入我的表 DOUBLON 的数据与从基 T 的 CLIENT 中的数据。 如果有类似的 TEL、TELPOR、TELPRO、TELDOM,那么它会更新 F.DOUBLON.doublon = 'OUI' 否则它会输入一个 'NON'。 我在 DOUBLON 表的基础 F 上创建了触发器。

我做了什么:

    CREATE TRIGGER DoublonInserted
    ON  dbo.DOUBLON
    AFTER INSERT
    AS 
    DECLARE @doublon INTEGER
    SELECT @doublon = 0
    IF SELECT count(C.TEL)
    FROM T.dbo.CLIENT AS C , inserted AS I
    where I.TEL = C.TEL
    OR I.TEL = C.TELDOM
    OR I.TEL = C.TELPRO
    OR I.TEL = C.TELPOR
    OR I.TELDOM = C.TEL
    OR I.TELDOM = C.TELDOM
    OR I.TELDOM = C.TELPRO
    OR I.TELDOM = C.TELPOR
    OR I.TELPRO = C.TEL
    OR I.TELPRO = C.TELDOM
    OR I.TELPRO = C.TELPRO
    OR I.TELPRO = C.TELPOR
    OR I.TELPOR = C.TEL
    OR I.TELPOR = C.TELDOM
    OR I.TELPOR = C.TELPRO
    OR I.TELPOR = C.TELPOR) > 1
    BEGIN
    UPDATE dbo.DOUBLON
    SET DOUBLON = 'OUI' --, @doublon = 0 
    FROM T.dbo.CLIENT AS C, inserted AS I
    where I.TEL = C.TEL
    OR I.TEL = C.TELDOM
    OR I.TEL = C.TELPRO
    OR I.TEL = C.TELPOR
    OR I.TELDOM = C.TEL
    OR I.TELDOM = C.TELDOM
    OR I.TELDOM = C.TELPRO
    OR I.TELDOM = C.TELPOR
    OR I.TELPRO = C.TEL
    OR I.TELPRO = C.TELDOM
    OR I.TELPRO = C.TELPRO
    OR I.TELPRO = C.TELPOR
    OR I.TELPOR = C.TEL
    OR I.TELPOR = C.TELDOM
    OR I.TELPOR = C.TELPRO
    OR I.TELPOR = C.TELPOR 
    END
    ELSE
    BEGIN
    UPDATE dbo.DOUBLON
    SET DOUBLON = 'NON' --, @doublon = 0
    FROM T.dbo.CLIENT AS C, inserted AS I
    where I.TEL != C.TEL
    OR I.TEL != C.TELDOM
    OR I.TEL != C.TELPRO
    OR I.TEL != C.TELPOR
    OR I.TELDOM != C.TEL
    OR I.TELDOM != C.TELDOM
    OR I.TELDOM != C.TELPRO 
    OR I.TELDOM != C.TELPOR
    OR I.TELPRO != C.TEL
    OR I.TELPRO != C.TELDOM
    OR I.TELPRO != C.TELPRO
    OR I.TELPRO != C.TELPOR
    OR I.TELPOR != C.TEL
    OR I.TELPOR != C.TELDOM
    OR I.TELPOR != C.TELPRO
    OR I.TELPOR != C.TELPOR
    END

事实上它是“工作”而不是现实:

案例工作。 如果我的插入中有任何重复,请在我的列 doublon 中为插入的每一行触发设置“NON”。 如果我的插入中只有重复项,请在我的列 doublon 中为插入的每一行触发设置“OUI”。

案例不工作。 如果有重复且没有插入重复,则无法正常工作。

我尝试重置我的 var @doublon 但还是一样。

我注意到,我的触发器将我的测试的最后结果放在了 doublon 列的所有行上。如果最新插入的是重复数据,则所有行都将显示“是”(反之亦然)。

我想请人帮忙解释一下原因,或者用其他方法(使用触发器)。

我无法触摸数据库 T(禁止添加列等)!

++ 基地在同一台服务器上 ++

感谢您的宝贵时间和您的帮助!

编辑:

表客户端

表DOUBLON

ID_CLIENT -> 整数

我想要什么: 在 Doublon 上设置正确的值

其他一切 varchar(50)

【问题讨论】:

  • Bad habits to kick : using old-style JOINs - 旧式 逗号分隔的表格列表 样式已替换为 ANSI 中的 proper ANSI JOIN 语法-92 SQL 标准(25 年前),不鼓励使用它
  • 你能找一位以英语为母语的人来帮你重写你的问题吗?我试图阅读它,但我就是不能。
  • 这里有一些严重的逻辑问题。首先,您的更新语句将更新 DOUBLON 中的每一行。其次,如果第一个条件为真,它将只运行第一个更新语句,否则它将运行第二个。您的插入中可能有同时满足这两个条件的数据。
  • 我会试试你的语法@marc_s 谢谢你的提示!
  • 我们不想逐行写任何东西。相反,它应该设置为基于更新。我不能在这里提供太多,因为我不知道你的桌子是什么样子的。这是一个很好的起点。 spaghettidba.com/2015/04/24/…

标签: sql-server database triggers insert


【解决方案1】:

我想我明白你现在想要什么了。这是您如何将其创建为触发器而不是触发器的方法。这应该非常接近。

CREATE TRIGGER DoublonInserted 
    ON dbo.DOUBLON
    INSTEAD OF INSERT AS 
BEGIN
    SET NOCOUNT ON;

    INSERT DOUBLON
    (
        ID_CLIENT
        , NOM
        , PRENOM
        , TEL
        , TELDOM
        , TELPRO
        , TELPOR
        , DOUBLON
    )
    select i.ID_CLIENT
        , i.NOM
        , i.PRENOM
        , i.TEL
        , i.TELDOM
        , i.TELPRO
        , i.TELPOR
        , case when 
                I.TEL = C.TEL
                OR I.TEL = C.TELDOM
                OR I.TEL = C.TELPRO
                OR I.TEL = C.TELPOR
                OR I.TELDOM = C.TEL
                OR I.TELDOM = C.TELDOM
                OR I.TELDOM = C.TELPRO
                OR I.TELDOM = C.TELPOR
                OR I.TELPRO = C.TEL
                OR I.TELPRO = C.TELDOM
                OR I.TELPRO = C.TELPRO
                OR I.TELPRO = C.TELPOR
                OR I.TELPOR = C.TEL
                OR I.TELPOR = C.TELDOM
                OR I.TELPOR = C.TELPRO
                OR I.TELPOR = C.TELPOR
            THEN 'OUI'
            ELSE 'NON'
            END
    FROM inserted AS I
    join T.dbo.CLIENT AS C on c.ID_CLIENT = i.ID_CLIENT;
END

在细节上仍然很模糊,但我认为你想要这样的东西。

CREATE TRIGGER DoublonInserted 
    ON dbo.DOUBLON
    INSTEAD OF INSERT AS 
BEGIN
    SET NOCOUNT ON;

    INSERT DOUBLON
    (
        ID_CLIENT
        , NOM
        , PRENOM
        , TEL
        , TELDOM
        , TELPRO
        , TELPOR
        , DOUBLON
    )
    select i.ID_CLIENT
        , i.NOM
        , i.PRENOM
        , i.TEL
        , i.TELDOM
        , i.TELPRO
        , i.TELPOR
        ,  CASE 
                when C.TEL IS NULL
                    OR C.TELPRO IS NULL
                    OR C.TELDOM IS NULL
                    OR C.TELPOR IS NULL
                THEN 'NON'
                ELSE 'OUI'
            END
    FROM inserted AS I
    left join T.dbo.CLIENT AS C on I.TEL = C.TEL
                                OR I.TEL = C.TELPRO
                                OR I.TEL = C.TELDOM
                                OR I.TEL = C.TELPOR
END

【讨论】:

  • 好的。我在这里猜测是因为我几乎没有什么细节可以处理。您如何知道插入的新行与 CLIENT 中的现有行相关?也许您只需要修改连接谓词?
  • 我们不希望在 TEL(电话号码)上重复,所以我们对此进行测试(您的“关心什么时候”)。如果除 TEL、TELPRO、TELDOM、TELPOR 之外的所有数据都相同,则行不会被视为重复。
  • @PandaRasta 查看我的最新编辑。我仍然对您的要求有所猜测,但我认为这更接近您想要的。
  • 我现在无法访问数据库,所以我将在明天早上测试它。感谢您的帮助和时间!
【解决方案2】:

您只需要一个“查找双重”查询:

CREATE TRIGGER DoublonInserted
ON  dbo.DOUBLON
AFTER INSERT
AS BEGIN
IF EXISTS(
    select * from
    FROM T.dbo.CLIENT AS C, inserted AS I
    where I.TEL = C.TEL
    OR I.TEL = C.TELDOM
    OR I.TEL = C.TELPRO
    OR I.TEL = C.TELPOR
    OR I.TELDOM = C.TEL
    OR I.TELDOM = C.TELDOM
    OR I.TELDOM = C.TELPRO
    OR I.TELDOM = C.TELPOR
    OR I.TELPRO = C.TEL
    OR I.TELPRO = C.TELDOM
    OR I.TELPRO = C.TELPRO
    OR I.TELPRO = C.TELPOR
    OR I.TELPOR = C.TEL
    OR I.TELPOR = C.TELDOM
    OR I.TELPOR = C.TELPRO
    OR I.TELPOR = C.TELPOR)
    UPDATE dbo.DOUBLON
    SET DOUBLON = 'OUI'
    WHERE ID_CLIENT = I.ID_CLIENT;
ELSE
    UPDATE dbo.DOUBLON
    SET DOUBLON = 'NON'
    WHERE ID_CLIENT = I.ID_CLIENT;
END

【讨论】:

  • sql server 中没有 BEFORE 触发器之类的东西。而且这里贴出的语法对sql server无效。
  • @sean 现在怎么样? (我不会说sql server)
  • 是的......我试着像在 Oracle db 上那样做,但是 sql server 不接受之前这就是我写之后的原因。我应该使用 INSTEAD OF 吗?
  • 您需要在两个更新中加入。逻辑似乎相当接近,但这需要成为一个而不是触发器。由于这是一个插入触发器,我们可能在 DOUBLON 中还没有一行。而且我们仍然存在两个结果都为真的可能性的问题,因为 sql server 中的触发器每次操作都会触发一次。如果插入了两行,则插入的虚拟表将有两行。
  • 还有一个问题。 ID_CLIENT 与 I.ID_CLIENT 不同(不要问我为什么不是构建架构的人......)
【解决方案3】:

好吧!这是“答案”:

    CREATE TRIGGER DoublonInserted 
ON dbo.DOUBLON
INSTEAD OF INSERT AS 
    BEGIN

INSERT INTO DOUBLON
(
    ID_CLIENT
    , NOM
    , PRENOM
    , TEL
    , TELDOM
    , TELPRO
    , TELPOR
    , DOUBLON
)
select i.ID_CLIENT
    , i.NOM
    , i.PRENOM
    , i.TEL
    , i.TELDOM
    , i.TELPRO
    , i.TELPOR
    ,  CASE 
            when I.TEL = C.TEL
OR I.TEL = C.TELDOM
OR I.TEL = C.TELPRO
OR I.TEL = C.TELPOR
OR I.TELDOM = C.TEL
OR I.TELDOM = C.TELDOM 
OR I.TELDOM = C.TELPRO
OR I.TELDOM = C.TELPOR
OR I.TELPRO = C.TEL
OR I.TELPRO = C.TELDOM 
OR I.TELPRO = C.TELPRO
OR I.TELPRO = C.TELPOR
OR I.TELPOR = C.TEL
OR I.TELPOR = C.TELDOM 
OR I.TELPOR = C.TELPRO
OR I.TELPOR = C.TELPOR
            THEN 'OUI'
            ELSE 'NON'
        END
FROM inserted AS I
left join T.dbo.CLIENT AS C 
on I.TEL = C.TEL
OR I.TEL = C.TELDOMICIL
OR I.TEL = C.TELPRO
OR I.TEL = C.TELPOR
OR I.TELDOM = C.TEL
OR I.TELDOM = C.TELDOM
OR I.TELDOM = C.TELPRO
OR I.TELDOM = C.TELPOR
OR I.TELPRO = C.TEL
OR I.TELPRO = C.TELDOM
OR I.TELPRO = C.TELPRO
OR I.TELPRO = C.TELPOR
OR I.TELPOR = C.TEL
OR I.TELPOR = C.TELDOM
OR I.TELPOR = C.TELPRO
OR I.TELPOR = C.TELPOR
END

感谢@Sean Lange(你做到了!)、@Bohemian♦ 和其他所有人!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-05
    • 2017-09-30
    • 2021-03-13
    • 2021-08-14
    • 1970-01-01
    • 1970-01-01
    • 2013-07-04
    相关资源
    最近更新 更多