| Author |
Topic |
|
p.shaw3@ukonline.co.uk
Posting Yak Master
103 Posts |
Posted - 2006-02-10 : 17:20:20
|
| I am trying to run the following SP in Query Analyser:-CREATE PROCEDURE [dbo].[usp_InsertUser]--CUSTOMER TABLE@Title Varchar(7), @Account_name Varchar(50), @Account_Contact Varchar(50), @FirstName Varchar(30), @MiddleName Varchar(30),@Surname Varchar(30), @ProfileType Varchar (10), @EntryDate datetime, @AddressName_No Varchar(30), @Address_Road varchar(30),@Address_1 Varchar(30), @Address_2 Varchar(30), @Address_County Varchar(30), @Address_Postcode Varchar(10), @Address_Country Char(10), @Telephone1 Varchar(14), @Telephone2 varchar(14), @fax Varchar(14), @Email Varchar(50), @CompanyName Varchar(40), @CompanyAddress Varchar(200),@Spec_Requirements Varchar(100), @Message Varchar(200), @WebEnabled Char(1), @Enabled Char(1), @CreatedBy Varchar(30), @CardAbbr Varchar(15),--LOGIN TABLE@CustomerId int, @Cust_Username Varchar(40), @Cust_Password Varchar(30), @Cust_Postcode Varchar(10),--CC TABLE@CCName Varchar(30), @EncNo Varchar(100), @CCType Varchar(20), @CCExpMon Char(2), @CCExpYear Char(2), @Valuer Varchar(25),--OUTPUT VARIABLES@Duplicate Varchar(30) OUTPUTASIf (Select @@ROWCOUNT as 'Rows Affected' from FyldeDB.dbo.Customer_Loginwhere Cust_Username = @Cust_Username AND Cust_Password = @Cust_Password AND Cust_Postcode = @Cust_Postcode) <> 0BEGIN --User exists in DB, send message to page and exit SET @Duplicate = 'USER EXISTS' RETURN ENDELSEBEGIN--User Doesn't Exist - DO THE INSERT TO CUSTOMERSBEGIN TRANSACTION TR_UpdateINSERT INTO FyldeDB.dbo.Customer_Details (Title, Account_Name, Account_Contact, FirstName, MiddleName, Surname, ProfileType, EntryDate, AddressName_No, Address_Road, Address_1, Address_2, Address_County, Address_Postcode, Address_Country, Telephone1, Telephone2, Fax, Email, CompanyName, CompanyAddress, Spec_Requirements,Message, WebEnabled, Enabled, CreatedBy, CardAbbr) Values (@Title, @Account_name, @Account_Contact, @FirstName, @MiddleName, @Surname, @ProfileType, @EntryDate, @AddressName_No, @Address_Road, @Address_1, @Address_2, @Address_County, @Address_Postcode, @Address_Country, @Telephone1, @Telephone2, @fax, @Email, @CompanyName, @CompanyAddress, @Spec_Requirements, @Message, @WebEnabled, @Enabled, @CreatedBy, @CardAbbr) SELECT @@IDENTITY RETURN @@IDENTITY--DO THE INSERT TO CUSTOMER LOGININSERT INTO FyldeDB.dbo.Customer_Login (Cust_Username, Cust_Password, CustomerId, Cust_Postcode) Values (@Cust_Username, @Cust_Password, @@IDENTITY, @Cust_Postcode)--DO THE INSERT TO CCSINSERT INTO FyldeDB.dbo.CCS (CCName, EncNo, CCType, CCExpMon, CCExpYear, Valuer, CustomerId) Values (@CCName, @EncNo, @CCType, @CCExpMon, @CCExpYear, @Valuer, @@IDENTITY)If @@ERROR <> 0 BEGIN ROLLBACK TRANSACTION TR_Update SET @Duplicate = 'ERROR OCCURED' RETURN ENDELSE BEGIN COMMIT TRANSACTION TR_Update SET @Duplicate = 'UPDATE COMPLETED' RETURN END ENDGOAs you hopefully can see, there are 3 inserts to different tables, each one inserting as a batch and only rolling back if an error is encountered. The problem is I keep getting the following error:-(1 row(s) affected)(1 row(s) affected)Server: Msg 266, Level 16, State 2, Procedure usp_InsertUser, Line 36Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION statement is missing. Previous count = 0, current count = 1.Stored Procedure: FyldeDB.dbo.usp_InsertUser Return Code = 10002 Output Parameter(s): @Duplicate = <NULL>Although the Return Code produces the correct ID, no rows are inserted in any of the 3 tables. Can anyone help please?Pat. |
|
|
p.shaw3@ukonline.co.uk
Posting Yak Master
103 Posts |
Posted - 2006-02-10 : 17:37:35
|
| BTW - The Customer_Login and CCS table both have a CustomerId column. These are Foriegn Keys to the Primary Key in the Customer_Details table. This is why I chose to the 3 Inserts in one batch. |
 |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2006-02-10 : 17:37:37
|
| You must test the value of @@ERROR after every INSERT, UPDATE, and DELETE. It gets reset after each. So if your first query is failing but your second and third are successful, it isn't rolling it back as @@ERROR = 0 after the third query.Tara Kizeraka tduggan |
 |
|
|
p.shaw3@ukonline.co.uk
Posting Yak Master
103 Posts |
Posted - 2006-02-10 : 17:39:10
|
| Could you please give me an example of how I should do this. Thank you. |
 |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2006-02-10 : 17:41:35
|
| After the first and second INSERT:If @@ERROR <> 0BEGINROLLBACK TRANSACTION TR_UpdateSET @Duplicate = 'ERROR OCCURED'RETURNENDAfter the third:If @@ERROR <> 0BEGINROLLBACK TRANSACTION TR_UpdateSET @Duplicate = 'ERROR OCCURED'RETURNENDELSEBEGINCOMMIT TRANSACTION TR_UpdateSET @Duplicate = 'UPDATE COMPLETED'RETURNENDSome people use GOTOs and labels to avoid this repeated code. You can check this out in SQL Server Books Online.Tara Kizeraka tduggan |
 |
|
|
p.shaw3@ukonline.co.uk
Posting Yak Master
103 Posts |
Posted - 2006-02-10 : 17:52:50
|
| Thanks very much for all your help that is very useful, but do you have any idea why the SP is failing. Can you see anything in the code that doesn't look correct? |
 |
|
|
afrika
Master Smack Fu Yak Hacker
2706 Posts |
Posted - 2006-02-10 : 18:01:19
|
quote: Originally posted by p.shaw3@ukonline.co.uk I am trying to run the following SP in Query Analyser:-CREATE PROCEDURE [dbo].[usp_InsertUser]--CUSTOMER TABLE@Title Varchar(7), @Account_name Varchar(50), @Account_Contact Varchar(50), @FirstName Varchar(30), @MiddleName Varchar(30),@Surname Varchar(30), @ProfileType Varchar (10), @EntryDate datetime, @AddressName_No Varchar(30), @Address_Road varchar(30),@Address_1 Varchar(30), @Address_2 Varchar(30), @Address_County Varchar(30), @Address_Postcode Varchar(10), @Address_Country Char(10), @Telephone1 Varchar(14), @Telephone2 varchar(14), @fax Varchar(14), @Email Varchar(50), @CompanyName Varchar(40), @CompanyAddress Varchar(200),@Spec_Requirements Varchar(100), @Message Varchar(200), @WebEnabled Char(1), @Enabled Char(1), @CreatedBy Varchar(30), @CardAbbr Varchar(15),--LOGIN TABLE@CustomerId int, @Cust_Username Varchar(40), @Cust_Password Varchar(30), @Cust_Postcode Varchar(10),--CC TABLE@CCName Varchar(30), @EncNo Varchar(100), @CCType Varchar(20), @CCExpMon Char(2), @CCExpYear Char(2), @Valuer Varchar(25),--OUTPUT VARIABLES@Duplicate Varchar(30) OUTPUTASIf (Select @@ROWCOUNT as 'Rows Affected' from FyldeDB.dbo.Customer_Loginwhere Cust_Username = @Cust_Username AND Cust_Password = @Cust_Password AND Cust_Postcode = @Cust_Postcode) <> 0BEGIN --User exists in DB, send message to page and exit SET @Duplicate = 'USER EXISTS' RETURN ENDELSEBEGIN--User Doesn't Exist - DO THE INSERT TO CUSTOMERSBEGIN TRANSACTION TR_UpdateINSERT INTO FyldeDB.dbo.Customer_Details (Title, Account_Name, Account_Contact, FirstName, MiddleName, Surname, ProfileType, EntryDate, AddressName_No, Address_Road, Address_1, Address_2, Address_County, Address_Postcode, Address_Country, Telephone1, Telephone2, Fax, Email, CompanyName, CompanyAddress, Spec_Requirements,Message, WebEnabled, Enabled, CreatedBy, CardAbbr) Values (@Title, @Account_name, @Account_Contact, @FirstName, @MiddleName, @Surname, @ProfileType, @EntryDate, @AddressName_No, @Address_Road, @Address_1, @Address_2, @Address_County, @Address_Postcode, @Address_Country, @Telephone1, @Telephone2, @fax, @Email, @CompanyName, @CompanyAddress, @Spec_Requirements, @Message, @WebEnabled, @Enabled, @CreatedBy, @CardAbbr) SELECT @@IDENTITY RETURN @@IDENTITY--DO THE INSERT TO CUSTOMER LOGININSERT INTO FyldeDB.dbo.Customer_Login (Cust_Username, Cust_Password, CustomerId, Cust_Postcode) Values (@Cust_Username, @Cust_Password, @@IDENTITY, @Cust_Postcode)--DO THE INSERT TO CCSINSERT INTO FyldeDB.dbo.CCS (CCName, EncNo, CCType, CCExpMon, CCExpYear, Valuer, CustomerId) Values (@CCName, @EncNo, @CCType, @CCExpMon, @CCExpYear, @Valuer, @@IDENTITY)If @@ERROR <> 0 BEGIN ROLLBACK TRANSACTION TR_Update SET @Duplicate = 'ERROR OCCURED' RETURN ENDELSE BEGIN COMMIT TRANSACTION TR_Update SET @Duplicate = 'UPDATE COMPLETED' RETURN END ENDGOAs you hopefully can see, there are 3 inserts to different tables, each one inserting as a batch and only rolling back if an error is encountered. The problem is I keep getting the following error:-(1 row(s) affected)(1 row(s) affected)Server: Msg 266, Level 16, State 2, Procedure usp_InsertUser, Line 36Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION statement is missing. Previous count = 0, current count = 1.Stored Procedure: FyldeDB.dbo.usp_InsertUser Return Code = 10002 Output Parameter(s): @Duplicate = <NULL>Although the Return Code produces the correct ID, no rows are inserted in any of the 3 tables. Can anyone help please?Pat.
If you ask it to return the @@identity value, it would exit the SP.Read books onlinequote: RETURNExits unconditionally from a query or procedure. RETURN is immediate and complete and can be used at any point to exit from a procedure, batch, or statement block. Statements following RETURN are not executed.
|
 |
|
|
p.shaw3@ukonline.co.uk
Posting Yak Master
103 Posts |
Posted - 2006-02-10 : 18:13:28
|
| Right I see. That's great thank you again. The problem is I need to get the value of @@IDENTITY and hold it so the 2 other inserts can access it and store the value in their CustomerId columns, that's what I was trying to do. Is there any other way I can accomplish this? |
 |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2006-02-10 : 18:18:44
|
| You need to put the value into an output variable. Don't use RETURN to output values. And use SCOPE_IDENTITY() instead of @@IDENTITY as @@IDENTITY can be wrong.DECLARE @i intSET @i = SCOPE_IDENTITY()Tara Kizeraka tduggan |
 |
|
|
p.shaw3@ukonline.co.uk
Posting Yak Master
103 Posts |
Posted - 2006-02-10 : 18:24:50
|
| Thank you all for your help. |
 |
|
|
afrika
Master Smack Fu Yak Hacker
2706 Posts |
Posted - 2006-02-12 : 02:53:20
|
SCOPE_IDENTITY() works in the scope of the transactions.Read about all three in books onlinequote: SCOPE_IDENTITY, IDENT_CURRENT, and @@IDENTITY are similar functions in that they return values inserted into IDENTITY columns. IDENT_CURRENT is not limited by scope and session; it is limited to a specified table. IDENT_CURRENT returns the value generated for a specific table in any session and any scope. For more information, see IDENT_CURRENT.SCOPE_IDENTITY and @@IDENTITY will return last identity values generated in any table in the current session. However, SCOPE_IDENTITY returns values inserted only within the current scope; @@IDENTITY is not limited to a specific scope.
|
 |
|
|
|
|
|