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 |
|
chillbeast
Starting Member
5 Posts |
Posted - 2010-02-05 : 19:11:06
|
No matter what I do, I can't get this trigger to fire without failing. I've tested all my SQL statements separately and they all are valid. Seems like it is doing the auto-rollback thing whenever the trigger fires though. Any help is appreciated.Here is my trigger:USE [MyDatabaseName]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER TRIGGER [dbo].[customer_trigger_INSERT]ON [dbo].[Customer]AFTER INSERTASIF EXISTS (SELECT * FROM EmailContacts WHERE Email=(SELECT Email FROM inserted)) BEGIN UPDATE EmailContacts SET Name = (SELECT FirstName + ' ' + LastName FROM inserted) WHERE Email = (SELECT Email FROM inserted) ENDELSE BEGIN INSERT INTO EmailContacts (Email, Name) SELECT FirstName + ' ' + LastName, Email FROM inserted END; It's supposed to update the EmailContacts table with the customers name and email and insert if they don't exist over there yet.Thanks in advance!-josh |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
|
|
Kristen
Test
22859 Posts |
Posted - 2010-02-06 : 02:10:29
|
I think there is a risk that some rows, but not all, might exist in EmailContacts, so I would go for a variation on Tara's suggestion:UPDATE eSET Name = i.FirstName + ' ' + i.LastNameFROM EmailContacts e JOIN inserted i ON e.Email = i.EmailWHERE Name <> i.FirstName + ' ' + i.LastNameINSERT INTO EmailContacts (Email, Name)SELECT Email, FirstName + ' ' + LastNameFROM inserted AS IWHERE NOT EXISTS( SELECT * FROM EmailContacts AS E WHERE E.Email = I.Email) Note also that you appear to have got your columns the wrong way round on your INSERT (may just have been cut & paste error to make your post here though)Edit: Added an optimisation to UPDATE to not update where there is no change. |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2010-02-06 : 02:12:11
|
P.S. Is it ever possible for either FirstName or LastName to be NULL? If so you need to concatenate them using:NullIf(RTrim(COALESCE(FirstName + ' ', '') + COALESCE(LastName, '')), '') |
 |
|
|
chillbeast
Starting Member
5 Posts |
Posted - 2010-02-08 : 12:00:15
|
thanks for the assistance Tara & Kristen, Here is what I have now:ALTER TRIGGER [dbo].[customer_trigger_INSERT]ON [dbo].[Customer]FOR INSERTASUPDATE eSET Name = i.FirstName + ' ' + i.LastNameFROM EmailContacts e JOIN inserted i ON e.Email = i.EmailWHERE Name <> i.FirstName + ' ' + i.LastNameINSERT INTO EmailContacts (Email, Name)SELECT Email, FirstName + ' ' + LastNameFROM inserted AS IWHERE NOT EXISTS( SELECT * FROM EmailContacts AS E WHERE E.Email = I.Email) It's still rolling back the entire INSERT. Could it be related to the fact that this gets triggered by a Stored Procedure? Unfortunately I am unable to modify the stored proc which would be much easier to accomplish this.Any other ideas/thoughts are greatly appreciated.-Josh |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2010-02-08 : 12:08:41
|
"Could it be related to the fact that this gets triggered by a Stored Procedure?"Only if the SProc (or some outer process) does a ROLLBACK. But then the changes would not be stored in your Customer table either.Are you saying that if you drop this trigger you can use the Sproc to change a Customer record, but if you Create this trigger then you can NOT change a Customer Record with the Sproc (i.e. it rolls back)?What happens if you do something like:BEGIN TRANSACTIONINSERT INTO dbo.Customer(FirstName, LastName, Email)VALUES('Kristen', 'Netsirk', 'kristen@example.com')SELECT TOP 10 * FROM dbo.Customer WHERE Email = 'kristen@example.com'SELECT TOP 10 * FROM dbo. EmailContacts WHERE Email = 'kristen@example.com'ROLLBACKthis won't actually generate a row insert (because of the ROLLBACK), so you will either get an error (which will hopefully shed more light on the problem), or you will see something from the two SELECT statements (in which case the trigger is working fine, and there is indeed some issue with the SProc not liking your trigger)Another possibility is that you need more columns in the INSERT statement (e.g. for any columns that are NOT NULL) - in which case add more columns and some suitable data |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2010-02-08 : 12:08:48
|
what about this?ALTER TRIGGER [dbo].[customer_trigger_INSERT]ON [dbo].[Customer]FOR INSERTASBEGINUPDATE eSET Name = i.FirstName + ' ' + i.LastNameFROM EmailContacts e JOIN inserted i ON e.Email = i.EmailWHERE Name <> i.FirstName + ' ' + i.LastNameINSERT INTO EmailContacts (Email, Name)SELECT I.Email, I.FirstName + ' ' + I.LastNameFROM inserted AS ILEFT JOIN EmailContacts AS E ON E.Email = I.EmailWHERE E.Email IS NULLEND |
 |
