Author |
Topic |
DavidChel
Constraint Violating Yak Guru
474 Posts |
Posted - 2008-08-06 : 10:25:09
|
First off, I know this trigger isn't practical for anything, I am simply taking small steps towards the trigger I want.My ERP database has a table called SORels (sales order releases) and I want to create a trigger to fire on it when records are added, updated, or deleted. I decided to start with updating. I created another database to keep track of the data called SOModifications with a table called soModTest. The Create statement for soModTest is: CREATE TABLE [soModTest] ( [fenumber] [char] (3) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [fsono] [char] (6) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [fnetprice] [numeric](17, 5) NOT NULL , [forderqty] [numeric](15, 5) NOT NULL , [funetprice] [numeric](17, 5) NOT NULL , [identity_column] [int] IDENTITY (1, 1) NOT NULL ) ON [PRIMARY]GO The Trigger is here: CREATE TRIGGER SoModAudit ON M2MData01.dbo.SorelsAFTER UPDATEASSET NOCOUNT ONINSERT SOModifications.dbo.soModTest(fenumber, fsono, fnetprice, forderqty, funetprice, identity_column)VALUES('999','123456', 100.95000, 1.00000, 100.95000 ,987654)Go Can anyone tell me why I am getting a "table update failure on SORELS! Check Table" error when I try to update it through my ERP software? |
|
jimf
Master Smack Fu Yak Hacker
2875 Posts |
Posted - 2008-08-06 : 10:44:50
|
You're trying to insert 987654 into an identity column, which is a no-no. The idenity column is automatic so you can't insert a specific value in to itJim |
|
|
DavidChel
Constraint Violating Yak Guru
474 Posts |
Posted - 2008-08-06 : 11:09:40
|
So, should it read like this? CREATE TRIGGER SoModAudit ON M2MData01.dbo.SorelsAFTER UPDATEASSET NOCOUNT ONINSERT SOModifications.dbo.soModTest(fenumber, fsono, fnetprice, forderqty, funetprice)VALUES('999','123456', 100.95000, 1.00000, 100.95000)Go |
|
|
jimf
Master Smack Fu Yak Hacker
2875 Posts |
Posted - 2008-08-06 : 11:19:40
|
Yes, and the identity column will automatically increase by 1. If you specifically need to put the 987654 in, then you'd have to change the data type in the tableJim |
|
|
DavidChel
Constraint Violating Yak Guru
474 Posts |
Posted - 2008-08-06 : 11:26:26
|
Thanks Jim, that worked. |
|
|
DavidChel
Constraint Violating Yak Guru
474 Posts |
Posted - 2008-08-06 : 16:06:15
|
So, here's my current status of the code: CREATE TRIGGER SOMODAUDITON M2MDATA01.DBO.SORELSAFTER UPDATE,INSERTAS SET NOCOUNT ON INSERT SOMODIFICATIONS.DBO.SOMODTEST (FENUMBER, FSONO, FRELEASE, FDATECHANGED, FORDERQTYOLD, FORDERQTYNEW, FUNETPRICEOLD, FUNETPRICENEW, PRICEMOD, MODTYPE) SELECT I.FENUMBER, I.FSONO, I.FRELEASE, GETDATE(), D.FORDERQTY, I.FORDERQTY, D.FUNETPRICE, I.FUNETPRICE, (I.FNETPRICE - D.FNETPRICE) AS PRICEMOD, 'C' FROM INSERTED I INNER JOIN DELETED D ON I.IDENTITY_COLUMN = D.IDENTITY_COLUMN WHERE I.FNETPRICE <> D.FNETPRICE OR I.FORDERQTY <> D.FORDERQTY GO This does a good job for updates. However, I also need this to work for Inserts and Deletes. I know this can be done on 1 trigger, but I'm having trouble understanding how. Ideally for an insert you would insert something in the new table like: 002, 281345, 000, Date, NULL, 50.00000, NULL, 123.00000, 6150.00000, 'N' And a Delete would look like this: 002, 281345, 000, Date, 50.00000, NULL, 123.00000, NULL, -6150.00000, 'D'A nudge in the right direction would be wonderful. |
|
|
jrussell
Starting Member
1 Post |
Posted - 2008-08-06 : 17:47:16
|
Try this in your trigger ...IF EXISTS(SELECT * FROM inserted) AND EXISTS(SELECT * FROM deleted)-- Code for UPDATEELSE IF EXISTS(SELECT * FROM inserted) -- Code for INSERT ELSE -- Code for DELETE |
|
|
jezemine
Master Smack Fu Yak Hacker
2886 Posts |
Posted - 2008-08-06 : 19:22:13
|
that trigger is hardly blowing up. what you need to do is write a CLR trigger and call Environment.Exit() from it! elsasoft.org |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-08-07 : 02:19:54
|
[code]CREATE TRIGGER SOMODAUDITON M2MDATA01.DBO.SORELSAFTER UPDATE,INSERT,DELETEAS SET NOCOUNT ON INSERT SOMODIFICATIONS.DBO.SOMODTEST (FENUMBER, FSONO, FRELEASE, FDATECHANGED, FORDERQTYOLD, FORDERQTYNEW, FUNETPRICEOLD, FUNETPRICENEW, PRICEMOD, MODTYPE) SELECT COALESCE(I.FENUMBER,D.FENUMBER), COALESCE(I.FSONO,D.FSONO), COALESCE(I.FRELEASE,D.FRELEASE), GETDATE(), D.FORDERQTY, I.FORDERQTY, D.FUNETPRICE, I.FUNETPRICE, (COALESCE(I.FNETPRICE,0) - COALESCE(D.FNETPRICE,0)) AS PRICEMOD, CASE WHEN I.IDENTITY_COLUMN IS NOT NULL AND D.IDENTITY_COLUMN IS NULL THEN 'N' WHEN I.IDENTITY_COLUMN IS NULL AND D.IDENTITY_COLUMN IS NOT NULL THEN 'D' ELSE 'C' END FROM INSERTED I LEFT JOIN DELETED D ON I.IDENTITY_COLUMN = D.IDENTITY_COLUMN WHERE I.FNETPRICE <> D.FNETPRICE OR I.FORDERQTY <> D.FORDERQTY GO[/code] |
|
|
DavidChel
Constraint Violating Yak Guru
474 Posts |
Posted - 2008-08-07 : 09:58:38
|
quote: Originally posted by jrussell Try this in your trigger ...IF EXISTS(SELECT * FROM inserted) AND EXISTS(SELECT * FROM deleted)-- Code for UPDATEELSE IF EXISTS(SELECT * FROM inserted) -- Code for INSERT ELSE -- Code for DELETE
Thanks for the advice jrussell, before I saw this, I actually did something just like that. CREATE TRIGGER SOMODAUDITON M2MDATA01.DBO.SORELSAFTER UPDATE,INSERT, DELETEAS SET NOCOUNT ONif exists(select * from inserted) and exists(select * from deleted) -- UpdateBegin INSERT SOMODIFICATIONS.DBO.SOMODTEST (FENUMBER, FSONO, FRELEASE, FDATECHANGED, FORDERQTYOLD, FORDERQTYNEW, FUNETPRICEOLD, FUNETPRICENEW, PRICEMOD, MODTYPE) SELECT I.FENUMBER, I.FSONO, I.FRELEASE, GETDATE(), D.FORDERQTY, I.FORDERQTY, D.FUNETPRICE, I.FUNETPRICE, (I.FNETPRICE - D.FNETPRICE) AS PRICEMOD, 'C' FROM INSERTED I INNER JOIN DELETED D ON I.IDENTITY_COLUMN = D.IDENTITY_COLUMN WHERE I.FNETPRICE <> D.FNETPRICE OR I.FORDERQTY <> D.FORDERQTY ReturnEnd if not exists(select * from inserted) and exists(select * from deleted) -- Delete Begin INSERT SOMODIFICATIONS.DBO.SOMODTEST (FENUMBER, FSONO, FRELEASE, FDATECHANGED, FORDERQTYOLD, FUNETPRICEOLD, PRICEMOD, MODTYPE) SELECT D.FENUMBER, D.FSONO, D.FRELEASE, GETDATE(), D.FORDERQTY, D.FUNETPRICE, (0 - D.FNETPRICE) AS PRICEMOD, 'D' FROM DELETED D Return Endif exists(select * from inserted) and not exists(select * from deleted) -- InsertBegin INSERT SOMODIFICATIONS.DBO.SOMODTEST (FENUMBER, FSONO, FRELEASE, FDATECHANGED, FORDERQTYNEW, FUNETPRICENEW, PRICEMOD, MODTYPE) SELECT I.FENUMBER, I.FSONO, I.FRELEASE, GETDATE(), I.FORDERQTY, I.FUNETPRICE, (I.FNETPRICE) AS PRICEMOD, 'N' FROM INSERTED I Return END GO |
|
|
DavidChel
Constraint Violating Yak Guru
474 Posts |
Posted - 2008-08-07 : 10:00:29
|
Thanks again Visakh. I was kind of proud of what I came up with, and then I see your response and got just another small reminder of how little I know about this stuff. |
|
|
DavidChel
Constraint Violating Yak Guru
474 Posts |
Posted - 2008-08-07 : 14:50:51
|
quote: Originally posted by visakh16
CREATE TRIGGER SOMODAUDITON M2MDATA01.DBO.SORELSAFTER UPDATE,INSERT,DELETEAS SET NOCOUNT ON INSERT SOMODIFICATIONS.DBO.SOMODTEST (FENUMBER, FSONO, FRELEASE, FDATECHANGED, FORDERQTYOLD, FORDERQTYNEW, FUNETPRICEOLD, FUNETPRICENEW, PRICEMOD, MODTYPE) SELECT COALESCE(I.FENUMBER,D.FENUMBER), COALESCE(I.FSONO,D.FSONO), COALESCE(I.FRELEASE,D.FRELEASE), GETDATE(), D.FORDERQTY, I.FORDERQTY, D.FUNETPRICE, I.FUNETPRICE, (COALESCE(I.FNETPRICE,0) - COALESCE(D.FNETPRICE,0)) AS PRICEMOD, CASE WHEN I.IDENTITY_COLUMN IS NOT NULL AND D.IDENTITY_COLUMN IS NULL THEN 'N' WHEN I.IDENTITY_COLUMN IS NULL AND D.IDENTITY_COLUMN IS NOT NULL THEN 'D' ELSE 'C' END FROM INSERTED I LEFT JOIN DELETED D ON I.IDENTITY_COLUMN = D.IDENTITY_COLUMN WHERE I.FNETPRICE <> D.FNETPRICE OR I.FORDERQTY <> D.FORDERQTY GO
I appreciate your help as always Visahk, but that doesn't work. I don't think it will capture the deletes because of the left join. My verbose 3 tiered statement works. Can I implement a trigger while people are actively using the database? If I want to remove it, can I do it with people in? |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-08-07 : 14:52:31
|
quote: Originally posted by DavidChel
quote: Originally posted by visakh16
CREATE TRIGGER SOMODAUDITON M2MDATA01.DBO.SORELSAFTER UPDATE,INSERT,DELETEAS SET NOCOUNT ON INSERT SOMODIFICATIONS.DBO.SOMODTEST (FENUMBER, FSONO, FRELEASE, FDATECHANGED, FORDERQTYOLD, FORDERQTYNEW, FUNETPRICEOLD, FUNETPRICENEW, PRICEMOD, MODTYPE) SELECT COALESCE(I.FENUMBER,D.FENUMBER), COALESCE(I.FSONO,D.FSONO), COALESCE(I.FRELEASE,D.FRELEASE), GETDATE(), D.FORDERQTY, I.FORDERQTY, D.FUNETPRICE, I.FUNETPRICE, (COALESCE(I.FNETPRICE,0) - COALESCE(D.FNETPRICE,0)) AS PRICEMOD, CASE WHEN I.IDENTITY_COLUMN IS NOT NULL AND D.IDENTITY_COLUMN IS NULL THEN 'N' WHEN I.IDENTITY_COLUMN IS NULL AND D.IDENTITY_COLUMN IS NOT NULL THEN 'D' ELSE 'C' END FROM INSERTED I FULL OUTER JOIN DELETED D ON I.IDENTITY_COLUMN = D.IDENTITY_COLUMN WHERE I.FNETPRICE <> D.FNETPRICE OR I.FORDERQTY <> D.FORDERQTY GO
I appreciate your help as always Visahk, but that doesn't work. I don't think it will capture the deletes because of the left join. My verbose 3 tiered statement works. Can I implement a trigger while people are actively using the database? If I want to remove it, can I do it with people in?
ah....make it full outer |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-08-07 : 14:54:12
|
Yup...you can create a trigger but this will surely have a serious impact on your system performance especially with lots of users interacting. |
|
|
DavidChel
Constraint Violating Yak Guru
474 Posts |
Posted - 2008-08-07 : 14:55:22
|
I doubt it would be a problem here. But my second question stands, can I remove it without exclusive access to the database if I need it? |
|
|
DavidChel
Constraint Violating Yak Guru
474 Posts |
Posted - 2008-08-11 : 08:42:51
|
quote: Originally posted by DavidChel I doubt it would be a problem here. But my second question stands, can I remove it without exclusive access to the database if I need it?
Anybody? |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-08-11 : 10:21:26
|
quote: Originally posted by DavidChel I doubt it would be a problem here. But my second question stands, can I remove it without exclusive access to the database if I need it?
remove the trigger you mean? for that you need the alter table permission on table on which trigger is created. |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-08-11 : 10:53:48
|
[code]CREATE TRIGGER SOMODAUDITON M2MDATA01.DBO.SORELSAFTER UPDATE, INSERT, DELETEASSET NOCOUNT ONDECLARE @Action CHAR(1)IF EXISTS (SELECT * FROM inserted) IF EXISTS (SELECT * FROM deleted) SET @Action = 'U' -- Update ELSE SET @Action = 'I' -- InsertELSE SET @Action = 'D' -- Delete INSERT SOMODIFICATIONS.DBO.SOMODTEST ( FENUMBER, FSONO, FRELEASE, FDATECHANGED, FORDERQTYOLD, FORDERQTYNEW, FUNETPRICEOLD, FUNETPRICENEW, PRICEMOD, MODTYPE )SELECT i.FENUMBER, i.FSONO, i.FRELEASE, GETDATE(), d.FORDERQTY, i.FORDERQTY, d.FUNETPRICE, i.FUNETPRICE, (i.FNETPRICE - d.FNETPRICE), @ActionFROM inserted AS iFULL JOIN deleted AS d ON d.IDENTITY_COLUMN = i.IDENTITY_COLUMN[/code] E 12°55'05.25"N 56°04'39.16" |
|
|
DavidChel
Constraint Violating Yak Guru
474 Posts |
Posted - 2008-08-11 : 11:30:08
|
quote: Originally posted by visakh16
quote: Originally posted by DavidChel I doubt it would be a problem here. But my second question stands, can I remove it without exclusive access to the database if I need it?
remove the trigger you mean? for that you need the alter table permission on table on which trigger is created.
I have full permissions. If I decided that the trigger wasn't working out or was having a deleterious effect on performance, could I remove it while users were still actively using the database? |
|
|
DavidChel
Constraint Violating Yak Guru
474 Posts |
Posted - 2008-08-11 : 14:39:14
|
While I greatly appreciate everyone's help, this is the only one that seems to work (which was from a few days ago): CREATE TRIGGER SOMODAUDITON M2MDATA01.DBO.SORELSAFTER UPDATE,INSERT, DELETEAS SET NOCOUNT ONif exists(select * from inserted) and exists(select * from deleted) -- UpdateBegin INSERT SOMODIFICATIONS.DBO.SOMODTEST (FENUMBER, FSONO, FRELEASE, FDATECHANGED, FORDERQTYOLD, FORDERQTYNEW, FUNETPRICEOLD, FUNETPRICENEW, FDISCPCTOLD, FDISCPCTNEW, PRICEMOD, MODTYPE) SELECT I.FENUMBER, I.FSONO, I.FRELEASE, GETDATE(), D.FORDERQTY, I.FORDERQTY, D.FUNETPRICE, I.FUNETPRICE, D.FDISCPCT, I.FDISCPCT, (I.FNETPRICE - D.FNETPRICE) AS PRICEMOD, 'C' FROM INSERTED I INNER JOIN DELETED D ON I.IDENTITY_COLUMN = D.IDENTITY_COLUMN WHERE I.FNETPRICE <> D.FNETPRICE OR I.FORDERQTY <> D.FORDERQTY ReturnEnd if not exists(select * from inserted) and exists(select * from deleted) -- Delete Begin INSERT SOMODIFICATIONS.DBO.SOMODTEST (FENUMBER, FSONO, FRELEASE, FDATECHANGED, FORDERQTYOLD, FUNETPRICEOLD, PRICEMOD, MODTYPE) SELECT D.FENUMBER, D.FSONO, D.FRELEASE, GETDATE(), D.FORDERQTY, D.FUNETPRICE, (0 - D.FNETPRICE) AS PRICEMOD, 'D' FROM DELETED D Return Endif exists(select * from inserted) and not exists(select * from deleted) -- InsertBegin INSERT SOMODIFICATIONS.DBO.SOMODTEST (FENUMBER, FSONO, FRELEASE, FDATECHANGED, FORDERQTYNEW, FUNETPRICENEW, PRICEMOD, MODTYPE) SELECT I.FENUMBER, I.FSONO, I.FRELEASE, GETDATE(), I.FORDERQTY, I.FUNETPRICE, (I.FNETPRICE) AS PRICEMOD, 'N' FROM INSERTED I Return END GO The bolded code needs to be considered because this table gets updated frequently and I only want this to perform if there is a difference in quantity or price. If I use the following: CREATE TRIGGER SOMODAUDITON M2MDATA01.DBO.SORELSAFTER UPDATE, INSERT, DELETEASSET NOCOUNT ONDECLARE @Action CHAR(1)IF EXISTS (SELECT * FROM inserted) IF EXISTS (SELECT * FROM deleted) SET @Action = 'U' -- Update ELSE SET @Action = 'I' -- InsertELSE SET @Action = 'D' -- Delete INSERT SOMODIFICATIONS.DBO.SOMODTEST ( FENUMBER, FSONO, FRELEASE, FDATECHANGED, FORDERQTYOLD, FORDERQTYNEW, FUNETPRICEOLD, FUNETPRICENEW, PRICEMOD, MODTYPE )SELECT i.FENUMBER, i.FSONO, i.FRELEASE, GETDATE(), d.FORDERQTY, i.FORDERQTY, d.FUNETPRICE, i.FUNETPRICE, (i.FNETPRICE - d.FNETPRICE), @ActionFROM inserted AS iFULL JOIN deleted AS d ON d.IDENTITY_COLUMN = i.IDENTITY_COLUMNWHERE I.FNETPRICE <> D.FNETPRICE OR I.FORDERQTY <> D.FORDERQTY I don't get the inserts or deletes. I suspect it is because of the WHERE clause and the null values. Is there anything I can do to keep the more elegant SQL Trigger but get my functionality at the same time? |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-08-11 : 14:44:59
|
Change like this and try:-CREATE TRIGGER SOMODAUDITON M2MDATA01.DBO.SORELSAFTER UPDATE, INSERT, DELETEASSET NOCOUNT ONDECLARE @Action CHAR(1)IF EXISTS (SELECT * FROM inserted) IF EXISTS (SELECT * FROM deleted) SET @Action = 'U' -- Update ELSE SET @Action = 'I' -- InsertELSE SET @Action = 'D' -- Delete INSERT SOMODIFICATIONS.DBO.SOMODTEST ( FENUMBER, FSONO, FRELEASE, FDATECHANGED, FORDERQTYOLD, FORDERQTYNEW, FUNETPRICEOLD, FUNETPRICENEW, PRICEMOD, MODTYPE )SELECT i.FENUMBER, i.FSONO, i.FRELEASE, GETDATE(), d.FORDERQTY, i.FORDERQTY, d.FUNETPRICE, i.FUNETPRICE, (i.FNETPRICE - d.FNETPRICE), @ActionFROM inserted AS iFULL JOIN deleted AS d ON d.IDENTITY_COLUMN = i.IDENTITY_COLUMNAND (I.FNETPRICE <> D.FNETPRICE OR I.FORDERQTY <> D.FORDERQTY) |
|
|
Next Page
|
|
|