假设我在SQL
服务器中有一个程序:
create procedure BULKINSERT
AS
INSERT INTO TABLEB (
SELECT NAME, ID From TableA
)
GO
从 TABLE A
读取数据并插入 TABLE B
的简单数据。如果我有100万条记录要插入表B,如果一条记录因任何原因失败,在这种情况下我应该使用 TRANSACTION
吗?
我应该回滚整个操作吗?
答案 0 :(得分:2)
您可以将以下模板用于存储过程:
SET NOCOUNT, XACT_ABORT ON;
BEGIN TRY
BEGIN TRANSACTION;
-- CODE BLOCK GOES HERE
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
BEGIN
ROLLBACK TRANSACTION
END;
-- GET ERRORS DETAILS OR THROW ERROR
END CATCH;
SET NOCOUNT, XACT_ABORT OFF;
更多详情:
XACT_ABORT - 指定当Transact-SQL语句引发运行时错误时,SQL Server是否自动回滚当前事务;
如果您需要有关错误的信息(ERROR_MESSAGE,ERROR_LINE,ERROR_NUMBER,ERROR_PROCEDURE,ERROR_SEVERITY,ERROR_STATE)
这是处理事务的一般技术。我会推荐Erland Sommarskog
的以下文章:
答案 1 :(得分:1)
由于一个语句始终被视为原子语,并且此处只有1个语句,因此在TABLEB
中插入了100万条记录,或者没有。但是,如果发生错误,您可能希望处理错误,在这种情况下,您应将INSERT
放入TRY
块并添加CATCH
来处理错误时应采取的措施
要阅读有关该主题的更多信息,请查看以下来源以获得良好的起点:
答案 2 :(得分:1)
如上所述,单一陈述是一项交易。
对TABLEB的主键上的插入进行排序以减慢碎片。
要注意的一件事是多次插入相同的数据 如果你想阻止它然后离开加入pk。
declare @Ta table (id int identity primary key, name varchar(10));
declare @Tb table (id int primary key, name varchar(10));
insert into @Ta values ('name'), ('name'), ('name'), ('name'), ('name'), ('name'), ('name'), ('nameL');
insert into @Tb (id, name)
select id, name from @Ta order by id;
select * from @Tb;
insert into @Tb (id, name)
select ta.id, ta.name
from @Ta ta
left join @Tb tb
on tb.id = ta.id
where tb.id is null
order by ta.id;
select * from @Tb;
如果要更新现有搜索合并命令的数据。