从 TSQL OPENXML 中的 xml 文档中选择节点文本值

发布于 2024-10-07 16:50:31 字数 1518 浏览 4 评论 0原文

我有一个 xml 文档,我想用它来更新存储过程中的值。我可以使用 OPENXML 处理 XML,但我对提取所需的值感到困惑。 xml 中的每一行都是一个产品记录,我想为每个属性创建一个变量。 Cell0 是 ID、Cell2 描述等

DECLARE @idoc int  
DECLARE @doc varchar(1000)  
SET @doc ='
<products>    
 <rows>
  <row>
   <cell>1</cell>
   <cell>BALSAMO DERMOSCENT</cell>
   <cell>1.00</cell>
   <cell>0.00</cell>
   <cell>18.00</cell>
   <cell>18.00</cell>
   <cell>8.00</cell>
   <cell>427</cell>
   <cell>No</cell>
  </row>
  <row>
   <cell>2</cell>
   <cell>BAYTRIL 150 MG 1 CPDO</cell>
   <cell>1.00</cell>
   <cell>0.00</cell>
   <cell>3.50</cell>
   <cell>3.50</cell>
   <cell>8.00</cell>
   <cell>57</cell>
   <cell>No</cell>
  </row>
 </rows>
</products>'
--Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT statement that uses the OPENXML rowset provider.
SELECT    *
FROM       OPENXML (@idoc, '/products/rows/row/cell',1)
with (Col1 varchar(29) 'text()')

运行上述查询会为 xml 中的每个 CELL 返回 1 条记录。我希望能够每行返回 1 条记录,每个单元格具有不同的列,例如:-

Prod       Description              Qty
---------- --------------------     --------
1          BALSAMO DERMOSCENT       1.00  
2          BAYTRIL 150 MG 1 CPDO    1.00

我正在使用 MSSQL 2008

I have a xml document I want to use to update values in a stored procedure. I can process the XML using OPENXML, but I'm confused about extracting the values I want. Each row in the xml is a product record and I want to create a variable for each property. Cell0 is the ID, Cell2 description etc

DECLARE @idoc int  
DECLARE @doc varchar(1000)  
SET @doc ='
<products>    
 <rows>
  <row>
   <cell>1</cell>
   <cell>BALSAMO DERMOSCENT</cell>
   <cell>1.00</cell>
   <cell>0.00</cell>
   <cell>18.00</cell>
   <cell>18.00</cell>
   <cell>8.00</cell>
   <cell>427</cell>
   <cell>No</cell>
  </row>
  <row>
   <cell>2</cell>
   <cell>BAYTRIL 150 MG 1 CPDO</cell>
   <cell>1.00</cell>
   <cell>0.00</cell>
   <cell>3.50</cell>
   <cell>3.50</cell>
   <cell>8.00</cell>
   <cell>57</cell>
   <cell>No</cell>
  </row>
 </rows>
</products>'
--Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT statement that uses the OPENXML rowset provider.
SELECT    *
FROM       OPENXML (@idoc, '/products/rows/row/cell',1)
with (Col1 varchar(29) 'text()')

Running the above query returns 1 record for each CELL in the xml. I want to be able to return 1 record per row with different columns for each cell, something like:-

Prod       Description              Qty
---------- --------------------     --------
1          BALSAMO DERMOSCENT       1.00  
2          BAYTRIL 150 MG 1 CPDO    1.00

I'm using MSSQL 2008

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南冥有猫 2024-10-14 16:50:31

我想出了以下适合我的工作

DECLARE @idoc int
DECLARE @doc varchar(1000)
SET @doc ='
<products>
  <rows>
    <row>
      <cell>1</cell>
      <cell>BALSAMO DERMOSCENT</cell>
      <cell>1.00</cell>
      <cell>0.00</cell>
      <cell>18.00</cell>
      <cell>18.00</cell>
      <cell>8.00</cell>
      <cell>427</cell>
      <cell>No</cell>
    </row>
    <row>
      <cell>2</cell>
      <cell>BAYTRIL 150 MG 1 CPDO</cell>
      <cell>1.00</cell>
      <cell>0.00</cell>
      <cell>3.50</cell>
      <cell>3.50</cell>
      <cell>8.00</cell>
      <cell>57</cell>
      <cell>No</cell>
    </row>
  </rows>
