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 |
|
EDanaII
Starting Member
5 Posts |
Posted - 2009-02-13 : 11:37:15
|
I would appreciate a critique on the following stored procedure, if anyone is willing:USE EDLibraryGO/****** Object: StoredProcedure Items.CheckIn Script Date: 01/30/2009 11:03:54 ******/IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'Items.CheckIn') AND type in (N'P', N'PC')) DROP PROCEDURE Items.CheckInGO/****** Object: StoredProcedure Items.CheckIn Script Date: 01/30/2009 11:04:10 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROC Items.CheckIn ( @ISBN INT, @CopyNo INT, @Result INT OUTPUT)ASSET NOCOUNT ON--Do we have ISBN?IF (@ISBN IS NULL) RAISERROR('An ISBN must be supplied.', 16, 1)--Do we have Copy No?IF (@ISBN IS NULL) RAISERROR('A Copy Number must be supplied.', 16, 2)BEGIN TRY BEGIN TRANSACTION-- Record this loan for posterity. INSERT INTO LoanHist SELECT ISBN, Copy_No, Out_Date, Title_No, Member_No, Due_Date, GETDATE(), NULL, NULL, NULL, NULL FROM Loan WHERE ISBN = @ISBN AND Copy_No = @CopyNo-- Check to see if the update was successful. SET @Result = @@ERROR IF @Result <> 0 RAISERROR('The LoanHist table was not updated.', 16, @Result)-- Remove current loan from the record. DELETE FROM Loan WHERE ISBN = @ISBN AND Copy_No = @CopyNo-- Check to see if the update was successful. SET @Result = @@ERROR IF @Result <> 0 RAISERROR('The Loan table was not updated.', 16, @Result)-- Indicate that the copy is no longer on loan. UPDATE Copy SET On_Loan = 'N' WHERE ISBN = @ISBN AND Copy_No = @CopyNo-- Check to see if the update was successful. SET @Result = @@ERROR IF @Result <> 0 RAISERROR('The Copy table was not updated.', 16, @Result) SET @Result = 0 COMMIT TRANSACTIONEND TRY--Report on any errors should they occur.BEGIN CATCH SET @Result = error_state() SELECT @Result 'Error State', error_message() 'Error Message' ROLLBACK TRANSACTIONEND CATCHAnything I'm doing wrong, anything I could do better? I'm just looking for anything that would help me improve my technique.Thanks,Ed. |
|
|
yosiasz
Master Smack Fu Yak Hacker
1635 Posts |
Posted - 2009-02-13 : 12:08:28
|
| looks gorgeous to mebut you haev a problem in the second IF statement--Do we have ISBN?IF (@ISBN IS NULL) RAISERROR('An ISBN must be supplied.', 16, 1)--Do we have Copy No?IF (@ISBN IS NULL) RAISERROR('A Copy Number must be supplied.', 16, 2) |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2009-02-13 : 12:20:29
|
Might want to put some a RETURN statement after the messages as well so the you don't do the logic: That way you can also return an error value to a calling proc. (in this caase 500)IF (@ISBN IS NULL) RAISERROR('An ISBN must be supplied.', 16, 1)to IF (@ISBN IS NULL) BEGIN RAISERROR('An ISBN must be supplied.', 16, 1) RETURN 500ENDCharlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2009-02-13 : 12:24:28
|
Also -- you make a blind reference to a table during an insert: I'd change that to include the columns inserted into -- it's easier to debug and it means the statement can survive a schema change that introduces optional columns. INSERT INTO LoanHist ( x, y, z, a, b, c, .....) SELECT ISBN, Copy_No, Out_Date, Title_No, Member_No, Due_Date, GETDATE(), NULL, NULL, NULL, NULL FROM Loan WHERE ISBN = @ISBN AND Copy_No = @CopyNo Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
|
EDanaII
Starting Member
5 Posts |
Posted - 2009-02-13 : 15:31:56
|
| Thanks for the feedback, guys. It's appreciated.@ Transact Charlie.Wouldn't the RETURN be unreachable placed after the RAISERROR or am I misunderstanding how it works?Also, wouldn't it be more efficient to place the RETURN at the end of the BEGIN CATCH block under those circumstances?Just wondering.Ed. |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2009-02-16 : 06:51:23
|
| Hi EDanaII,RAISERROR doesn't halt a batch (unless there's something I'm not aware of). However it does fire your TRY CATCH block. (I've just tested it on a 2005 server -- We've got a mixed 2000 / 2005 code base so we have to write to compant level 80 most of the time! Sucks because I can't use TRY / CATCH or my personal favourite ROW_NUMBER most of the time!)Indded -- you don't need the RETURN value for each RAISERROR (you would without the TRY/CATCH and you could use it in your CATCH block after the ROLLBACK. Disregard my previous advice re RETURN -- it's not relevant!all looks good -- I don't like unqualified references to tables for inserts / updates but that's probably a personal thing. It's only really bad if your schema is apt to change a lot.Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
|
jbp_j
Starting Member
24 Posts |
Posted - 2009-02-16 : 07:56:30
|
| hi,After any DML operation completed u r checking for error, if any error is occur the control automatically goes to catch block no need of Checking the error each time.-- Check to see if the update was successful. SET @Result = @@ERROR IF @Result <> 0 RAISERROR('The LoanHist table was not updated.', 16, @Result)if any errors are occurred u have to handle ERRORS in catch block only.I THINK THIS CODE IS ENOUGH.USE EDLibraryGO/****** Object: StoredProcedure Items.CheckIn Script Date: 01/30/2009 11:03:54 ******/IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'Items.CheckIn') AND type in (N'P', N'PC')) DROP PROCEDURE Items.CheckInGO/****** Object: StoredProcedure Items.CheckIn Script Date: 01/30/2009 11:04:10 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROC Items.CheckIn ( @ISBN INT, @CopyNo INT, @Result INT OUTPUT)ASSET NOCOUNT ON--Do we have ISBN?IF (@ISBN IS NULL) BEGIN RAISERROR('An ISBN must be supplied.', 16, 1)RETURN 500END--Do we have Copy No?IF (@ISBN IS NULL) BEGIN RAISERROR('A Copy Number must be supplied.', 16, 2)RETURN 500 END BEGIN TRY BEGIN TRANSACTION-- Record this loan for posterity. INSERT INTO LoanHist SELECT ISBN, Copy_No, Out_Date, Title_No, Member_No, Due_Date, GETDATE(), NULL, NULL, NULL, NULL FROM Loan WHERE ISBN = @ISBN AND Copy_No = @CopyNo-- Remove current loan from the record. DELETE FROM Loan WHERE ISBN = @ISBN AND Copy_No = @CopyNo-- Indicate that the copy is no longer on loan. UPDATE Copy SET On_Loan = 'N' WHERE ISBN = @ISBN AND Copy_No = @CopyNo SET @Result = 0 COMMIT TRANSACTIONEND TRY--Report on any errors should they occur.BEGIN CATCH SET @Result = error_state() SELECT @Result 'Error State', error_message() 'Error Message' ROLLBACK TRANSACTIONEND CATCH |
 |
|
|
|
|
|
|
|