[英]Errors are not handled by Try/Catch Block in SQL Server
We are using following error handling pattern in SQL Server stored procedures:我们在 SQL Server 存储过程中使用以下错误处理模式:
ALTER PROCEDURE [dbo].[USP_Districtdata_Import]
@DistrictData DistrictData Readonly
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRAN
--Insert the new records into BudgetDistrict Table.
INSERT INTO [dbo].[BudgetDistrict]
(
DistrictID,
[Year],
Season,
BudgetStateID,
ProjectedReturnCountIsCalc,
RowStatus,
CreatedBy,
CreatedDate,
LastModifiedBy,
LastModifiedDate,
EnableBudgetLock
)
SELECT
DISTINCT list.[District Id],list.[Year],list.[Season],1,0,'A',@CreatedBy,@Updtime,@CreatedBy,@Updtime,0
FROM @DistrictData liston]
AND bud.RowStatus = 'A'
)
LEFT OUTER JOIN [dbo].[BudgetDistrict] bud
ON (bud.DistrictID = list.[District Id]
AND bud.[Year] = list.[Year]
AND bud.[Season] = list.[Seas
WHERE bud.DistrictID IS NULL
--Update the existing pending budgets
UPDATE wk
SET wk.Budget = list.[Budget],
wk.BudgetAdjusted = list.[Budget],
wk.ProjectedReturnCount = list.[ProjectedReturn Count],
wk.CreatedBy = @CreatedBy,
wk.CreatedDate = @Updtime,
wk.LastModifiedBy = @CreatedBy,
wk.LastModifiedDate = @Updtime
FROM @DistrictData list
INNER JOIN [dbo].[BudgetDistrict] bud
ON (bud.DistrictID = list.[District Id]
AND bud.[Year] = list.[Year]
AND bud.[Season] = list.[Season])
INNER JOIN [dbo].[BudgetDistrictWeekly] wk
ON (wk.NationalBudgetID = bud.BudgetDistrictID
AND wk.[WeekDate] = list.[Week])
WHERE bud.RowStatus = 'A'
AND wk.RowStatus = 'A'
AND bud.BudgetStateID = 1
--Insert the new budgets
INSERT INTO [dbo].[BudgetDistrictWeekly]
(
WeekDate,
Budget,
BudgetAdjusted,
RowStatus,
CreatedBy,
CreatedDate,
LastModifiedBy,
LastModifiedDate,
ProjectedReturnCount
)
SELECT LIST.[Week],list.[Budget],list.[Budget],'A',@CreatedBy,@Updtime,@CreatedBy,@Updtime,[ProjectedReturn Count]
FROM @DistrictData list
LEFT JOIN [dbo].[BudgetDistrict] bud
ON (bud.DistrictID = list.[District Id]
AND bud.[Year] = list.[year]
AND bud.[Season] = list.Season
AND bud.RowStatus = 'A')
WHERE bud.DistrictID IS NULL
IF @@ERROR = 0
BEGIN
COMMIT TRAN;
END
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_LINE() AS ErrorLine,
ERROR_MESSAGE() AS ErrorMessage;
ROLLBACK TRAN;
END CATCH
SET NOCOUNT OFF;
END
but when the below error occurs in the stored procedure the try/catch block didn't work.但是当存储过程中出现以下错误时,try/catch 块不起作用。
Error details: stored Procedure tried to insert a NULL
value into a not null column.错误详细信息:存储过程试图将
NULL
值插入到非空列中。
During the execution of the stored procedure, I got following error在执行存储过程期间,出现以下错误
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements.
EXECUTE 之后的事务计数表示 BEGIN 和 COMMIT 语句的数量不匹配。 Previous count = 1, current count = 0.
先前计数 = 1,当前计数 = 0。
Msg 3903, Level 16, State 1, Line 30
消息 3903,级别 16,状态 1,第 30 行
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.ROLLBACK TRANSACTION 请求没有对应的 BEGIN TRANSACTION。
Why is the exception not handled?为什么不处理异常? Please help
请帮忙
According to documentation ( Errors Unaffected by a TRY…CATCH Construct section) some errors are not caught by CATCH statement.根据文档(错误不受 TRY…CATCH 构造部分的影响),某些错误不会被 CATCH 语句捕获。
Particularly:特别是:
Quite typical situation is when a stored proc accesses table column (or accesses object) that were removed after the stored proc has been created.非常典型的情况是当存储过程访问在创建存储过程后删除的表列(或访问对象)时。
See the sample below:请参阅下面的示例:
create table #test (id int, somecolumn uniqueidentifier)
GO
create procedure #testSP
as
begin try
set nocount on;
begin tran;
insert into #test (id, somecolumn)
values (1, 0x);
commit;
end try
begin catch
rollback;
print 'Error happened';
end catch
GO
exec #testSP
GO
alter table #test
drop column somecolumn
GO
exec #testSP
GO
The above code produces上面的代码产生
Msg 207, Level 16, State 1, Procedure #testSP_..._00053EAF, Line 33 Invalid column name 'somecolumn'.
消息 207,级别 16,状态 1,过程#testSP_..._00053EAF,第 33 行无效的列名称“somecolumn”。
Msg 266, Level 16, State 2, Procedure #testSP_..._00053EAF, Line 33 Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements.
消息 266,级别 16,状态 2,过程#testSP_..._00053EAF,第 33 行 EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数量不匹配。 Previous count = 1, current count = 2.
先前计数 = 1,当前计数 = 2。
As you see despite the severity level is 16, the errors are not caught and message Error happened
does not printed.如您所见,尽管严重性级别为 16,但未捕获
Error happened
并且未打印Error happened
消息。
有一种方法,如果您能够使用动态 sql,那么请尝试使用 catch 工作
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.