Запрос выбора значений в XML в SQL Server, в таблице смешанных значений - PullRequest
1 голос
/ 08 июля 2019

У меня есть таблица с людьми, которые купили билеты на благотворительное вечернее мероприятие, и таблица содержит подробную информацию о регистрации события, а в XML будет показано, какие гости привезут с собой, а также подробную информацию о диетических требованиях и случайный человек, который может быть инвалидом. Это должно быть перенесено в нашу систему CRM, но в настоящее время это не работает.

Я пытаюсь извлечь некоторые значения из некоторого XML, который находится в столбце нашей таблицы импорта.

Я видел множество примеров запросов к обычным фрагментам XML, но не тогда, когда XML находится внутри таблицы с другими обычными значениями INT и VARCHAR.

Мы используем SQL Server 2014. Я часами гуглял, но не имел ни малейшего представления о том, чтобы составить запрос, который бы объединял их вместе. Или даже если я должен поместить XML-материал во временную таблицу, с которой я мог бы затем выполнить соединение.

Declare @xmlstring xml = '<field_import_admin_event_tickets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
     xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <und is_array="true">
    <item>
      <value>8463</value>
      <revision_id>4763</revision_id>
    </item>
  </und>
</field_import_admin_event_tickets>'

select 
    MainDataCenter.Col.value('(value)[1]', 'varchar(max)') as Name, 
    MainDataCenter.Col.value('(revision_id)[1]', 'varchar(max)') as Value
from 
    @xmlstring.nodes('/field_import_admin_event_tickets/und/item') as MainDataCenter(Col)

^ это будет работать

но мне нужно запросить его вместе с этим: -

SELECT * 
FROM [importtickets].[bcc].[entityform]
WHERE type LIKE '%show%'
  AND createdDATETIME > '2019-03-14'
  AND LEN(CAST(field_import_admin_event_tickets AS VARCHAR(MAX)) ) >1
  -- bodging a way of seeing if XML code exists or not, doesn't seem to work with IS NOT NULL
  AND Jobstatus = 'completed' 

Единственный способ, которым я могу грубо получить значения из XML, - это CAST его в VARCHAR и использование большого количества команд REPLACE, чтобы вырезать теги XML, чтобы получить его до значений. В каждом кусочке XML может быть от 2 до 18 числовых значений

Это мой первый пост в StackOverflow, и я потратил несколько дней на его поиск, поэтому, пожалуйста, будьте осторожны со мной. Благодаря.

2019-07-10 Привет, поэтому я не прояснил это полностью. каждый столбец XML (некоторые из которых являются нулевыми) содержит от 2 до 34 отдельных чисел. Я сделал несколько грубых манипуляций с данными, вставив их в VARCHAR и выполнив множество команд замены, чтобы лучше это понять. это самый большой пример здесь для некоторых XML, 34 целочисленных значения, 17 «значение» и 17 «revision_id» Поэтому я поместил все это в новую таблицу, используя много SUBSTRING. Это грубо, но эффективно, но предполагает, что каждое значение имеет пять цифр (это пока), но мой начальник не заинтересован в этом решении. грубо измельченный XML с использованием CAST для VARCHAR и удалением тегов вручную Мне просто нужно, чтобы каждый набор значений извлекался в каждой строке, чтобы я мог затем выполнить JOIN или подзапрос к ним со строкой или чем-то идентифицируемым. Числа будут относиться к гостю, который приходит на некоторые благотворительные мероприятия, которые будут иметь некоторые атрибуты, такие как диетические требования или инвалидность.

1 Ответ

1 голос
/ 08 июля 2019

Не знаю, если это самый лучший подход к вашей проблеме, но я надеюсь, что я правильно понял ваш вопрос, что вы хотите объединить рабочий запрос с изолированным XML с табличным запросом, где XML это содержимое столбца:

Прежде всего я создаю макет с двумя рядами

DECLARE @mockupTable TABLE(ID INT IDENTITY,SomeOtherValue VARCHAR(100),YourXml XML);
INSERT INTO @mockupTable(SomeOtherValue,YourXml) VALUES
('This is some value in row 1'
,'<field_import_admin_event_tickets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <und is_array="true">
    <item>
      <value>8463</value>
      <revision_id>4763</revision_id>
    </item>
  </und>
</field_import_admin_event_tickets>')

,('This is some value in row 2'
,'<field_import_admin_event_tickets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <und is_array="true">
    <item>
      <value>999</value>
      <revision_id>888</revision_id>
    </item>
  </und>
</field_import_admin_event_tickets>');

- запрос

SELECT t.ID
      ,t.SomeOtherValue
      ,MainDataCenter.Col.value('(value)[1]', 'varchar(max)') as Name 
      ,MainDataCenter.Col.value('(revision_id)[1]', 'varchar(max)') as Value
FROM @mockupTable t
CROSS APPLY t.YourXml.nodes('/field_import_admin_event_tickets/und/item') as MainDataCenter(Col);

Результат

ID  SomeOtherValue               Name   Value
1   This is some value in row 1  8463   4763
2   This is some value in row 2   999    888

Идея вкратце:

APPLY позволяет вызывать табличную функцию построчно. В этом случае мы передаем содержимое столбца (в вашем случае XML) во встроенную функцию .nodes().
Подобно JOIN мы получаем объединенный набор, который добавляет столбцы (и строки) в окончательный набор. Мы можем использовать метод .value() для извлечения фактических значений из XML.

Если это лучший подход? Я не знаю ...

Ваш образец выше показывает только один <item>. .nodes() потребуется для возврата нескольких <item> элементов в производном наборе. С одним <item> это можно сделать проще, используя .value() напрямую ...

...