Reputation: 2432
I am transitioning my database from storing datetimes in Pacific time into UTC, but will not be changing all of the code at the same time.
I am trying to write a trigger that will update times entered in either column and convert them and insert them into the other column.
Ex. If I insert a Pacific time in the OriginalTime column, it should convert the time to UTC and update the NewTime column with a time in UTC. Conversely, if I insert/update the value in NewTime, it should convert the time back to Pacific and put it in OriginalTime.
Am I looping things incorrectly or something?
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
For some reason, my current trigger is entering the converted value correctly, but the insert that caused the trigger to fire seems to be failing.
If I insert a value:
INSERT INTO Calls (CreateDate)
VALUES (GETDATE()) -- getdate currently outputs in pacific time
I get the trigger result but not the inserted value:
+-----------------+--------------------------+
| CreateDate | CreateDateUTC |
+-----------------+--------------------------+
| NULL | 2013-01-24 20:27:13.510 |
+-----------------+--------------------------+
Upvotes: 0
Views: 219
Reputation: 11813
On an insert UPDATE(column)
is true for all columns. That is wh your second update writes a null into the CreateDate column.
So you need to create two triggers, One that deals with updates as in your code and one that deals with inserts. If only CreateDate is valued, CreateDateUTC is NULL and you can check for that.
Also, you should really not use a cursor for this. Use something like this instead:
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;
That is, for the insert trigger. For the UPDATE you can use something like this:
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;
This is all untested code, but it should work.
EDIT: See my longer comment below for why you really should wrap this UPDATE
inside of an IF
statement.
Upvotes: 5