4

我在 SQL 过程中遇到问题,我似乎找不到合适的解决方案。存储过程包含一个 XML 数据类型的参数 (name = @data)。

传入消息的示例如下(实际消息包含更多节点,但为简单起见,我将它们省略了):

<Suppliers xmlns="">
  <Supplier>
    <IDCONO>3</IDCONO>
    <IDSUNO>009999</IDSUNO>
    <IDSUTY>0</IDSUTY>
  </Supplier>
</Suppliers>

在我的 SQL 数据库中,我有一个名为“Supplier”的表,它包含与 XML 中的节点完全相同的列(IDCONO、IDSUNO、IDSUTY、..)

我需要遍历节点并将数据插入列中。我已经实现了下面的过程,但这给我带来了很多关于较大文件的性能问题(处理时间长,甚至超时):

INSERT INTO SUPPLIER
   (IDCONO
   ,IDSUNO
   ,IDSUTY)
SELECT
   T.C.value('IDCONO[1]', 'VARCHAR(50)') as IDCONO,
   T.C.value('IDSUNO[1]', 'VARCHAR(50)') as IDSUNO,
   T.C.value('IDSUTY[1]', 'VARCHAR(50)') as IDSUTY
from @data.nodes('/Suppliers/Supplier') T(C)

任何帮助表示赞赏!请注意,SQL 版本是 SQL Server 2012。

提前致谢。

4

1 回答 1

6

我要尝试的第一个方法是text()在使用 XML 数据类型时指定节点,以防止 SQL Server 对文本元素进行深度搜索。

INSERT INTO SUPPLIER
   (IDCONO
   ,IDSUNO
   ,IDSUTY)
SELECT
   T.C.value('(IDCONO/text())[1]', 'VARCHAR(50)') as IDCONO,
   T.C.value('(IDSUNO/text())[1]', 'VARCHAR(50)') as IDSUNO,
   T.C.value('(IDSUTY/text())[1]', 'VARCHAR(50)') as IDSUTY
FROM @data.nodes('/Suppliers/Supplier') T(C)

如果这还不够好,我会尝试使用 OPENXML。

DECLARE @idoc INT
EXEC sp_xml_preparedocument @idoc OUT, @data

INSERT INTO SUPPLIER
   (IDCONO
   ,IDSUNO
   ,IDSUTY)
SELECT IDCONO, IDSUNO, IDSUTY
FROM OPENXML(@idoc, '/Suppliers/Supplier', 2) WITH
        (IDCONO VARCHAR(50),
         IDSUNO VARCHAR(50),
         IDSUTY VARCHAR(50))


EXEC sp_xml_removedocument @idoc
于 2013-05-27T12:49:57.273 回答