|
|
chillbeast
Starting Member
5 Posts |
Posted - 2010-02-08 : 12:33:24
|
quote: Originally posted by Kristen "Could it be related to the fact that this gets triggered by a Stored Procedure?"Only if the SProc (or some outer process) does a ROLLBACK. But then the changes would not be stored in your Customer table either.Are you saying that if you drop this trigger you can use the Sproc to change a Customer record, but if you Create this trigger then you can NOT change a Customer Record with the Sproc (i.e. it rolls back)?What happens if you do something like:BEGIN TRANSACTIONINSERT INTO dbo.Customer(FirstName, LastName, Email)VALUES('Kristen', 'Netsirk', 'kristen@example.com')SELECT TOP 10 * FROM dbo.Customer WHERE Email = 'kristen@example.com'SELECT TOP 10 * FROM dbo. EmailContacts WHERE Email = 'kristen@example.com'ROLLBACKthis won't actually generate a row insert (because of the ROLLBACK), so you will either get an error (which will hopefully shed more light on the problem), or you will see something from the two SELECT statements (in which case the trigger is working fine, and there is indeed some issue with the SProc not liking your trigger)
I believe this is the case as I did see results from the trigger when I used your SQL statements above to test. I also noticed that the ID field which is autoincrementing is up to 563 when the next lowest in the DB is 501, so all these tests I've been doing have been triggering properly, something else is causing it to mess up. Now I'm at a loss of what to do next as I cannot make any changes to the stored procedure. Unfortunately I might have to add code to every web form that can possibly modify the customer table to reflect those changes on the emailcontacts table.Thanks again for your help, especially Kristen. Hopefully I can get something working :)-Josh |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2010-02-08 : 12:36:37
|
| is there a chance of any other triggers(instead of ) existing on tables EmailContacts or Customer which might be doing something against save action? |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2010-02-08 : 12:40:51
|
| Well I'll be blowed. Can't imagine what the Sproc could possibly be doing that could trip up on this. But there is always something to catch us out of course ...Right ...You could look at the SProc:sp_HelpText TheCannotBeChangedSProcNameand see if you can see any code that is rolling back the transaction and if so under what circumstances it does it.One possibility is that it is getting the IDENTITY number using @@IDENTITY (which is now old hat, and outdated - it should be using SCOPE_IDENTITY() ), and that may be getting the IDENTITY from your insert into EmailContacts (assuming that has an IDENTITY column), then doing a Lookup and, not unreasonably, NOT finding the new record.Does this have to be real time? Could you run a batch once an hour, or so, that freshened up EmailContacts where it was different to Customer table? |
 |
|
|
chillbeast
Starting Member
5 Posts |
Posted - 2010-02-08 : 12:42:05
|
| This is actually the only trigger for the entire DB. It's a shopping cart system we use and everything is in stored procs. I think I may actually be able to go ahead and change the stored proc to update both tables so I may end up just going that route. |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2010-02-08 : 12:46:58
|
| I think it needs some investigation of what the Sproc is doing, because this trigger is about as benign as it is possible to be! |
 |
