Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
tubbscc
Starting Member
3 Posts |
Posted - 2010-03-24 : 22:37:04
|
| SQL 2000: I have a table Enrolments that I need to log any attempted change to the ResultDate field if ResultDate=5 to another table enrolments_audit. I then need to block that update from happening once logged. Let me know if you need more info and thanks for the help.--Enrolments Table DesignSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [dbo].[Enrolments]( [IDco] [int] NOT NULL DEFAULT (0), [IDu] [int] NOT NULL DEFAULT (0), [EnrolDate] [datetime] NOT NULL DEFAULT (getdate()), [DueDate] [datetime] NULL, [Result] [smallint] NOT NULL DEFAULT (0), [ResultDate] [datetime] NULL, [Type] [smallint] NOT NULL DEFAULT (0), CONSTRAINT [aaaaaEnrolments_PK] PRIMARY KEY CLUSTERED ( [IDco] ASC, [IDu] ASC)WITH FILLFACTOR = 90 ON [PRIMARY]) ON [PRIMARY]--Enrolments_Audit Table DesignSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [dbo].[Enrolments_Audit]( [IDco] [int] NOT NULL CONSTRAINT [DF__Enrolments__IDco__5BED93EA] DEFAULT (0), [IDu] [int] NOT NULL CONSTRAINT [DF__Enrolments___IDu__5CE1B823] DEFAULT (0), [EnrolDate] [datetime] NOT NULL CONSTRAINT [DF__Enrolment__Enrol__5DD5DC5C] DEFAULT (getdate()), [DueDate] [datetime] NULL, [Result] [smallint] NOT NULL CONSTRAINT [DF__Enrolment__Resul__5ECA0095] DEFAULT (0), [ResultDate] [datetime] NULL, [Type] [smallint] NOT NULL CONSTRAINT [DF__Enrolments__Type__5FBE24CE] DEFAULT (0), [UpdateAttemptDate] [datetime] NULL) ON [PRIMARY]This is my first time writing a trigger and it's been slow going with alot of mistakes along the way. This is the code I have so far that does log the update to enrolments.ResultDate if Result=5 but two problems still.1. I thought I could use a Rollback Transaction after inserting all deleted values into enrolments_audit but that just undoes/blocks what I just did.2. When updating the UpdateAttemptDate in enrolments_audit if there are more than one row with the same data except for the UpdateAttempDate all rows with the same data get the same UpdateAttemptDate I just set, I realize I need a qualifier here but not sure what.Here's my trigger so far, be kind as I've worked really hard on this and it almost works. If what I've done is completely wrong please advise on a better direction.--Trigger Codeset ANSI_NULLS ONset QUOTED_IDENTIFIER ONGOCREATE TRIGGER [dbo].[trig_testEnrolments] ON [dbo].[Enrolments] FOR UPDATE ASSET NOCOUNT ON/*PREVENT UPDATES TO 'RESULTDATE' IF 'RESULT' ALREADY = 5 IMPLEMENTED TO RESOLVE UNWANTED CHANGES TO THE RESULTDATE---ONLY IMPLEMENTED FOR DRIVING SAFETY DB*/IF UPDATE (ResultDate)BEGIN IF EXISTS (SELECT * FROM deleted WHERE Result = 5) BEGIN /*** COPY ALL ROWS TO BE UPDATED TO ENROLMENTS_AUDIT TABLE Working now ***/ INSERT enrolments_audit (IDco, IDu, EnrolDate, DueDate, Result, ResultDate, Type) SELECT IDco, IDu, EnrolDate, DueDate, Result, ResultDate, Type FROM deleted /*** DECLARE LOCAL VARIABLES ***/ DECLARE @IDco Int DECLARE @IDu Int DECLARE @EnrolDate DateTime DECLARE @DueDate DateTime DECLARE @Result SmallInt DECLARE @ResultDate DateTime DECLARE @Type SmallInt /*** SET LOCAL VARIABLES ***/ SET @IDco = (SELECT IDco FROM deleted) SET @IDu = (SELECT IDu FROM deleted) SET @EnrolDate = (SELECT EnrolDate FROM deleted) SET @DueDate = (SELECT DueDate FROM deleted) SET @Result = (SELECT Result FROM deleted) SET @ResultDate = (SELECT ResultDate FROM deleted) SET @Type = (SELECT Type FROM deleted) /*** LOG DATE/TIME FOR 'UpdateAttemptDate' FOR NEW LOG ENTRY ***/ UPDATE enrolments_audit SET UpdateAttemptDate = GetDate() WHERE @IDco = enrolments_audit.Idco AND @IDu = enrolments_audit.IDu AND @EnrolDate = enrolments_audit.EnrolDate AND @DueDate = enrolments_audit.DueDate AND @Result = enrolments_audit.Result AND @ResultDate = enrolments_audit.ResultDate AND @Type = enrolments_audit.Type /*** Print 'Attempt to update ResultDate was STOPPED' ***/ /*** DO SOMETHING TO STOP THE UPDATE HERE ***/ /*** ROLLBACK TRANSACTION ***/ ENDEND |
|
|
Lumbago
Norsk Yak Master
3271 Posts |
Posted - 2010-03-25 : 04:24:49
|
Look up the syntax for CREATE TRIGGER in Books Online:CREATE TRIGGER [dbo].[trig_testEnrolments] ON [dbo].[Enrolments] INSTEAD OF UPDATE AS - LumbagoIf the facts don't fit the theory, change the facts. Albert Einstein |
 |
