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

Откуда:
Сообщений: 1195
Всем привет!

Есть таблица с текстовыми полями description, data1, data2, ..., data8

Подскажите, как построить запрос FOR XML, чтобы получить такой XML:
<Root>
  <Descriptions>
    <Item name="description">Description</Item>
  </Descriptions>
  <Specifications>
    <Item name="data1" value="Specification" />
    <Item name="data2" value="Specification" />
    <Item name="data3" value="Specification" />
    <Item name="data4" value="Specification" />
    <Item name="data5" value="Specification" />
    <Item name="data6" value="Specification" />
    <Item name="data7" value="Specification" />
    <Item name="data8" value="Specification" />
  </Specifications>
</Root>

Отдельно для того и другого получается, а вместе что-то никак.
Т.е. как объединить эти 2 запроса?
SELECT 1 as Tag,
       NULL as Parent,
       NULL as [Descriptions!1],
	   NULL as [Item!2!name],
       NULL as [Item!2!name!ELEMENT]
FROM   temp.ProductXMLTest
WHERE product_id = 'bf82617c-240d-4f77-a190-a7d5bb251268'
UNION
SELECT  2 as Tag,
        1 as Parent,
        NULL,
	    'description', 
        description
FROM   temp.ProductXMLTest
FOR XML EXPLICIT, ROOT('Root')

и

SELECT 1 as Tag,
       NULL as Parent,
       NULL as [Specifications!1],
       NULL as [Item!2!name],
       NULL as [Item!2!value]
FROM   temp.ProductXMLTest
WHERE product_id = 'bf82617c-240d-4f77-a190-a7d5bb251268'
UNION
SELECT  2 as Tag,
        1 as Parent,
	    NULL,
	    'data1', data1
FROM   temp.ProductXMLTest
WHERE product_id = 'bf82617c-240d-4f77-a190-a7d5bb251268'
UNION
SELECT  2 as Tag,
        1 as Parent,
	    NULL,
	    'data2', data2
FROM   temp.ProductXMLTest
WHERE product_id = 'bf82617c-240d-4f77-a190-a7d5bb251268'
UNION
SELECT  2 as Tag,
        1 as Parent,
	    NULL,
	    'data3', data3
FROM   temp.ProductXMLTest
WHERE product_id = 'bf82617c-240d-4f77-a190-a7d5bb251268'
UNION
SELECT  2 as Tag,
        1 as Parent,
	    NULL,
	    'data4', data4
FROM   temp.ProductXMLTest
WHERE product_id = 'bf82617c-240d-4f77-a190-a7d5bb251268'
UNION
SELECT  2 as Tag,
        1 as Parent,
	    NULL,
	    'data5', data5
FROM   temp.ProductXMLTest
WHERE product_id = 'bf82617c-240d-4f77-a190-a7d5bb251268'
UNION
SELECT  2 as Tag,
        1 as Parent,
	    NULL,
	    'data6', data6
FROM   temp.ProductXMLTest
WHERE product_id = 'bf82617c-240d-4f77-a190-a7d5bb251268'
UNION
SELECT  2 as Tag,
        1 as Parent,
	    NULL,
	    'data7', data7
FROM   temp.ProductXMLTest
WHERE product_id = 'bf82617c-240d-4f77-a190-a7d5bb251268'
UNION
SELECT  2 as Tag,
        1 as Parent,
	    NULL,
	    'data8', data8
FROM   temp.ProductXMLTest
WHERE product_id = 'bf82617c-240d-4f77-a190-a7d5bb251268'
FOR XML EXPLICIT, ROOT('Root')
22 окт 09, 19:58    [7826528]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по FOR XML.  [new]
tsyoma
Member

Откуда:
Сообщений: 31
как то так:
SELECT  (
         SELECT 1 as Tag
              , NULL as Parent
              , NULL as [Descriptions!1]
              , NULL as [Item!2!name]
              , NULL as [Item!2!name!ELEMENT]
         FROM   temp.ProductXMLTest
         WHERE  product_id = 'bf82617c-240d-4f77-a190-a7d5bb251268'
         UNION
         SELECT 2 as Tag
              , 1 as Parent
              , NULL
              , 'description'
              , description
         FROM   temp.ProductXMLTest
        FOR
         XML EXPLICIT
           , ROOT('Root')
        ) AS [Descriptions]
      , (
         SELECT 1 as Tag
              , NULL as Parent
              , NULL as [Specifications!1]
              , NULL as [Item!2!name]
              , NULL as [Item!2!value]
         FROM   temp.ProductXMLTest
         WHERE  product_id = 'bf82617c-240d-4f77-a190-a7d5bb251268'
		UNION
		....
        ) AS [Specifications]
FOR     XML PATH('root') 
(неоднократно обсуждалось пользуйте поиск)
23 окт 09, 10:37    [7827804]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по FOR XML.  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
Jovanny,

