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 |
|
Vivaldi
Constraint Violating Yak Guru
298 Posts |
Posted - 2003-02-14 : 12:03:07
|
| Well,I have seen some sprocs where they have their sqland a label at the bottom to handle the error handling.I am trying to write more robust sprocs that have error handlingat any point and when an error occurs to jump out of the sql areahit the label (then do rollbacks, etc).Are labels the way to go. Or is there a better solution?Does the label get read if it comes to the label areain the sproc, or must it be called explicitly?Thanks for any advice________________________________________________A recent study shows that Southern Germany may have the best beer in the world. |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2003-02-14 : 12:15:38
|
| Well I have always heard from different experienced programmers that using labels is kind of like cheating. But that doesn't mean that you shouldn't use them. I currently do not have any stored procedures with labels in them, but I would never say that I will not use them in the future. Example of what to do:BEGIN TRAN UPDATE Table1 SET Column1 = 'value' WHERE Column3 = 'other' IF @@ERROR = 0 COMMIT TRAN ELSE BEGIN ROLLBACK TRAN GOTO BailOut END DELETE FROM Table2 WHERE Column2 = 76:BailOutRETURN--This example shows that if the UPDATE statement fails, the DELETE statement will not occur due to the BailOut label. |
 |
|
|
Vivaldi
Constraint Violating Yak Guru
298 Posts |
Posted - 2003-02-14 : 12:22:17
|
| Thanks,So, is the best way to write code to alwaysdo the if(@@error <> 0) -- do the rollbackelse -- commit it?It just seems there could be a more usable way to utilize error handling in a sproc than tripling the size of your code withthe error handlers.bitte________________________________________________A recent study shows that Southern Germany may have the best beer in the world. |
 |
|
|
nr
SQLTeam MVY
12543 Posts |
Posted - 2003-02-15 : 02:21:34
|
| You might want to set @context before the updates then the error handling becomes a single goto.declare @error int, @rowcount intdeclare @Context varchar(100)update...select @error = @@error, @rowcount = @@rowcountif @error <> 0beginset @context = 'update 1'goto errhndendbegin tranupdate...select @error = @@error, @rowcount = @@rowcountif @error <> 0beginset @context = 'update 2'goto errhndendcommit tranreturnErrHnd:raiserror('failed error=%d - %s',16,-1,@error, @context)returnErrHndTran:rollback tranraiserror('failed error=%d - %s',16,-1,@error, @context)return==========================================Cursors are useful if you don't know sql.DTS can be used in a similar way.Beer is not cold and it isn't fizzy. |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2003-02-15 : 11:31:46
|
| oooh, nr, I like that idea ! Hadn't thought of that one ... also kind of labels each segment of your code without needing a comment! very nice, I am going to start using this...- Jeff |
 |
|
|
tfountain
Constraint Violating Yak Guru
491 Posts |
Posted - 2003-02-18 : 10:37:54
|
| We use labels all the time for our error handling in our procedures. I'm not an advocate of GOTO's in any language, but they do have their place. |
 |
|
|
Vivaldi
Constraint Violating Yak Guru
298 Posts |
Posted - 2003-02-18 : 10:49:14
|
| Wow,Thanks for the advice.I will dig in and utilize that. Good to know its a reasonable way to do that.________________________________________________A recent study shows that Southern Germany may have the best beer in the world. |
 |
|
|
X002548
Not Just a Number
15586 Posts |
Posted - 2003-02-18 : 14:44:06
|
| There is a new feature with SQL 2000...it comes with sample templates so you don't have to type standard DDL code (like create Table, ect).It comes paramterized so you can globally replace them by going to menu item "EDIT\Replace Template Parameters", or CTRL+Shft+M.This is very useful, but they also allow you to create your own templates....so I took the sample below and turned in to a template.It needs to be stored in the location:C:\Program Files\Microsoft SQL Server\80\Tools\Templates\SQL Query Analyzer\Create ProcedureThe following can be placed in a file and saved as *.tql:if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[<stored_procedure_name, sysname, usp_New>]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)drop procedure [dbo].[<stored_procedure_name, sysname, usp_New>]GOCREATE PROCEDURE <stored_procedure_name, sysname, usp_New>AS ---- Enterprise Solutions---- File: <location_of_script, varchar(255), C:\TEMP\>-- Date: <Creation_Date, Date, GetDate()>-- Author: <author_name, varchar(255), Brett Kaiser>-- Server: <server_name, varchar(255), NJROS1D151\NJROS1D151DEV>-- Database: <db_Name, varchar(255), TaxReconDB>-- Login: <Login, varchar(255), sa>-- Description: <short_desc, varchar(255), This Procedure will >------ The stream will do the following:---- <Functions, varchar(255), '1. Function...>---- Tables Used: <Tables_Used, varchar(255), Table>---- Tables Created: <Tables_Created, varchar(255), Table>------ Row Estimates:-- name rows reserved data index_size unused-- -------------------- ----------- ------------------ ------------------ ------------------ ------------------------ sp_spaceused tblAcct_LedgerBalance--Change Log---- UserId Date Description-- ----------- -------------- -------------------------------------------------------------------------------------------- <Author_Id, Varchar(8), x002548> <Install_Date, DateTime, GetDate> <Init_Rel, varchar(255), 1. Initial release>------Declare @error_out int, @Result_Count int, @Error_Message varchar(255), @Error_Type int, @Error_Loc intBEGIN TRAN <SQL_Statement, varchar(255), SELECT> Select @Result_Count = @@ROWCOUNT, @error_out = @@error If @error_out <> 0 BEGIN Select @Error_Loc = 1 Select @Error_Type = 50001 GOTO <stored_procedure_name, sysname, usp_New>_Error END If @Result_Count = 0 -- Business Logic Error...This one for an expected row but no results BEGIN Select @Error_Loc = 1 Select @Error_Message = 'Put appropriate message here' Select @Error_Type = 50002 GOTO <stored_procedure_name, sysname, usp_New>_Error ENDCOMMIT TRAN<stored_procedure_name, sysname, usp_New>_Exit:-- Place any house keeping procedures here like...Set ansi_warnings ONreturn<stored_procedure_name, sysname, usp_New>_Error:Rollback TRANIf @Error_Type = 50001 BEGIN Select @error_message = (Select 'Location: ' + ',"' + RTrim(Convert(char(3),@Error_Loc)) + ',"' + ' @@ERROR: ' + ',"' + RTrim(Convert(char(6),error)) + ',"' + ' Severity: ' + ',"' + RTrim(Convert(char(3),severity)) + ',"' + ' Message: ' + ',"' + RTrim(description) From master..sysmessages Where error = @error_out) ENDIf @Error_Type = 50002 BEGIN Select @Error_Message = 'Location: ' + ',"' + RTrim(Convert(char(3),@Error_Loc)) + ',"' + ' Severity: UserLevel ' + ',"' + ' Message: ' + ',"' + RTrim(@Error_Message) ENDRAISERROR @Error_Type @Error_MessageGOTO <stored_procedure_name, sysname, usp_New>_ExitGO |
 |
|
|
|
|
|
|
|