我使用類似這樣的東西:
CREATE PROCEDURE ErrorHandlingPattern
( @intParam int
,@varcharParam varchar(10)
,@dateParam datetime
)
AS
BEGIN TRY
SET NOCOUNT ON
DECLARE @Rows int --store @@ROWCOUNT in this
,@ErrorMsg varchar(500) --temp string to build the contents of messages passed into RAISERROR calls
,@LogInfo varchar(5000) --will hold any info necessary for error debugging, append to this throughout the procedure with important info
,@TransactionCount int
SELECT @[email protected]@TRANCOUNT
,@LogInfo='@intParam=' +ISNULL(''''+CONVERT(varchar(10), @intParam )+'''','NULL')
+', @varcharParam=' +ISNULL(''''+ @varcharParam +'''','NULL')
+', @dateParam=' +ISNULL(''''+CONVERT(varchar(10), @dateParam,121 )+'''','NULL')
+'; @@TRANCOUNT=' +ISNULL(''''+CONVERT(varchar(10), @@TRANCOUNT )+'''','NULL')
--validate parameters
IF @intParam ....
BEGIN --logical error
SET @ErrorMsg='Error, invalid value for @intParam: '+ISNULL(''''+CONVERT(varchar(10),@intParam)+'''','NULL')
RAISERROR(@ErrorMsg,16,1) --send control to the BEGIN CATCH block
END
IF @TransactionCount=0 --if we are already in a transaction, no need to start another, nesting transactions +rollback=warnings about transaction count not being the same as when the procedure started.
BEGIN
BEGIN TRANSACTION
END
--do your work here....
INSERT/UPDATE/DELETE...
SELECT @[email protected]@ROWCOUNT
IF @Rows!=ExpectedValue
BEGIN --logical error
SET @ErrorMsg='Error, INSERT/UPDATE/DELETE of tableXYZ resulted in '+ISNULL(''''+CONVERT(varchar(10),@Rows)+'''','NULL')+' rows affected'
RAISERROR(@ErrorMsg,16,1) --send control to the BEGIN CATCH block
END
--append improtant info to log string
SET @LogInfo=ISNULL(@LogInfo,'')+'; INSERT/UPDATE/DELETE of tableXYZ resulted in '+ISNULL(''''+CONVERT(varchar(10),@Rows)+'''','NULL')+' rows affected'
IF @TransactionCount=0 --only end the transaction if it started here
BEGIN
COMMIT --put in try block to be able to catch any problems committing
END
END TRY
BEGIN CATCH
IF XACT_STATE()!=0 --if there is any error end the transaction ASAP
BEGIN
ROLLBACK TRANSACTION
END
--will echo back the complete original error message
DECLARE @ErrorMessage nvarchar(400), @ErrorNumber int, @ErrorSeverity int, @ErrorState int, @ErrorLine int
SELECT @ErrorMessage = N'Error %d, Line %d, Message: '+ERROR_MESSAGE(),@ErrorNumber = ERROR_NUMBER(),@ErrorSeverity = ERROR_SEVERITY(),@ErrorState = ERROR_STATE(),@ErrorLine = ERROR_LINE()
RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState, @ErrorNumber,@ErrorLine)
--because the transaction was ROLLBACKed this insert will be recorded in the database
INSERT INTO YourErrorLog (...) VALUES (...ISNULL(@ErrorMessage,'')+ISNULL(@LogInfo,''))
RETURN 999
END CATCH
RETURN 0
GO
由於您只是在執行一批a batch of SELECT, INSERT
,因此您可以刪除CREATE PROCEDURE和參數聲明並使第一行開始於BEGIN TRY。另外,因爲您沒有創建過程,請將所有RETURN語句替換爲GOTO TheEnd
,並在腳本底部添加一個TheEnd:
標籤。
這是非常完整的,謝謝。我確實在創建一個程序:我簡化了一下我的問題。非常滿意我今天學到的@@ ROWCOUNT和@@ TRANCOUNT。我總是避免長時間存儲過程,而是從Access(我真的掌握)中逐個調用一些零件。感覺現在變成「親」;-) – 2010-05-19 12:25:56