Вы уверены, что надо использовать именно UNION, а не UNION ALL?
23 окт 09, 10:53    [7827973]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по FOR XML.  [new]
Jovanny
Member

Откуда:
Сообщений: 1195
Спасибо, tsyoma, похоже на то, что мне нужно.

To Senya_L.
В моём случае безразницы.
23 окт 09, 11:12    [7828191]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по FOR XML.  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31200
Jovanny
To Senya_L.
В моём случае безразницы.
Так зачем тогда лишнюю работу серверу давать???

По умолчанию нужно писать всегда UNION ALL, если есть веские причины, то, подумав и не найдя другого выхода, писать UNION.
23 окт 09, 11:19    [7828256]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по FOR XML.  [new]
Jovanny
Member

Откуда:
Сообщений: 1195
В общем, логично. Спасибо, что указали.
23 окт 09, 12:28    [7828938]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по FOR XML.  [new]
Jovanny
Member

Откуда:
Сообщений: 1195
tsyoma
как то так:
SELECT  (
         SELECT 1 as Tag
              , NULL as Parent
              , NULL as [Descriptions!1]
              , NULL as [Item!2!name]
              , NULL as [Item!2!name!ELEMENT]
         FROM   temp.ProductXMLTest
         WHERE  product_id = 'bf82617c-240d-4f77-a190-a7d5bb251268'
         UNION
         SELECT 2 as Tag
              , 1 as Parent
              , NULL
              , 'description'
              , description
         FROM   temp.ProductXMLTest
        FOR
         XML EXPLICIT
           , ROOT('Root')
        ) AS [Descriptions]
      , (
         SELECT 1 as Tag
              , NULL as Parent
              , NULL as [Specifications!1]
              , NULL as [Item!2!name]
              , NULL as [Item!2!value]
         FROM   temp.ProductXMLTest
         WHERE  product_id = 'bf82617c-240d-4f77-a190-a7d5bb251268'
		UNION
		....
        ) AS [Specifications]
FOR     XML PATH('root') 
(неоднократно обсуждалось пользуйте поиск)


Фигня получается - в подзапросе UNION использовать нельзя.
Придётся, наверное, через UDF.
23 окт 09, 13:29    [7829491]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по FOR XML.  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381

> Фигня получается - в подзапросе UNION использовать нельзя.
> Придётся, наверное, через UDF.

можно. там сообщение об ошибке просто внимательно надо прочитать и понять.
читать сообщение на английском - если у вас сообщения на русском выводятся,
переключите язык - русский перевод абсолютно не в тему.

надо только уметь его готовить:
SELECT  (
         select * from (
          SELECT 1 as Tag
               , NULL as Parent
               , NULL as [Descriptions!1]
               , NULL as [Item!2!name]
               , NULL as [Item!2!name!ELEMENT]
          FROM   temp.ProductXMLTest
          WHERE  product_id = 'bf82617c-240d-4f77-a190-a7d5bb251268'
          UNION
          SELECT 2 as Tag
               , 1 as Parent
               , NULL
               , 'description'
               , description
          FROM   temp.ProductXMLTest
         ) t
         FOR
          XML EXPLICIT
            , ROOT('Root')
            , type
         ) AS [Descriptions]
FOR     XML PATH('root')

зы: раз уж у вас 2005-ый - не проще ли все через path() прописать?

Posted via ActualForum NNTP Server 1.4

23 окт 09, 13:39    [7829555]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по FOR XML.  [new]
Jovanny
Member

Откуда:
Сообщений: 1195
daw
зы: раз уж у вас 2005-ый - не проще ли все через path() прописать?


Хотелось бы, но не позволяет элементы с одинаковыми именами атрибутов вставлять.

Вот это, например, работает:

SELECT     'description' 'Item/@name',  description 'Item'
FROM         temp.ProductXMLTest 
WHERE product_id = 'bf82617c-240d-4f77-a190-a7d5bb251268'
FOR XML PATH ('Descriptions')
а на это ругается

SELECT     'description' 'Item/@name',  description 'Item',
           'data1' 'Item/@name',  data1 'Item'
FROM         temp.ProductXMLTest 
WHERE product_id = 'bf82617c-240d-4f77-a190-a7d5bb251268'
FOR XML PATH ('Descriptions')

Msg 6852, Level 16, State 1, Line 1
Attribute-centric column 'Item/@name' must not come after a non-attribute-centric sibling in XML hierarchy in FOR XML PATH.
23 окт 09, 13:50    [7829637]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по FOR XML.  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381

> Хотелось бы, но не позволяет элементы с одинаковыми именами атрибутов
> вставлять.

да все он позволяет - запрос только надо правильно написать.
что у вас за данные-то в вашей таблице temp.ProductXMLTest
(лучше скрипт приведите с созданием таблицы и заполнением
данными) и по какому принципу из них xml должен строиться?
а то, я что-то так и не врубаюсь никак. <Specification> прямо так
и должно составляться, или вы упростили просто что-то?

