Author |
Topic |
Iain
Starting Member
5 Posts |
Posted - 2007-08-01 : 20:30:28
|
I have a stored procedure that basically increments a counter by one and returns the incremented number, occasionaly the sp returns the same value twice in a row, in an attempt to debug this i have run the profiler on this sp to see if i can see anything amiss i also changed the sp to return the value before the update was run to see if the update was failing but that seems to be ok the sp is:CREATE PROCEDURE dbo.GetAcctNextPaymentXML( @key nvarchar(20), @value1 int output, @value int output, @MyError nvarchar(100) output)ASSELECT @value1 = AccValueFROM AcctKeysWHERE AccKey = @keybegin transactionUPDATE AcctKeysSET AccValue = AccValue + 1WHERE (AccKey = @Key)if @@error <> 0begin SELECT @MyError = @@errorendSELECT @value = AccValueFROM AcctKeysWHERE AccKey = @keycommit transaction Does anyone know if this is a known issue or maybe a workround? any help would be great.CheersIain |
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2007-08-01 : 20:33:16
|
Why aren't you just using the reliable Identity option?In order to get yours to work, you'd need to put a lock on the AcctKeys table to ensure no other process is accessing the same data.Tara Kizerhttp://weblogs.sqlteam.com/tarad/ |
 |
|
Iain
Starting Member
5 Posts |
Posted - 2007-08-02 : 04:12:31
|
TaraThank you for your help but what is the reliable identity option, also with the locking doesn't putting it all in a transaction lock the table anyway?CheersIain quote: Originally posted by tkizer Why aren't you just using the reliable Identity option?In order to get yours to work, you'd need to put a lock on the AcctKeys table to ensure no other process is accessing the same data.Tara Kizerhttp://weblogs.sqlteam.com/tarad/
|
 |
|
Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)
7020 Posts |
Posted - 2007-08-02 : 14:07:15
|
If you use an IDENTITY column in your table, it will increment automatically when you insert a new row. It is more efficient, scalable, and dependable than your solution, so it is almost always a better way to do this.You should read about IDENTITY in SQL Server Books Online.CODO ERGO SUM |
 |
|
Iain
Starting Member
5 Posts |
Posted - 2007-08-02 : 20:03:34
|
Michael, thank you for your response, I am not actually adding rows to this table so i can't see how an identity column would help. What this table is doing is recording the latest number for a series of xml files where the next xml file that is created must have the next number in the series for a file name so all the sp does is look at what the last numbered xml was and add 1 and return that value. These xml files must be numbered in this manner for the requirements of some 3rd party software that i have no control over. The problem that i have described above is only happening in maybe 1 time in 100.CheersIainquote: Originally posted by Michael Valentine Jones If you use an IDENTITY column in your table, it will increment automatically when you insert a new row. It is more efficient, scalable, and dependable than your solution, so it is almost always a better way to do this.You should read about IDENTITY in SQL Server Books Online.CODO ERGO SUM
|
 |
|
Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)
7020 Posts |
Posted - 2007-08-02 : 23:53:27
|
You can try thisCREATE PROCEDURE dbo.GetAcctNextPaymentXML( @key nvarchar(20), @value1 int output, @value int output, @MyError nvarchar(100) output)ASdeclare @error int, @rowcount int, @New_value intUPDATE AcctKeysSET @New_value = AccValue = AccValue + 1WHERE AccKey = @Keyselect @error = @@error, @rowcount = @@rowcountif @error <> 0 begin set @MyError = @error endelse if @rowcount = 1 and @New_value is not null begin set @value = @New_value set @value1 = @value-1 end else begin set @MyError = -9999 end CODO ERGO SUM |
 |
|
Iain
Starting Member
5 Posts |
Posted - 2007-08-03 : 11:52:32
|
MichaelThanks, but it seems like the only difference in how you have changed the sp, is in what happens when @@error is anything else but 0, what i failed to mention earlier is that @@error is not throwing anything but 0 so the else part of your if statement will never get hit. Please correct if i have mis-understood.CheersIain |
 |
|
Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)
7020 Posts |
Posted - 2007-08-03 : 14:20:28
|
quote: Originally posted by Iain MichaelThanks, but it seems like the only difference in how you have changed the sp, is in what happens when @@error is anything else but 0, what i failed to mention earlier is that @@error is not throwing anything but 0 so the else part of your if statement will never get hit. Please correct if i have mis-understood.CheersIain
It seems like you didn't really look at the code I posted.CODO ERGO SUM |
 |
|
Iain
Starting Member
5 Posts |
Posted - 2007-08-03 : 20:39:17
|
My appologies, i did indeed mis-read the code you posted but i don't see how the changes would help for the following reason: my code follows this logic, retrieve the AccValue before doing the update and return it, update the AccValue, retrieve the AccValue again and return it. Your logic: Update the AccValue, if there was no error when updating and 1 row did get updated then return the value that the AccValue was updated to. Now, in my original logic the @value being returned after the update is always what would be expected to be returned (1 more than it was before the update) and comes from requerying the table after the update. whereas in your logic the @value being returned is taken from what is updating the table and the @value1 is calculated from the @value (as a note the only reason for @value1 is to see what is already in the table before the update while i am testing to find out where my problem lies). When the problem happens in my logic; the @value1 returned before the AccValue is updated is the same as before the AccValue was updated the previous time. Sorry if I'm making this sound complicated it is the middle of the night here.CheersIain |
 |
|
|