我使用类似这样的东西:
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