Posted via ActualForum NNTP Server 1.4

23 окт 09, 13:58    [7829704]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по FOR XML.  [new]
tsyoma
Member

Откуда:
Сообщений: 31
daw,
+1
23 окт 09, 14:19    [7829866]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по FOR XML.  [new]
Jovanny
Member

Откуда:
Сообщений: 1195
CREATE TABLE ProductXMLTest(
	product_id uniqueidentifier NOT NULL,
	description varchar(max) NULL,
	data1 varchar(255) NULL,
	data2 varchar(255) NULL,
	data3 varchar(255) NULL,
	data4 varchar(255) NULL,
	data5 varchar(255) NULL,
	data6 varchar(255) NULL,
	data7 varchar(255) NULL,
	data8 varchar(255) NULL
)
GO
INSERT INTO temp.ProductXMLTest
                      (product_id, description, data1, data2, data3, data4, data5, data6, data7, data8)
VALUES     ('bf82617c-240d-4f77-a190-a7d5bb251268', 'Some description',
'Some data1', 
'Some data2', 
'Some data3',
'Some data4',
'Some data5',
'Some data6',
'Some data7',
'Some data8')


Вот структура и образец данных.

Помогите мне получить вот такой XML:

<Root>
  <Descriptions>
    <Item name="description">Description</Item>
  </Descriptions>
  <Specifications>
    <Item name="data1" value="Specification" />
    <Item name="data2" value="Specification" />
    <Item name="data3" value="Specification" />
    <Item name="data4" value="Specification" />
    <Item name="data5" value="Specification" />
    <Item name="data6" value="Specification" />
    <Item name="data7" value="Specification" />
    <Item name="data8" value="Specification" />
  </Specifications>
</Root>
23 окт 09, 14:22    [7829894]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по FOR XML.  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381

так устроит?
select
   'description' as [Descriptions/Item/@name]
   , description as [Descriptions/Item/text()]
   , (select name as [Item/@name], value as [Item/@value]
      from (select 'data1' as name, data1 as value
            union all
            select 'data2', data2
            union all
            select 'data3', data3
            union all
            select 'data4', data4
            union all
            select 'data5', data5
            union all
            select 'data6', data6
            union all
            select 'data7', data7
            union all
            select 'data8', data8
           ) t
      for xml path(''), type
     ) [Specification]

from ProductXMLTest
for xml path(''), root('Root')


Posted via ActualForum NNTP Server 1.4

23 окт 09, 14:32    [7829989]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по FOR XML.  [new]
Jovanny
Member

Откуда:
Сообщений: 1195
daw,

спасибо, то, что надо.
23 окт 09, 14:36    [7830030]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по FOR XML.  [new]
Jovanny
Member

Откуда:
Сообщений: 1195
daw, не поможете ли в ещё одном вопросе?
Мне нужно добавить к корню пространства имён, но запрос:

WITH XMLNAMESPACES ('http://www.w3.org/2001/XMLSchema-instance' as xsi,
'http://www.w3.org/2001/XMLSchema' as xsd, DEFAULT 'http://aaa.com/ProductDescriptionSchema.xsd')
select
   'description' as [Descriptions/Item/@name]
   , description as [Descriptions/Item/text()]
   , (select name as [Item/@name], value as [Item/@value]
      from (select 'data1' as name, data1 as value
            union all
            select 'data2', data2
            union all
            select 'data3', data3
            union all
            select 'data4', data4
            union all
            select 'data5', data5
            union all
            select 'data6', data6
            union all
            select 'data7', data7
            union all
            select 'data8', data8
           ) t
      for xml path(''), type
     ) [Specifications]
from temp.ProductXMLTest
for xml path(''), root('Root');
добавляет их к каждому элементу.
23 окт 09, 17:36    [7831569]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по FOR XML.  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381

> Мне нужно добавить к корню пространства имён, но запрос:
> добавляет их к каждому элементу.

проще всего - так:
select
   cast(
   '<Root xmlns="http://aaa.com/ProductDescriptionSchema.xsd"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   >' +
   (
   select
      'description' as [Descriptions/Item/@name]
      , description as [Descriptions/Item/text()]
      , (select name as [Item/@name], value as [Item/@value]
         from (select 'data1' as name, data1 as value
               union all
               select 'data2', data2
               union all
               select 'data3', data3
               union all
               select 'data4', data4
               union all
               select 'data5', data5
               union all
               select 'data6', data6
               union all
               select 'data7', data7
               union all
               select 'data8', data8
              ) t
         for xml path(''), type
        ) [Specifications]
   from ProductXMLTest
   for xml path('')
   ) + '</Root>' as xml)

Posted via ActualForum NNTP Server 1.4

26 окт 09, 09:28    [7836786]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по FOR XML.  [new]
Jovanny
Member

Откуда:
Сообщений: 1195
Спасибо! :-)
26 окт 09, 10:10    [7836942]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить