Try Catch Block的存储过程无效

时间:2015-12-21 15:08:09

标签: sql sql-server tsql

我必须编写一个存储过程来将一个表的数据复制到另一个表中。如果在复制过程中出现任何损坏的记录(例如:null记录),则需要绕过这些记录,并且复制应继续下一条记录。

我在目标表中有列用于标识复制哪些办公室以及未复制哪些办公室。我已尝试使用try catch block

下面的存储过程
CREATE TABLE OFFICE_new 
(
    id int identity, 
    officeid int null, 
    ok int,
    notok int
)

CREATE TABLE OFFICE_old 
( 
    id int identity, 
    officeid int null
)

insert into OFFICE_old (officeid)
values (1000),(2000),(3000),(4000),(null),(6000)
go

alter procedure exception_check
as
begin
   begin try
   begin tran 
        insert into OFFICE_new (officeid)
            select officeid
            from OFFICE_old

        if @@error = 0
        begin
            update OFFICE_new 
            set ok = 1

            commit tran 
        end
    end try
    begin  catch
        insert into OFFICE_new (officeid,notok)
            select officeid, 1
            from OFFICE_old
        commit tran
    end catch
end

此存储过程应插入复制的办公室'ok' = 1和失败的办公室'notok' = 1。但它不起作用。

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

您的查询有多处问题。

首先,您的@@错误检查似乎不正确。您确定自己不在@@error = 0之后吗?

此外,您的提交语句位于IF内部,因此如果您未到达IF,您将永远不会提交。

 if @@error <>0
        begin
        update OFFICE_new set ok = 1
        commit tran /*<---- will not commit if you do not reach */
        end

此外 - 在您的捕获中,您仍尝试插入在您的交易中出错的内容,因此您将收到其他错误。 您正试图在officeid中插入NULL。

 insert into OFFICE_new (officeid,notok)
        select officeid, 1
        from OFFICE_old /* one of the values are NULL */

因此也会失败,因此不会设置&#39; notok&#39;

答案 1 :(得分:1)

将@@ error语句和alter procedure删除为:

alter procedure exception_check
as
begin
begin try
begin tran 
        insert into OFFICE_new (officeid,notok,ok)
        select officeid,0 as notok,1 as ok
        from OFFICE_old
        commit tran 
    end try
    begin  catch
          insert into OFFICE_new (officeid,notok,ok)
        select officeid,1 as notok,0 as ok
        from OFFICE_old
    commit tran
    end catch
end