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

Откуда: Минск
Сообщений: 1820
В чем разница применения exist ?
    SELECT
	    Param1.query('.').exist('/Param[(@Name cast as xs:string?) eq xs:string("UserId")]'),
	    Param1.exist('/Param[(@Name cast as xs:string?) eq xs:string("UserId")]')
    FROM
      job.TaskQueue AS tq
      CROSS APPLY tq.Params.nodes(N'(/Xml/Param)') AS T(Param1)
    WHERE
      tq.Id_TaskQueue = 1

Первый вернёт 1
Второй вернёт 0
Запрос Xml
<Xml>
  <Param Name="UserId" Type="INT">54129</Param>
</Xml>
12 ноя 15, 16:10    [18407126]     Ответить | Цитировать Сообщить модератору
 Re: Разница использования xml  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1712
X-Cite,

https://msdn.microsoft.com/ru-ru/library/ms189869(v=sql.120).aspx

в том что путь по которому вы ищете во втором сегменте не соответствует узлу: /Xml/Param

declare @x xml 
set @x = '<Xml>
  <Param Name="UserId" Type="INT">54129</Param>
</Xml>'


select @x.exist('//Param[@Name="UserId"]')

   SELECT
	    Param1.query('.').exist('/Param[(@Name cast as xs:string?) eq xs:string("UserId")]'),
	    Param1.query('.')
    FROM (select 1 as id, @x as Params) tq
      CROSS APPLY tq.Params.nodes(N'(/Xml/Param)') AS T(Param1)
    WHERE
      tq.id = 1
12 ноя 15, 16:39    [18407343]     Ответить | Цитировать Сообщить модератору
 Re: Разница использования xml  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1712
в данном случае exist сработает вот так
   SELECT
	    Param1.query('.').exist('/Param[(@Name cast as xs:string?) eq xs:string("UserId")]'),
	    Param1.exist('@Name="UserId"')
    FROM (select 1 as id, @x as Params) tq
      CROSS APPLY tq.Params.nodes(N'(/Xml/Param)') AS T(Param1)
    WHERE
      tq.id = 1
12 ноя 15, 16:41    [18407356]     Ответить | Цитировать Сообщить модератору
 Re: Разница использования xml  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1820
felix_ff
в данном случае exist сработает вот так
   SELECT
	    Param1.query('.').exist('/Param[(@Name cast as xs:string?) eq xs:string("UserId")]'),
	    Param1.exist('@Name="UserId"')
    FROM (select 1 as id, @x as Params) tq
      CROSS APPLY tq.Params.nodes(N'(/Xml/Param)') AS T(Param1)
    WHERE
      tq.id = 1

Если записать Param1.exist('@Name="BlaBlaBla"') тоже вернет 1, а надо 0.

А как узнать как выглядит сегмент который возвращает nodes ?

P.S. в xQuery я не силен
12 ноя 15, 17:38    [18407853]     Ответить | Цитировать Сообщить модератору
 Re: Разница использования xml  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1712
X-Cite
felix_ff
в данном случае exist сработает вот так
   SELECT
	    Param1.query('.').exist('/Param[(@Name cast as xs:string?) eq xs:string("UserId")]'),
	    Param1.exist('@Name="UserId"')
    FROM (select 1 as id, @x as Params) tq
      CROSS APPLY tq.Params.nodes(N'(/Xml/Param)') AS T(Param1)
    WHERE
      tq.id = 1

Если записать Param1.exist('@Name="BlaBlaBla"') тоже вернет 1, а надо 0.

А как узнать как выглядит сегмент который возвращает nodes ?

P.S. в xQuery я не силен



Param1.query('.')
12 ноя 15, 17:41    [18407873]     Ответить | Цитировать Сообщить модератору
 Re: Разница использования xml  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1712
X-Cite,

накосячил скобки забыл условные

DECLARE @x XML
SET @x = '<Xml>
              <Param Name="UserId" Type="INT">54129</Param>
          </Xml>'

SELECT
	 Param1.query('.').exist('/Param[(@Name cast as xs:string?) eq xs:string("UserId")]'),
	 Param1.exist('.[@Name="UserId45"]'),
	 Param1.query('.')
FROM (SELECT 1 AS ID, @x AS Params) tq
    CROSS APPLY tq.Params.nodes(N'(/Xml/Param)') AS T(Param1)
WHERE tq.ID = 1
12 ноя 15, 17:45    [18407917]     Ответить | Цитировать Сообщить модератору
 Re: Разница использования xml  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1820
felix_ff
X-Cite
пропущено...

Если записать Param1.exist('@Name="BlaBlaBla"') тоже вернет 1, а надо 0.

А как узнать как выглядит сегмент который возвращает nodes ?

P.S. в xQuery я не силен



Param1.query('.')

Ну так возвращает то что надо
<Param Name="UserId" Type="INT">54129</Param>

но применяя exist к Param1.query('.') я получаю что есть строка с атрибутом Name и значением в нем UserId
а применяя exist к Param1 получают что нет.
Вот я хочу понять разницу...
12 ноя 15, 17:47    [18407926]     Ответить | Цитировать Сообщить модератору
 Re: Разница использования xml  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1712
X-Cite,

Param1.exist('/Param[(@Name cast as xs:string?) eq xs:string("UserId")]')


применяя этот код для такого узла:
<Param Name="UserId" Type="INT">54129</Param>


вы пытаетесь найти узел Param в текущем узле Param а в данный момент у вас узел Param не содержит дочерних узлов, только текст 54129
12 ноя 15, 17:51    [18407959]     Ответить | Цитировать Сообщить модератору
 Re: Разница использования xml  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1820
Спасибо.... почитал еще на википедии про xPath немного с вашими комментариями стало понятно...
12 ноя 15, 17:54    [18407994]     Ответить | Цитировать Сообщить модератору
 Re: Разница использования xml  [new]
invm
Member

Откуда: Москва
Сообщений: 9683
X-Cite
Вот я хочу понять разницу...
declare @x xml = '<Xml>
  <Param Name="UserId" Type="INT">54129</Param>
</Xml>';

select
 Param1.query('.'),
 Param1.query('.').exist('/Param[@Name = "UserId"]'),
 Param1.query('/'),
 Param1.exist('/Param[@Name = "UserId"]'),
 Param1.exist('/Xml/Param[@Name = "UserId"]')
from
 @x.nodes(N'(/Xml/Param)') AS T(Param1);
12 ноя 15, 18:06    [18408076]     Ответить | Цитировать Сообщить модератору
 Re: Разница использования xml  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1820
А можно динамически указать значение?
Например:
DECLARE @x XML
SET @x = '<Xml>
              <Param Name="UserId" Type="INT">54129</Param>
          </Xml>'

DECLARE
	@User INT = 54129

SELECT
	 Param1.exist('.[.=54129]')
FROM (SELECT 1 AS ID, @x AS Params) tq
    CROSS APPLY tq.Params.nodes(N'(/Xml/Param)') AS T(Param1)
WHERE tq.ID = 1

только вместо 54129 указать @User т.к. на вход значение может быть разным
12 ноя 15, 18:07    [18408086]     Ответить | Цитировать Сообщить модератору
 Re: Разница использования xml  [new]
invm
Member

Откуда: Москва
Сообщений: 9683
X-Cite
только вместо 54129 указать @User
https://msdn.microsoft.com/ru-ru/library/ms188254(v=sql.120).aspx
12 ноя 15, 18:17    [18408141]     Ответить | Цитировать Сообщить модератору
 Re: Разница использования xml  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1820
Спасибо, то что надо..
Но вот вопрос.. стоит ли доверять планам?
Xml та же.
Был запрос:
    SELECT
      1
    FROM
      job.TaskQueue AS tq
      CROSS APPLY tq.Params.nodes(N'(/Xml/Param)') AS T(Param1)
    WHERE
      Param1.value(N'@Name', N'NVARCHAR(MAX)') = N'UserId' AND
      Param1.value(N'.', N'INT') = @IdU

Показал много CONVERT_IMPLICIT почитал про value что так и есть, она любит это делать и если надо фильтровать, то лучше exist.
Переписал запрос в виде:
    SELECT
      1
    FROM
      job.TaskQueue AS tq
      CROSS APPLY tq.Params.nodes(N'(/Xml/Param)') AS T(Param1)
    WHERE
      Param1.exist(N'.[@Name = "UserId"]') = 1 AND
      Param1.exist(N'.[. = sql:variable("@IdU")]') = 1

CONVERT_IMPLICIT ушли, но план по отношению к предыдущему 53% на 47%
13 ноя 15, 10:12    [18410589]     Ответить | Цитировать Сообщить модератору
 Re: Разница использования xml  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1820
Правда если положить Primary Xml Index на Param (а больше выбрать не дает) то тогда картинка приятнее 14% на 86%
13 ноя 15, 10:17    [18410634]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить