我必须编写一个存储过程来将一个表的数据复制到另一个表中。如果在复制过程中出现任何损坏的记录(例如: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
。但它不起作用。
感谢您的帮助。
答案 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