SQL触发器触发但未插入原始值

时间:2013-01-24 22:50:27

标签: sql sql-server-2005 triggers

我正在将我的数据库从太平洋时间的日期时间转换为UTC,但不会同时更改所有代码。

我正在尝试编写一个触发器,它将更新在任一列中输入的时间并转换它们并将它们插入另一列。

实施例。如果我在OriginalTime列中插入太平洋时间,它应该将时间转换为UTC并使用UTC时间更新NewTime列。相反,如果我在NewTime中插入/更新值,它应该将时间转换回Pacific并将其放入OriginalTime。

我是否错误地循环了某些内容?

ALTER TRIGGER tr_Calls_CreateDate ON Calls
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON

DECLARE
    @CallId INT,
    @CreateDate DATETIME,
    @CreateDateUTC DATETIME

--Create cursor
DECLARE CreateDate_Cursor CURSOR LOCAL FOR
    SELECT CallId, CreateDate, CreateDateUTC FROM Inserted

OPEN CreateDate_Cursor;

-- Get First Row
FETCH NEXT FROM CreateDate_Cursor INTO @CallId, @CreateDate, @CreateDateUTC;

WHILE @@FETCH_STATUS = 0
BEGIN
    IF UPDATE ([CreateDate])
    BEGIN
        UPDATE Calls
        SET CreateDateUTC = dbo.ConvertPacificTimeToUTC(@CreateDate)
        WHERE CallId = @CallId
    END

    IF UPDATE ([CreateDateUTC])
    BEGIN
        UPDATE Calls
        SET CreateDate = dbo.ConvertUTCTimeToPacific(@CreateDateUTC)
        WHERE CallId = @CallId
    END

    FETCH NEXT FROM CreateDate_Cursor INTO @CallId, @CreateDate, @CreateDateUTC;
END

-- Free Up Cursor
CLOSE CreateDate_Cursor;
DEALLOCATE CreateDate_Cursor;
END

由于某种原因,我当前的触发器正确输入转换后的值,但导致触发器触发的插入似乎失败。

如果我插入一个值:

INSERT INTO Calls (CreateDate)
VALUES (GETDATE()) -- getdate currently outputs in pacific time

我得到了触发结果,但没有插入值:

+-----------------+--------------------------+
|   CreateDate    |      CreateDateUTC       |
+-----------------+--------------------------+
|       NULL      | 2013-01-24 20:27:13.510  |
+-----------------+--------------------------+

1 个答案:

答案 0 :(得分:5)

对于所有列,插入UPDATE(column)都是如此。这是你的第二次更新将null写入CreateDate列。

因此,您需要创建两个触发器,一个处理代码中的更新,另一个处理插入。如果仅对CreateDate进行了估值,则CreateDateUTC为NULL,您可以检查它。

另外,你真的不应该使用游标。请改用这样的东西:

UPDATE c SET
  CreateDate = ISNULL(CreateDate, dbo.ConvertUTCTimeToPacific(i.CreateDateUTC)),
  CreateDateUTC = ISNULL(CreateDateUTC, dbo.ConvertPacificTimeToUTC(i.CreateDate))
FROM dbo.Calls AS c
JOIN INSERTED AS i
ON i.CallId = c.CallId;

也就是说,对于插入触发器。对于UPDATE,您可以使用以下内容:

UPDATE c SET
  CreateDate = CASE WHEN UPDATE ([CreateDateUTC]) THEN CreateDate
                  ELSE dbo.ConvertUTCTimeToPacific(i.CreateDateUTC)
               END,
  CreateDateUTC = CASE WHEN UPDATE ([CreateDate]) THEN CreateDateUTC
                    ELSE dbo.ConvertPacificTimeToUTC(i.CreateDate)
                  END
FROM dbo.Calls AS c
JOIN INSERTED AS i
ON i.CallId = c.CallId;

这是所有未经测试的代码,但它应该有效。


编辑:请参阅下面的更长评论,了解为什么要真正将UPDATE包含在IF语句中。