2010-12-15 2 views
3

У меня есть XML-документ, который я хочу использовать для обновления значений в хранимой процедуре. Я могу обрабатывать XML с помощью OPENXML, но я запутался в извлечении значений, которые я хочу. Каждая строка в xml является записью продукта, и я хочу создать переменную для каждого свойства. Cell0 - это идентификатор, описание Cell2 и т. Д.SELECT текстовые значения узла из XML-документа в TSQL OPENXML

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

ответ

4

Я пришел с нижеследующим делает то работа для меня

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

Было интересно об этом. +1. Почему бы не пойти дальше и не принять свой собственный ответ ;-) – 2010-12-15 13:54:28

0

Зачем использовать 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) 

Примечание: Если вы делаете это хранимая процедура, возможно, придется включать в себя следующее до оператора выбора:

SET ARITHABORT ON -- required for .nodes 

Если вы должны использовать OPENXML, по крайней мере, очистить его, когда все готово:

exec sp_xml_removedocument @idoc 
+0

В чем причина требования SET ARITHABORT ON? Есть ли у вас какой-либо справочный материал, который указывает, что последствия этого не применяются? – 2012-08-24 07:04:50

Смежные вопросы