-1

好的,所以我有一个相当基本的触发器:

换句话说,在插入之后,获取 IP 信息并使用新数据更新插入的行

CREATE TRIGGER [BasicData.IPInfo.Gather]
ON [BasicData]
AFTER INSERT
AS
BEGIN
    DECLARE @City VARCHAR(1000),
        @Country VARCHAR(1000),
        @IP VARCHAR(1000),
        @ROWID UNIQUEIDENTIFIER

    SELECT @IP=[IP],@ROWID=[ID] FROM [inserted]

    SELECT @Country = [Country], @City= [City]
    FROM [IPInfo] WHERE [IP] = @IP

    IF (@City IS NOT NULL) AND (@Country IS NOT NULL)
        BEGIN -- Never seems to fire
            UPDATE [BasicData]
            SET [IPCountry]=@Country,[IPCity]=@City
            WHERE [ID] = @ROWID
        END
    ELSE
        BEGIN -- Fired correctly
            INSERT INTO [IPInfo.Missing] VALUES (@IP)
        END
END

现在的问题是,它正确添加了丢失的 IP 信息(仅在丢失时),但是,它似乎并没有更新表,我错过了什么?

我已经以我能想到的所有可能方式对其进行了调整......(我的触发知识相当糟糕)

4

1 回答 1

0

有几个问题:

  1. INSERTED 可以包含许多行。您的触发器只允许一个。
  2. 触发器是在插入之后,我猜这可能会排除更新。尝试AFTER INSERT, UPDATE
  3. 您的 IF 语句没有检查 UPDATE - 如果列被 UPDATED 为 NULL 怎么办?即使它是更新,它也不会捕获它。如果有东西插入了 NON NULL 数据怎么办?它会认为这是一个更新。

据我所知,识别 UPDATE 的唯一方法是加入 INSERTED并在 PK 上删除。如果有匹配,则已更新。

也许你可以这样重写它:

CREATE TRIGGER [BasicData.IPInfo.Gather]
ON [BasicData]
AFTER INSERT, UPDATE
AS
BEGIN

-- Save UPDATES to BasicData
UPDATE [BasicData]
SET [IPCountry]=I.Country,[IPCity]=I.City
FROM [BasicData] UT
INNER JOIN
[inserted] I
ON I.ID = UT.ID
INNER JOIN
Deleted D
ON D.ID = I.ID
INNER JOIN
[IPInfo] IP
ON I.ID = IP.ID

-- Save inserts to Missing
INSERT INTO [IPInfo.Missing] (IP)
SELECT IP FROM
INSERTED I
WHERE NOT EXISTS (SELECT 1 FROM DELETED D WHERE D.ID = I.ID)

END
于 2013-04-07T08:21:55.197 回答