Выбор всех совпадающих строковых значений из XML

#sql #xml #tsql #parsing #sql-server-2012

#sql #xml #tsql #синтаксический анализ #sql-server-2012

Вопрос:

Мне нужно извлечь все предложения, которые заканчиваются на ‘ ‘, из столбца XML. Текущий запрос, который у меня есть, извлекает только первое предложение.

Вот содержимое XML:

 <file>
  <row>Addendum and/or contract providing additional event details and conditions.  </row>
  <row />
  <row>Special duty officer(s) required for event. There are charges for these services. </row>
  <row />
  <row>Notify Mall Crew of electrical needs for activities. </row>
  <row />
  <row>8’ pedestrian pathway must be maintained on sidewalks throughout event area.~</row>
  <row />
  <row>Provide and maintain access to the Hotel during event.~</row>
  <row />
  <row>Event organizer/sponsor is responsible for cleanup of event area.|</row>
  <row />  
</file>
  

Вы можете видеть, что есть три строки с предложениями, которые заканчиваются на ‘ ‘. Я запускаю этот запрос:

 SELECT b.value('(./row/text())[1]','nvarchar(max)') as [row]
FROM @xmlstr.nodes('/file') AS a(b)
WHERE right(b.value('(./row/text())[1]','nvarchar(max)'), 1) = ' '
  

Но я получаю только первое предложение, и мне нужны все предложения со знаком плюс в конце.

Если бы кто-нибудь мог помочь мне разобраться в этом, я был бы очень благодарен

Заранее благодарю вас.

Ответ №1:

Решение Джона отличное, просто чтобы предложить альтернативу, вы можете вызвать XQuery для проверки последнего символа, как здесь:

 DECLARE @xml XML=N'<file>
  <row>Addendum and/or contract providing additional event details and conditions.  </row>
  <row />
  <row>Special duty officer(s) required for event. There are charges for these services. </row>
  <row />
  <row>Notify Mall Crew of electrical needs for activities. </row>
  <row />
  <row>8’ pedestrian pathway must be maintained on sidewalks throughout event area.~</row>
  <row />
  <row>Provide and maintain access to the Hotel during event.~</row>
  <row />
  <row>Event organizer/sponsor is responsible for cleanup of event area.|</row>
  <row />  
</file>';

SELECT r.value('text()[1]','nvarchar(1000)')
FROM @xml.nodes('/file/row[substring(text()[1],string-length(text()[1]),1)=" "]') A(r);
  

Результат

 Addendum and/or contract providing additional event details and conditions.  
Special duty officer(s) required for event. There are charges for these services. 
Notify Mall Crew of electrical needs for activities. 
  

Комментарии:

1. Вау! Подход xquery имеет 15% пакета плана выполнения против моих 85%. Я снова узнал что-то новое. 1

2. @JohnCappelletti Действительно так много? Не ожидал этого… Ваш может быть улучшен с помощью text()[1] вместо . и /file/row вместо file/* . Кроме того, я бы ожидал, что RIGHT(REVERSE(),1) это будет быстрее, чем LIKE '% ' … Или SUBSTRING для получения последнего символа, как указано выше в XQuery… Тем не менее, спасибо за положительный результат 🙂

3. Никаких изменений в / file / row, но я получил целых ЧЕТЫРЕ процентных пункта с помощью right (…, 1) 🙂

Ответ №2:

Возможно, что-то вроде этого

 SELECT b.value('.','nvarchar(max)') as [row]
 FROM  @xmlstr.nodes('file/*') AS a(b)
WHERE  b.value('.','nvarchar(max)') like '% '
  

ВОЗВРАТ

 row
Addendum and/or contract providing additional event details and conditions.  
Special duty officer(s) required for event. There are charges for these services. 
Notify Mall Crew of electrical needs for activities.