</products>'
--Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT statement that uses the OPENXML rowset provider.
SELECT    *
FROM       OPENXML (@idoc, '/products/rows/row',1)
with (pLineNo int 'cell[1]/text()',
      pDesc varchar(50) 'cell[2]/text()',
      pQty float 'cell[3]/text()',
      pCost float 'cell[4]/text()',
      pPvp float 'cell[5]/text()',
      pTotal float 'cell[6]/text()',
      pIva float 'cell[7]/text()',
      pId int 'cell[8]/text()',
      pnoFact varchar(5) 'cell[9]/text()')

I've come up with the following which does the job for me

DECLARE @idoc int
DECLARE @doc varchar(1000)
SET @doc ='
<products>
  <rows>
    <row>
      <cell>1</cell>
      <cell>BALSAMO DERMOSCENT</cell>
      <cell>1.00</cell>
      <cell>0.00</cell>
      <cell>18.00</cell>
      <cell>18.00</cell>
      <cell>8.00</cell>
      <cell>427</cell>
      <cell>No</cell>
    </row>
    <row>
      <cell>2</cell>
      <cell>BAYTRIL 150 MG 1 CPDO</cell>
      <cell>1.00</cell>
      <cell>0.00</cell>
      <cell>3.50</cell>
      <cell>3.50</cell>
      <cell>8.00</cell>
      <cell>57</cell>
      <cell>No</cell>
    </row>
  </rows>
</products>'
--Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT statement that uses the OPENXML rowset provider.
SELECT    *
FROM       OPENXML (@idoc, '/products/rows/row',1)
with (pLineNo int 'cell[1]/text()',
      pDesc varchar(50) 'cell[2]/text()',
      pQty float 'cell[3]/text()',
      pCost float 'cell[4]/text()',
      pPvp float 'cell[5]/text()',
      pTotal float 'cell[6]/text()',
      pIva float 'cell[7]/text()',
      pId int 'cell[8]/text()',
      pnoFact varchar(5) 'cell[9]/text()')
巾帼英雄 2024-10-14 16:50:31

为什么在 sql server 2008 上使用 openxml?

这是一个更好的选择(我使用 varchar(max) 作为数据类型,但输入任何适用的内容)。请注意,您必须将变量声明为 xml,而不是 varchar。

SELECT
 Row.Item.value('data(cell[1])', 'varchar(max)') As Prod,
 Row.Item.value('data(cell[2])', 'varchar(max)') As Description,
 Row.Item.value('data(cell[3])', 'varchar(max)') As Qty
FROM
 @doc.nodes('//row') AS Row(Item)

注意:如果您执行的是存储过程,则可能必须在 select 语句之前包含以下内容:

SET ARITHABORT ON -- required for .nodes

如果必须使用 openxml,至少在完成后清理它:

exec sp_xml_removedocument @idoc

Why use openxml on sql server 2008?

This is a better option (I used varchar(max) as the datatype, but enter whatever is applicable). Note you have to declare the variable as xml, not varchar.

SELECT
 Row.Item.value('data(cell[1])', 'varchar(max)') As Prod,
 Row.Item.value('data(cell[2])', 'varchar(max)') As Description,
 Row.Item.value('data(cell[3])', 'varchar(max)') As Qty
FROM
 @doc.nodes('//row') AS Row(Item)

Note: If you're doing this is a stored procedure you may have to include the following before the select statement:

SET ARITHABORT ON -- required for .nodes

If you must use openxml, at least clean it up when you're done:

exec sp_xml_removedocument @idoc
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文