【发布时间】:2010-09-01 16:05:27
【问题描述】:
我有一个应用程序,我必须使用 SQL Server 2008 在数据库中插入 N 个元组,并且必须插入所有元组才能成功插入,我的问题是如何插入这些元组和如果有人失败,我会进行回滚以消除所有未正确插入的元组。
谢谢
【问题讨论】:
标签: sql sql-server sql-server-2008 insert
我有一个应用程序,我必须使用 SQL Server 2008 在数据库中插入 N 个元组,并且必须插入所有元组才能成功插入,我的问题是如何插入这些元组和如果有人失败,我会进行回滚以消除所有未正确插入的元组。
谢谢
【问题讨论】:
标签: sql sql-server sql-server-2008 insert
在 SQL Server 上,您可能会考虑使用bulk insert。
【讨论】:
在 .NET 中,您可以使用 SQLBulkCopy。
表值参数 (TVP) 是第二条路线。在您的插入语句中,在目标表上使用WITH (TABLOCK) 以实现最少的日志记录。例如:
INSERT Table1 WITH (TABLOCK) (Col1, Col2....)
SELECT Col1, Col1, .... FROM @tvp
将其包装在一个将@tvp 作为参数公开的存储过程中,添加一些事务处理,然后从您的应用程序中调用此过程。
如果数据具有嵌套结构,您甚至可以尝试将数据作为 XML 传递,然后将其分解到数据库端的表中。
【讨论】:
您应该调查交易。这是一个很好的intro article,它讨论了回滚等。
【讨论】:
如果您直接从程序中插入数据,您似乎需要的是事务。您可以直接在存储过程中启动事务,也可以从以您使用的任何语言编写的数据适配器启动事务(例如,在 C# 中您可能使用 ADO.NET)。
插入所有数据后,您可以提交事务或在出现错误时进行回滚。
有关创建、提交和回滚事务的一些详细信息,请参阅Scott Mitchell's "Managing Transactions in SQL Server Stored Procedures。
【讨论】:
对于 MySQL,请查看LOAD DATA INFILE,它允许您从磁盘文件中插入。
另请参阅Speed of INSERT Statements 上的一般 MySQL 讨论。
如需更详细的答案,请提供一些关于您正在使用的软件堆栈的提示,或许还有一些源代码。
【讨论】:
您有两个相互竞争的利益,进行大型事务(性能较差,失败风险高),或进行快速导入(最好不要在一个事务中完成所有操作)。
如果您要向表中添加行,则不要在事务中运行。如果您不喜欢第一轮的外观,您应该能够识别哪些行是新行并删除它们。
如果事务很复杂(每行影响几十个表等),那么在事务中小批量运行它们。
如果您绝对必须在一个事务中运行大量数据导入,请考虑在数据库处于单用户模式时执行此操作,并考虑使用 checkpoint 关键字。
【讨论】: