I am going this brutal way to handle deadlocks by re-trying 5 times (using SQL Server 2008R2) and no error handling.
I know it is not delicate, but for the scope of it, can you find any flaws?
Thank you
WHILE #retry < 5
BEGIN
BEGIN TRY
INSERT available
SELECT 'x','y','z'
BREAK
END TRY
BEGIN CATCH
IF error_number() = 1205 AND #retry < 5
BEGIN
SELECT #retry = #retry + 1
WAITFOR DELAY '00:00:00.100'
ELSE
BREAK
END
END CATCH;
END
EDIT: I have edited the code following #Charlieface helpfull suggestions.
I have never used TRY/CATCH in SQL server code though. Also THROW is not supported in SQL Server 2008R2
Any suggestions appreciated.
Related
In SQL Server 2012 I have a SQL Agent Job that shows "success" when it goes into the CATCH block, but I want it to show failure. I thought THROW would do this but in the below code when the query performs CATCH, ROLLBACK, and THROW the agent job succeeds.
All I'm trying to do is rollback the previous updates if update2 or update3 fail (pk violation), and in that case let the SQL job show "failure".
Please clue me in...
BEGIN TRY
BEGIN TRAN
UPDATE 1
UPDATE 2
UPDATE 3
COMMIT
END TRY
BEGIN CATCH
ROLLBACK
;THROW
END CATCH
I have a SQL script that does quite a few updates. When I retrieve the script (in a Classic ASP page) from a text file and attempt to execute it, it does not appear to apply all the updates I expect yet if I copy and paste the content into Management Studio, the query works fine. I cannot work out why this might be the case. Is there a limit as to how many statements/operations you can include in such a script?
Also the execute command oConn.Execute strSql does not fail, it just moves to the next line of classic ASP code. Is there any way I can test for errors?
Unfortunately I don't have enough reputation to comment on your question, but have you tried wrapping your code in TRANSACTION blocks? Very useful if things go wrong.
As for error handling, you can refer to the ##ERROR...
DECLARE #ErrorVar INT
RAISERROR(N'Message', 16, 1);
IF ##ERROR <> 0
-- This PRINT statement prints 'Error = 0' because
-- ##ERROR is reset in the IF statement above.
PRINT N'Error = ' + CAST(##ERROR AS NVARCHAR(8));
GO
Paul set me on the right track here, thank you. I've been coding SQL for years but confess I have dabbled only a little in the world of transactions. After the code below I put other stats and the failure message into a table that I interrogate in the ASP code after calling the script.
BEGIN TRY
BEGIN TRANSACTION
--My long update script placed in here
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF ##TRANCOUNT > 0
BEGIN
ROLLBACK TRANSACTION
SET #FailMsg = ERROR_MESSAGE() + ' Failed at line ' + CAST(ERROR_LINE() as varchar) + '.'
END
END CATCH
My question: Is it possible to rollback a stored procedure from another stored procedure in SQL Server 2005?
I have SP1 to insert the values into one table and SP2 to insert the values into another table.
So, if any error comes while executing the SP2 I want to rollback the SP1 also.
Please anyone help me to solve my problem.
Thanks,
Bharath
You need to wrap both calls in a single transaction.
if you call them in SQL then this is way, or using a more comprehensive version like the other answer by answered 7 mins ago gbn.
create proc doall as
BEGIN TRY
BEGIN TRAN
EXECUTE SP1
EXECUTE SP1
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRAN
END CATCH;
if you're calling the SPs from another source, such as from a non SQL program, you need to setup the outer transaction using a Microsoft Distributed Transaction Coordinator (MSDTC) service.
Depending on the API you're using you set up the transaction in Code, and then commit and rollback in code, dependant on conditions.
for example in .net you can use the System.Transactions namespace to create distributed transactions.
In the main program
var tran = new System.Transactions.Transaction();
.
.
.
in one piece of code doe a db call (and pass the tran object to the sql connection) so it enlists in the transaction... if it fails - abort the transaction (trans.Rollback())
.
.
.
.
in another piece of code do another db call (and pass the tran object to the sql connection) so it enlists in the transaction... if it fails - abort the transaction (trans.Rollback())
.
.
.
later...
if both pieces of code succeed commit the transaction
This is a good introduction to the this namespace if you're using .net
You need a wrapper stored procedure to manage the transaction.
##TRANCOUNT on entry and exit to a stored procedure must be the same, otherwise you get error 266. So you can't exit SP1 having started a TXN for example.
I assume that SP1 and SP2 ca nbe called standalone so you need a nested transaction.
Then you hit the same error because
BEGIN TRAN adds one to ##TRANCOUNT
COMMIT TRAN subtracts one from ##TRANCOUNT
ROLLBACK makes ##TRANCOUNT zero
So you can still get error 266.
My answer here explains more about it, including nesting, error 266 suppression etc: Nested stored procedures containing TRY CATCH ROLLBACK pattern?
So in your case, you need soemthing like this
CREATE PROCEDURE Wrapper
AS
SET XACT_ABORT, NOCOUNT ON
DECLARE #starttrancount int
BEGIN TRY
SELECT #starttrancount = ##TRANCOUNT
IF #starttrancount = 0
BEGIN TRANSACTION
EXEC SP1
EXEC SP2
IF #starttrancount = 0
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0 AND #starttrancount = 0
ROLLBACK TRANSACTION
RAISERROR [rethrow caught error using #ErrorNumber, #ErrorMessage, etc]
END CATCH
GO
I am using SQL Server 2008. I have tried to execute the following:
BEGIN TRY
SELECT 1/0;
END TRY
BEGIN CATCH
PRINT 'ERROR'
END CATCH;
But I am getting the following error:
>Msg 170, Level 15, State 1, Line 1
Line 1: Incorrect syntax near 'TRY'.
Msg 156, Level 15, State 1, Line 3
Incorrect syntax near the keyword 'END'.
Can any one tell me how execute try catch in SQL Server?
That is a completely valid statement for SQL Server 2005 and up, so I'd check your compatibility level using sp_dbcmptlevel (Transact-SQL):
exec sp_dbcmptlevel 'YourDatabaseName'
80 = SQL Server 2000
90 = SQL Server 2005
100 = SQL Server 2008
I think it will return 80 or lower, it seems that it doesn't know BEGIN TRY, only BEGIN. The BEGIN TRY was added in SQL Server 2005.
If you still have this error, the question becomes, have you put a BEGIN CATCH...END CATCH section in. If not, you get this error. If you have a BEGIN TRY...END TRY section with no T-SQL code in it, then it will also produce the error.
I don't think it's helpful people tell you that you're using SQL Server 2000. It is more likely a T-SQL coding issue as you tend to know what server you are running.
Begin try
Begin transaction
--------
--------
Commit transaction
End try
Begin catch
Rollback transaction
End catch
http://intquesans.blogspot.com/2011/05/how-we-can-use-try-catch-in-sql.html
This seems like an incredibly dumb question to have to ask, but how do I get SQL Server Management Studio to stop processing a SQL script when it encounters an error?
I have a long script and if there is an error at the start SSMS reports it and then blindly carries on, screwing up things even more. I can't use transactions because the script creates several databases and they can't go in a transaction. It is the database creation that sometimes fails.
Toad for SQL Server will pause at the first error it encounters and ask if you want to stop or continue. This is the behaviour I'm looking for. Does it exist in SSMS?
I am not asking, "How do I write or modify a script so that it stops on an error?" I'm not interested in modifying my script to make this happen, I just want SSMS to stop on an error. Toad for SQL Server does exactly this and that is the behaviour I want. This is also not a duplicate of 659188 because that relates to modifying the script to stop SSMS.
Short answer: You can't.
Thanks to those that provided workarounds, but it seems that SSMS itself can not be set to pause or stop on an error in the same way that Toad for SQL Server can.
consider using the command line program 'sqlcmd' that comes with SQL Server, with the -b and the -V options set. -b will cause sqlcmd to quit when it hits an error. -V controls the severity level that is considered to be an error.
ApexSQL Script generates batch scripts in exactly the manner you want. As an example:
--Script Header
begin transaction
go
{Statement #1}
go
--Standard Post-Statement Block
if ##error <> 0 or ##trancount = 0 begin
if ##trancount > 0 rollback transaction
set noexec on
end
go
{Statement #2}
go
--Standard Post-Statement Block
if ##error <> 0 or ##trancount = 0 begin
if ##trancount > 0 rollback transaction
set noexec on
end
go
--Script Footer
if ##trancount > 0 commit transaction
go
set noexec off
go
11 years later SSMS still doesn't have this feature...
BUT! You can enable SQLCMD mode (Menu/Query/SQLCMD Mode) and then in text editor you can define this option:
:ON ERROR EXIT
before your t-sql script. Now it will stop execution on error.
You need to wrap your SQL Statements inside a Transaction.
BEGIN TRANSACTION
/* run all your SQL statements */
COMMIT TRANSACTION
If there's an error inside the begin/end transaction, all statements will be rolled back.
EDIT: Wrapping inside inside begin/end transaction, will prevent the statements from getting committed to the database, but not stop it at that point. You need to additionally wrap it inside a try/catch block as follows:
BEGIN TRY
BEGIN TRANSACTION
/* run all your SQL statements */
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH
Wow. That's kinda rubbish isn't it? I use SQL-Workbench which, like Toad for SQL Server, handles this easily. Unlike Toad for SQL Server though, it's free.
I'm astonished that such fundamental functionality isn't part of the standard tool.
would using a try catch block help here. On error the try will be exited, implement error handling in the catch
http://msdn.microsoft.com/en-us/library/ms179296.aspx
There are a few more work-arounds mentioned here:
SQL Server - stop or break execution of a SQL script
and
SQL Server: How to abort a series of batches in Query Analyzer?
(raiseerror 20 with log, set noexec on, sqlcmd mode :on error exit, etc.)
If you can't put your script into a stored procedure and use the return statement to exit on error, the solution provided by #Justice might be your best bet. Everyone else is missing the point - you can't return from a script, even if you use transactions or even if you raiserror. SSMS will just execute the next thing anyway, even if set xact abort is on.
If you can convert your script to a stored procedure, then you can just return from it when you detect an error.