|
|
Lumbago
Norsk Yak Master
3271 Posts |
Posted - 2010-03-25 : 04:25:28
|
| http://msdn.microsoft.com/en-us/library/aa258254(SQL.80).aspx- LumbagoIf the facts don't fit the theory, change the facts. Albert Einstein |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2010-03-25 : 05:00:10
|
"/*** SET LOCAL VARIABLES ***/SET @IDco = (SELECT IDco FROM deleted)SET @IDu = (SELECT IDu FROM deleted)SET @EnrolDate = (SELECT EnrolDate FROM deleted)SET @DueDate = (SELECT DueDate FROM deleted)SET @Result = (SELECT Result FROM deleted)SET @ResultDate = (SELECT ResultDate FROM deleted)SET @Type = (SELECT Type FROM deleted)/*** LOG DATE/TIME FOR 'UpdateAttemptDate' FOR NEW LOG ENTRY ***/UPDATE enrolments_audit SET UpdateAttemptDate = GetDate()WHERE @IDco = enrolments_audit.IdcoAND @IDu = enrolments_audit.IDuAND @EnrolDate = enrolments_audit.EnrolDateAND @DueDate = enrolments_audit.DueDateAND @Result = enrolments_audit.ResultAND @ResultDate = enrolments_audit.ResultDateAND @Type = enrolments_audit.Type"Two suggestions:This only selects one row (in effect at random from DELETED table), so is not safe as the trigger will fire only once for multiple rows deleted in a single batchMultiple SET statements will be slow, instead useSELECT @IDco = IDco @IDu = IDu... @Type = TypeFROM deleted this will also ensure that the variables are set to the SAME row. However, you still have the problem that this will only select one row from DELETED (at random).Not sure what your logic is intended to be here, but you can solve this by just using DELETED in a JOINUPDATE USET UpdateAttemptDate = GetDate()FROM enrolments_audit AS U JOIN DELETED AS D ON D.IDco = U.Idco AND D.IDu = U.IDu AND D.EnrolDate = U.EnrolDate AND D.DueDate = U.DueDate AND D.Result = U.Result AND D.ResultDate = U.ResultDate AND D.Type = U.Type but I think what you should be doing is to use teh Priamry Key for the join - maybe it is possible all those stated fields are not UNIQUE within the database?[code]UPDATE USET UpdateAttemptDate = GetDate()FROM enrolments_audit AS U JOIN DELETED AS D ON D.MyID = U.MyID |
 |
|
|
tubbscc
Starting Member
3 Posts |
Posted - 2010-03-25 : 13:15:14
|
quote: Originally posted by Lumbago Look up the syntax for CREATE TRIGGER in Books Online:CREATE TRIGGER [dbo].[trig_testEnrolments] ON [dbo].[Enrolments] INSTEAD OF UPDATE AS - LumbagoIf the facts don't fit the theory, change the facts. Albert Einstein
Lumbago, I did try the INSTEAD OF UPDATE with the same trigger code I posted before. I learned that this prevents any updates to the enrolment table at all regardless of Result. I do want other update to occur, I only want to block updating the ResultDate if the Result is already 5.I thought initially that the INSTEAD OF UPDATE would see the update attempt and then decide whether to allow or block the update based on this logic:IF UPDATE (ResultDate)BEGINIF EXISTS (SELECT * FROM deleted WHERE Result = 5)BEGIN |
 |
|
|
tubbscc
Starting Member
3 Posts |
Posted - 2010-03-25 : 13:18:14
|
| Kristen, I think I see what you are saying here. I will attempt to make the changes you suggest and see if I can get that to work. |
 |
|
|
|
|
|
|
|