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

Откуда: Москва
Сообщений: 188
Здравствуйте, сервер старый по версии (2000-2005), решения не смог найти...
подскажите пожалуйста как в пользовательской функции распарсить xml строку
(хочу использовать универсальную UDF на входе xml фрагмент и выражение xPath/xQuery на выходе значение узла/атрибута)

DECLARE @xData XML 
DECLARE @xPath varchar(256)

set @xData= '<ServerInfo><RecCount>10</RecCount></ServerInfo>'
set @xPath='//RecCount'
set @xPath='for $s in //RecCount return string($s)'

SELECT @xData.query('for $s in //RecCount return string($s)').value('text()[1]', 'varchar(255)')
--SELECT @xData.query('@xPath').value('text()[1]', 'varchar(255)')
SELECT @xData.query('sql:variable("@xPath")').value('text()[1]', 'varchar(255)')


проблема - не могу корректно вставить локальную переменную в строковый литерал .query
если литерал прописан сразу
.query('for $s in //RecCount return string($s)'... значение выводится корректно
если литерал указывается через переменную
.query('sql:variable("@xPath")'... выводится не значение узла а значение переменной - 'for $s in //RecCount return string($s)'

?
10 янв 18, 13:30    [21093204]     Ответить | Цитировать Сообщить модератору
 Re: mssql2000-2005 прочитать значение узла xml в UDF  [new]
ef1
Member

Откуда: Москва
Сообщений: 188
синтаксис брал из рабочего примера
DECLARE @xData XML 
DECLARE @x INT

set @xData= '<ServerInfo><RecCount>10</RecCount></ServerInfo>'
set @x= 1134

set @xData.modify('replace value of (/ServerInfo/RecCount/text())[1] with sql:variable("@x")')
SELECT @xData


но никак на чтение не могу переписать
10 янв 18, 13:38    [21093236]     Ответить | Цитировать Сообщить модератору
 Re: mssql2000-2005 прочитать значение узла xml в UDF  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1364
ef1,

вам походу динамический XQuery нужен
+ для версии > 2005

DECLARE @xData XML 
DECLARE @xPath varchar(256)
declare @xQuery varchar(256)
declare @sql nvarchar(max)

set @xData= '<ServerInfo><RecCount>10</RecCount></ServerInfo>'
set @xPath='//RecCount'
set @xQuery='for $s in //RecCount return string($s)'

SELECT @xData.query('for $s in //RecCount return string($s)').value('text()[1]', 'varchar(255)')
--SELECT @xData.query('@xPath').value('text()[1]', 'varchar(255)')
SELECT @xData.query('data(sql:variable("@xQuery"))')

set @sql = replace(N'select @xmldata.query(''{0}'').value(''.'', ''nvarchar(max)'');', '{0}', @xQuery);
exec sp_executesql
    @sql,
    @params = N'@xmldata xml',
    @xmldata = @xData



+ для версии 2005

DECLARE @xData XML 
DECLARE @xPath varchar(256)
declare @xQuery varchar(256)
declare @sql nvarchar(max)

set @xData= '<ServerInfo><RecCount>10</RecCount></ServerInfo>'
set @xPath='//RecCount'
set @xQuery='for $s in //RecCount return string($s)'

SELECT @xData.query('for $s in //RecCount return string($s)').value('text()[1]', 'varchar(255)')
--SELECT @xData.query('@xPath').value('text()[1]', 'varchar(255)')
--SELECT @xData.query('data(sql:variable("@xQuery"))')
set @sql = replace(replace('declare @x xml; set @x =''{0}''; select @x.query(''{1}'').value(''.'', ''nvarchar(max)'')', '{0}', convert(nvarchar(max), @xData)), '{1}', @xQuery);

exec (@sql);

10 янв 18, 14:56    [21093585]     Ответить | Цитировать Сообщить модератору
 Re: mssql2000-2005 прочитать значение узла xml в UDF  [new]
ef1
Member

Откуда: Москва
Сообщений: 188
да, похоже на то....
думал о динамическом запросе...

felix_ff - большое спасибо!!! - все ок, тему закрываем
10 янв 18, 15:11    [21093676]     Ответить | Цитировать Сообщить модератору
 Re: mssql2000-2005 прочитать значение узла xml в UDF  [new]
ef1
Member

Откуда: Москва
Сообщений: 188
felix_ff - еще один вопрос (для варианта MSSQL2005)

столкнулся с ограничением динамического запроса 'парсера xml' в 4к, хотя указан nvarchar(max) 8к/2g - но где-то режется до 4к - не подскажите где это ограничение в тексте хп

ALTER procedure [LSDBO].[Ric_Get_XmlParser_ForForms]
        (@xData xml,      		 -- исходная xml строка
         @xQuery varchar(256)       -- строка с xPath/xQuery запросом 
         )as 
Begin

declare @sql nvarchar(max)

 Set ARITHABORT ON --без этого наш клиент падает

  Begin
    set @xQuery = 'for $s in ' + @xQuery +' return string($s)' 
    set @sql = replace(replace(N'declare @x xml; set @x =''{0}''; select @x.query(''{1}'').value(''.'', ''nvarchar(max)'')', '{0}', convert(nvarchar(max), @xData)), '{1}', @xQuery);
    exec (@sql);    
  End

  Set ARITHABORT OFF
End

exec LSDBO.Ric_Get_XmlParser_ForForms xmlfragment, xPath/xQuery


все режет - @xQuery своим типом varchar(256)?
2 фев 18, 07:27    [21159440]     Ответить | Цитировать Сообщить модератору
 Re: mssql2000-2005 прочитать значение узла xml в UDF  [new]
ef1
Member

Откуда: Москва
Сообщений: 188
сам спросил сам ответил, обрезание было в двойном replace в одной строке, если разложить по отдельности - до 4к не срезается
--режется до 4к
set @sql = replace(replace('declare @x xml; set @x =''{0}''; select @x.query(''{1}'').value(''.'', ''nvarchar(max)'')', '{0}', convert(nvarchar(max), @xData)), '{1}', @xQuery);

--не режется     
    set @sql='declare @x xml; set @x =''{0}''; select @x.query(''{1}'').value(''.'', ''nvarchar(max)'')'
    set @sql=replace(@sql,'{1}', @xQuery);
    set @sql=replace(@sql,'{0}', convert(nvarchar(max), @xData));
2 фев 18, 08:14    [21159482]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить