应用程序层(ColdFusion)需要在SQL Server 2005中插入多行。
我正在考虑在app层中使用循环来构造多个输入语句,并通过JDBC在单个连接中发送到SQL Server。
然而,我的同事建议构建XML并批量插入XML。
哪一个是更好的方法?
答案 0 :(得分:4)
对于数百万行的插入,我使用了BULK INSERT,将数据写入SQL Server实例可以访问的CSV文件。这通过JDBC优于任何类型的插入,但代价是降低了灵活性。对于较少数量的行,可以使用JDBC的Statement.addBatch()
和Statement.executeBatch()
来避免发送许多小命令的开销。
根据您的要求,您可能必须将所有这些放在一个事务中,或者如果不需要对整个数据集进行完整的ACID保证,您可以分成几个事务。
这是一篇讨论bulk insert of XML的文章。我没有数据可以得出任何结论,但我猜想BULK INSERT原始行数据会更快,因为不需要OPENXML转换。当然,如果您的数据已经是XML格式,那么这是有道理的,但如果没有,那么保留表格数据可能是最简单的,也可能是最高效的。
答案 1 :(得分:2)
XML将是更好的IMO方法,尽管我还建议您创建一个存储过程来处理实际处理而不是运行内联查询。
基本上,您将XML数据作为单个参数发送,然后在SP内部运行INSERT INTO SELECT语句,从XML中选择一些表或一组表。
DECLARE @FOO xml;
SET @FOO = '<things><thing><id>1</id></thing><thing><id>2</id></thing><thing><id>3</id></thing><thing><id>4</id></thing></things>';
SELECT
ParamValues.id.value('.', 'int') AS thing_id
FROM
@FOO.nodes('/things/thing/id') AS ParamValues(id)
这将创建一个包含单个列“thing_id”的表。现在您所要做的就是
INSERT INTO someTable (someID)
SELECT
ParamValues.id.value('.', 'int') AS thing_id
FROM
@FOO.nodes('/things/thing/id') AS ParamValues(id)
并且你有一个INSERT可以处理你拥有的多行XML。
答案 2 :(得分:1)
由于所有网络延迟,一次一个INSERT将不必要地缓慢。
更好的执行方式是在一次网络往返中将多个交易作为单个批次发送,并将它们作为单个工作单元提交。
如果您有大量的记录,您可能需要考虑混合方法:循环多个批次并将它们作为一个工作单元发送。即使对于大型事务,这也会执行,并且在提交整个事务之前,您不会强制数据库维护大型回滚日志。
如果您的XML解决方案意味着将原始XML流作为CLOB插入,我不是粉丝。一旦它在数据库中,您将如何查询它?你失去了SQL给你的一切:查询的能力。如果存储原始XML,您所能做的就是针对特定值的XPath。更新意味着更换整个CLOB。