views:

139

answers:

3

I have a trigger that supposed to update log out time[generate random log out time within an hour of log in time, seconds have to differ too], how do I achieve that functionality, please help here is my trigger so far:

USE TestDB
GO
CREATE TRIGGER AfterInsertTG
ON dbo.usage_reports_Dummy2
AFTER INSERT AS

    DECLARE @pk_id as int, @member_id as int,@login_time AS DATETIME,@logout_time AS DATETIME
    ,@ip AS VARCHAR(255),@session_id AS VARCHAR(255);
    SELECT 
     @pk_id = pk_id ,
     @member_id = member_id,
     @login_time =login_time,
     @logout_time = logout_time,
     @ip = ip,
     @session_id = session_id
    FROM
     usage_reports_Dummy2


    IF(@logout_time IS NULL)

     BEGIN
     ??????? 
     END  

GO

Thank you all for helping me out specially Eric for taking some time and think about the formula, I chose Marc's answer becuase it suits my conditions

here is the final code:

CREATE TRIGGER trgInsert
ON dbo.usage_reports_Dummy2
INSTEAD OF INSERT
AS BEGIN
    INSERT INTO 
       dbo.usage_reports_Dummy2(member_id, login_time, logout_time, ip, session_id)
          SELECT 
             member_id, login_time, logout_time, ip, session_id
          FROM inserted 
          WHERE logout_time IS NOT NULL

    INSERT INTO 
       dbo.usage_reports_Dummy2(member_id, login_time, logout_time, ip, session_id)
          SELECT 
              member_id, login_time, DATEADD(ss, RAND() * 3600, login_time), 
              ip, session_id
          FROM inserted 
          WHERE logout_time IS NULL
END
+1  A: 

You can use newid to generate a random sequence for you, then send it to checksum to get an int out of it, and then mod (%) it by 3600 (seconds in an hour). Using the dateadd function, you can add that random amount of seconds to your @login_time.

select @logout_time = dateadd(ss, checksum(newid()) % 3600, @login_time)

It should be noted that rand only returns one value per statement, so all of your rows would have the same variance between @login_time and @logout_time.

However, if is a single row, then this works well:

select @logout_time = dateadd(ss, rand() * 3600, @login_time)
Eric
Thanks for your help but it's giving me invalid parameter errorInvalid parameter 1 specified for dateadd.
fzshah76
it should be DATEADD(ss, rand() * 3600, @login_time) - no quotes around ss
marc_s
Fixed. Sorry about that.
Eric
A: 

First thing you have to understand in writng a trigger is that you cannot assume that only one record will be processed at a time. SO first you need to rethink your process to not use variables that way. Trigger must be written to account for set-based operations.

Triggers have two pseuddotables intserted and deleted which store the information you need. In your case inserted has what you want. something like this (using the idea from above) might work:

update u
set logout_time = dateadd(ss, checksum(newid()) % 3600, login_time)
from usage_reports_Dummy2 u
join inserted i on u.id = i.id
where logout_time is null

This will update anyrecords that were inthe current insert that do not have a logout_time to the random value based onthe formula dateadd('ss', checksum(newid()) % 3600, login_time).

Test this and see what it will do. Possibly the formula will need tweaking.

HLGEM
it should be DATEADD(ss, rand() * 3600, @login_time) - no quotes around ss
marc_s
Thanks Marc, fixed now
HLGEM
I'll second the point about set-based operations, having been bitten, hard, by this back when I didn't know better....
RolandTumble
A: 

What you could do is create an INSTEAD OF INSERT trigger something like this:

CREATE TRIGGER trgInsert
ON dbo.usage_reports_Dummy2
INSTEAD OF INSERT
AS BEGIN
    INSERT INTO 
       dbo.usage_reports_Dummy2(member_id, login_time, logout_time, ip, session_id)
          SELECT 
             member_id, login_time, logout_time, ip, session_id
          FROM inserted 
          WHERE logout_time IS NOT NULL

    INSERT INTO 
       dbo.usage_reports_Dummy2(member_id, login_time, logout_time, ip, session_id)
          SELECT 
              member_id, login_time, DATEADD(ss, RAND() * 3600, login_time), 
              ip, session_id
          FROM inserted 
          WHERE logout_time IS NULL
END

That way, if a "logout_time" is provided, the values are stored "as is", and if not, then your logout_time is calculated based on your requirements.

Marc

marc_s
Thanks working perfectly:)
fzshah76