ВЫБЕРИТЕ текстовые значения узла из документа xml в TSQL OPENXML - PullRequest
3 голосов
/ 15 декабря 2010

У меня есть XML-документ, который я хочу использовать для обновления значений в хранимой процедуре.Я могу обработать XML с помощью OPENXML, но я не совсем понимаю, какие значения мне нужны.Каждая строка в XML является записью продукта, и я хочу создать переменную для каждого свойства.Cell0 - это идентификатор, описание 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()')

Выполнение вышеуказанного запроса возвращает 1 запись для каждой ячейки в xml.Я хочу иметь возможность возвращать 1 запись в строке с разными столбцами для каждой ячейки, например: -

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

Я использую MSSQL 2008

Ответы [ 2 ]

5 голосов
/ 15 декабря 2010

Я придумал следующее, которое выполняет эту работу за меня

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()')
0 голосов
/ 15 декабря 2010

Зачем использовать openxml на SQL Server 2008?

Это лучший вариант (я использовал 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
...