|
|
chillbeast
Starting Member
5 Posts |
Posted - 2010-02-08 : 13:10:50
|
The Sproc looks pretty straightforward, not really sure what would be causing a problem:ALTER proc [dbo].[aspdnsf_insCustomer] @Email nvarchar(100), @Password nvarchar(100), @SkinID int, @AffiliateID int, @Referrer ntext, @IsAdmin tinyint, @LastIPAddress varchar(40), @LocaleSetting nvarchar(10), @Over13Checked tinyint, @CurrencySetting nvarchar(10), @VATSetting int, @VATRegistrationID nvarchar(100), @CustomerLevelID int, @CustomerID int OUTPUT ASSET NOCOUNT ON insert dbo.Customer(CustomerGUID, CustomerLevelID, RegisterDate, Email, Password, DateOfBirth, Gender, FirstName, LastName, Notes, SkinID, Phone, AffiliateID, Referrer, CouponCode, OkToEmail, IsAdmin, BillingEqualsShipping, LastIPAddress, OrderNotes, SubscriptionExpiresOn, RTShipRequest, RTShipResponse, OrderOptions, LocaleSetting, MicroPayBalance, RecurringShippingMethodID, RecurringShippingMethod, BillingAddressID, ShippingAddressID, GiftRegistryGUID, GiftRegistryIsAnonymous, GiftRegistryAllowSearchByOthers, GiftRegistryNickName, GiftRegistryHideShippingAddresses, CODCompanyCheckAllowed, CODNet30Allowed, ExtensionData, FinalizationData, Deleted, CreatedOn, Over13Checked, CurrencySetting, VATSetting, VATRegistrationID, StoreCCInDB, IsRegistered, LockedUntil, AdminCanViewCC, PwdChanged, BadLoginCount, LastBadLogin, Active, PwdChangeRequired, SaltKey)values( newid(), @CustomerLevelID, getdate(), isnull(@Email, ''), isnull(@Password, ''), null, null, null, null, null, isnull(@SkinID, 1), null, @AffiliateID, @Referrer, null, 1, isnull(@IsAdmin, 0), 0, @LastIPAddress, null, null, null, null, null, isnull(@LocaleSetting, ('en-US')), 0.0, 1, null, null, null, newid(), 1, 1, null, 1, 0, 0, null, null, 0, getdate(), @Over13Checked, @CurrencySetting, @VATSetting, @VATRegistrationID, 1, 0, null, 1, getdate(), 0, null, 1, 0, 0) set @CustomerID = @@identity |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2010-02-08 : 13:26:18
|
"set @CustomerID = @@identity"is the problem Should beset @CustomerID = SCOPE_IDENTITY( ) either the Sproc is very old, or the people that wrote it are not up-to-speed with the more subtle nuances of SQL Server |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2010-02-08 : 13:31:40
|
I'm not sure why that would cause a rollback, but probably something in the APP itself.It is possible to work around this (i.e. FAKE the @@IDENTITY back to this Sproc, but that's a bit of a PITA if you can find another solution).And another thing whilst I'm on my soap box all the:isnull(@SomeParameter, '')is really stupid IMHO.NULL is a value specifically provided to indicate "unknown".ISNULL() is converting NULL values to "blank".If you store Blank, instead of NULL, you then have no way of differentiating between someone who was asked the question, and answered with a blank string, and another scenario where the user was never asked the question (which would legitimately be NULL).Smells of "We don't know where we are getting NULLs from, so lets just stop them hitting the database" |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2010-02-08 : 13:38:33
|
| Right! I'm really "off on one" now!" @Email nvarchar(100), Not long enough for Emails @Password nvarchar(100), Who actually uses 100 character passwords? @Referrer ntext, Is this a free text field, or just a web referrer (in which case the length is finite, not infinite) @LastIPAddress varchar(40), 40 character IP address? Current IP address is 15, IP6 is 23, allow for pan-galactic perhaps? @Over13Checked tinyint, Could be BIT ? @CurrencySetting nvarchar(10), Country code? 10 characters? UNICODE? @VATRegistrationID nvarchar(100), Well VAT has to be UK right? No way do we have 100 characters ..." |
 |
|
|
|
|
|
|
|