Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Парсинг xml - можно ли без курсора?  [new]
pima
Member

Откуда: Москва
Сообщений: 496
Добрый день!
Помогите, пожалуйста, с xml-ем, совсем туплю :(
Есть таблица, где для каждой строки лежит xml:

CREATE TABLE Tmp_Page(PageRequestID int, OutXml1 xml)
GO

INSERT INTO Tmp_Page(PageRequestID, OutXml1) VALUES(1, '<id-list_original>
        <item>
          <hash>2291011036397234713</hash>
          <idf>3.35</idf>
          <token>дорога</token>
        </item>
        <item>
          <hash>4102274751958317530</hash>
          <idf>0.52</idf>
          <token>налог</token>
        </item>
      </id-list_original>')
INSERT INTO Tmp_Page(PageRequestID, OutXml1) VALUES(2, '<id-list_original>
        <item>
          <hash>3502270050058774530</hash>
          <idf>0.52</idf>
          <token>подоходный</token>
        </item>
        <item>
          <hash>4102274751958317530</hash>
          <idf>0.52</idf>
          <token>налог</token>
        </item>
      </id-list_original>')
GO


Мне нужно получить выборку вида
1 2291011036397234713
1 4102274751958317530
2 3502270050058774530
2 4102274751958317530

Т.е. для каждого PageRequestID выбрать все значения item/hash. Как это сделать для одной записи, понятно:

DECLARE @test xml
SELECT @test = OutXml1 FROM Tmp_Page WHERE PageRequestID = 1

SELECT cast(cast(node.query('data(.)') as varchar(30)) as bigint)
FROM @test.nodes('/id-list_original/item/hash') as t(node)


А как теперь без курсора прикрутить сюда таблицу, чтобы это вызывалось для каждой записи? С курсором-то понятно, а без?
Пишу так:

SELECT cast(cast(node.query('data(.)') as varchar(30)) as bigint)
FROM dbo.Tmp_Page.OutXml1.nodes('/id-list_original/item/hash') as t(node)


получаю:
Msg 195, Level 15, State 15, Line 2
'dbo.Tmp_Page.OutXml1.nodes' is not a recognized function name.

Делаю функцию:

create function Test(@str xml)
returns table
AS
	RETURN SELECT cast(cast(node.query('data(.)') as varchar(30)) as bigint) as Hash
	FROM @str.nodes('/id-list_original/item/hash') as t(node)
GO


- а что толку-то, все равно надо как-то табличную функцию вызвать для каждой строки таблицы, а как?
select * from dbo.Test(monitor.Page.OutXml) - так, ясен пень, не идет. Значит, только курсором?
Заранее спасибо.
19 авг 13, 16:15    [14726490]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг xml - можно ли без курсора?  [new]
qwerty112
Guest
pima,

select a.PageRequestID, b.xz
from Tmp_Page a
cross apply (
	select t.c.value('text()[1]', 'varchar(20)') as xz
	from OutXml1.nodes('/id-list_original/item/hash') as t(c)
	) b
19 авг 13, 16:22    [14726550]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг xml - можно ли без курсора?  [new]
Гость333
Member

Откуда:
Сообщений: 3683
pima
надо как-то табличную функцию вызвать для каждой строки таблицы, а как?

Табличную функцию для каждой строки вызывают при помощи CROSS/OUTER APPLY.
Пользовательская функция тут не нужна, всё уже есть в методах XML.
SELECT tp.PageRequestID, node.value('.', 'bigint')
FROM Tmp_Page tp
     CROSS APPLY tp.OutXml1.nodes('/id-list_original/item/hash') as t(node)
19 авг 13, 16:24    [14726571]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг xml - можно ли без курсора?  [new]
pima
Member

Откуда: Москва
Сообщений: 496
Спасибо огромное! Заработало :)
19 авг 13, 16:25    [14726574]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить