SQL Запрос к серверу на xml типе данных для значения, присутствующего в теге - PullRequest
0 голосов
/ 14 апреля 2020

У меня есть SQL Серверная база данных с таблицей FormTable, которая имеет столбец DataXML в формате xml.

Данные в этом столбце XML выглядят следующим образом:

<Form>
  <Section name="metric1">
    <InputNumber type="int" min="0" max="100" title="Length of the box.">
      <Value>50</Value>
    </InputNumber>
    <PickList title="Is the shape square?">
      <Option selected="true">Yes</Option>
      <Option>No</Option>
      <Option>No standard shape</Option>
    </PickList>
  </Section>
</Form>

XML содержит еще много тегов InputNumber и PickList. Я написал этот запрос для получения необходимых данных. Возвращает:

  • категория - номер строки - заголовок
  • метрика1 - 1 - длина поля
  • метрика1 - 2 - это поле квадрат формы?
SELECT 
    tbl.FormId,
    category = c.value(''../../@name'', ''VARCHAR(max)''),
    ROW_NUMBER() OVER (order by (select 1)) as RowNumber,
    c.value(''../@title'',''VARCHAR(max)'') AS [title]
FROM 
    FormTable AS tbl
CROSS APPLY 
    tbl.DataXML.nodes(''/Form[1]/Section/*[local-name() = ("PickList", "InputNumber"")]/*[local-name() = ("Value", "Option")]'') AS t(c)
WHERE
    Formid = '10';

Теперь я хочу вернуть еще один столбец с именем value, и результат должен выглядеть следующим образом:

  • category - номер строки - title - - значение
  • метрика1 - 1 - Длина коробки - 50
  • метрика1 - 2 - Квадрат формы? - Да

Как получить столбец значений?

1 Ответ

0 голосов
/ 14 апреля 2020

Если вы хотите значение (внутренний текст) текущего элемента, просто используйте c.value('.', 'VARCHAR(max)') as [value], например:

create table FormTable (
  FormID int not null,
  DataXML xml
);

insert FormTable (FormID, DataXML) values
(10, N'<Form>
  <Section name="metric1">
    <InputNumber type="int" min="0" max="100" title="Length of the box.">
      <Value>50</Value>
    </InputNumber>
    <PickList title="Is the shape square?">
      <Option selected="true">Yes</Option>
      <Option>No</Option>
      <Option>No standard shape</Option>
    </PickList>
  </Section>
</Form>');

SELECT 
    tbl.FormId,
    category = c.value('../../@name', 'VARCHAR(max)'),
    ROW_NUMBER() OVER (order by t.c) as RowNumber,
    c.value('../@title',  'VARCHAR(max)') AS [title],
    c.value('.', 'VARCHAR(max)') as [value]
FROM 
    FormTable AS tbl
CROSS APPLY 
    tbl.DataXML.nodes('/Form[1]/Section/*[local-name() = ("PickList", "InputNumber")]/*[local-name() = ("Value", "Option")]') AS t(c)
WHERE
    FormID = 10;

, что дает результат:

FormId  category  RowNumber  title                 value
10      metric1   1          Length of the box.    50
10      metric1   2          Is the shape square?  Yes
10      metric1   3          Is the shape square?  No
10      metric1   4          Is the shape square?  No standard shape
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...