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

Откуда: USSR
Сообщений: 215
Привет читающему.

Задача - Есть три селекта (которые возвращают XML через FOR XML), необходимо выгрузить результаты этих селектов в один XML файл, и при этом прописать пару тегов в заглавье документа (кодировка и все такое). После это дело выгружается в с помощью BCP в XML файл в джобе.

Селекты разные, т.е. выборка происходит с разных таблиц.
Каждый селект возвращает результат в тегах <record></record>. Может быть и такое, что один из селектов может вернуть NULL.

Посоветуйте пожалуйста, как склеить результаты этих трех селектов?
Заранее спасибо.
14 июл 09, 09:35    [7411637]     Ответить | Цитировать Сообщить модератору
 Re: Склеить XML (concatenating XML)  [new]
Ennor Tiegael
Member

Откуда:
Сообщений: 3205
Не проверял, но как-то так:
select (select 1 as [X] for xml auto, type) as [Query_1],
  (select 2 as [Y] for xml auto, type) as [Query_2],
  (select 3 as [Z] for xml auto, type) as [Query_3]
for xml path(''), type;
14 июл 09, 09:41    [7411659]     Ответить | Цитировать Сообщить модератору
 Re: Склеить XML (concatenating XML)  [new]
Zeda
Member

Откуда: USSR
Сообщений: 215
Ennor Tiegael
Не проверял, но как-то так:
select (select 1 as [X] for xml auto, type) as [Query_1],
  (select 2 as [Y] for xml auto, type) as [Query_2],
  (select 3 as [Z] for xml auto, type) as [Query_3]
for xml path(''), type;


Спасибо, вроде как почти то что я хочу..
Вот что я получаю:
SELECT 
	          (SELECT 1 AS [X] FOR XML PATH,TYPE)
                 ,(SELECT 2 AS [Y] FOR XML PATH,TYPE)
                 ,(SELECT 3 AS [Z] FOR XML PATH,TYPE)
       FOR XML PATH(''),TYPE;  

это дает вот такое:
<row>
         <X>1</X>
</row>
<row>
        <Y>2</Y>
</row>
<row>
        <Z>3</Z>
</row>

Мне нужно как то убрать теги "<row></row>" (в моем случае это название колонок для селктов - мне это не нужно т.к. запросы уже возвращаются с тегами <record></record>).

Короче, как то надо получить вот такое:
         <X>1</X>
         <Y>2</Y>
         <Z>3</Z>
14 июл 09, 10:02    [7411769]     Ответить | Цитировать Сообщить модератору
 Re: Склеить XML (concatenating XML)  [new]
PaulYoung
Member

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

как вариант, не претендующий на оптимальность
IF object_id('tempdb..#X') IS NOT NULL
  DROP TABLE #X

DECLARE @idoc int, @xml XML, @s varchar(max)

SET @xml =
(
select (select 1 as [X] for xml path(''), type) as [Q1],
  (select 2 as [Y] for xml path(''), type) as [Q2],
  (select 3 as [Z] for xml path(''), type) as [Q3]
for xml raw
)

EXEC sp_xml_preparedocument @idoc OUTPUT, @xml

SELECT * INTO #X FROM OPENXML(@idoc, '/row', 1)

EXEC sp_xml_removedocument @idoc

SET @s = ''

SELECT @s = @s + '<' + t2.localname + '>' + cast(t1.text AS  nvarchar(max)) + '</' + t2.localname + '>'
FROM #X t1
JOIN #X t2 ON t1.parentid = t2.id
WHERE t1.text IS NOT NULL

SET @xml = @s

SELECT @xml
14 июл 09, 10:49    [7412078]     Ответить | Цитировать Сообщить модератору
 Re: Склеить XML (concatenating XML)  [new]
daw
Member

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

> Спасибо, вроде как почти то что я хочу..
> Вот что я получаю:
>
> SELECT
> (SELECT *1* AS [X]FOR XML PATH,TYPE)
> ,(SELECT *2* AS [Y]FOR XML PATH,TYPE)
> ,(SELECT *3* AS [Z]FOR XML PATH,TYPE)
> FOR XML PATH(''),TYPE;

гм. а реальный запрос увидеть можно?
потому как, конкретно для этого запроса решение будет:

SELECT
	(SELECT  1  AS  [X] FOR  XML PATH(''),TYPE)
                    ,(SELECT  2  AS  [Y] FOR  XML PATH(''),TYPE)
                    ,(SELECT  3  AS  [Z] FOR  XML PATH(''),TYPE)
          FOR  XML PATH(''),TYPE;

Posted via ActualForum NNTP Server 1.4

14 июл 09, 11:11    [7412245]     Ответить | Цитировать Сообщить модератору
 Re: Склеить XML (concatenating XML)  [new]
Zeda
Member

Откуда: USSR
Сообщений: 215
daw,
Проведу аналогию с примером от микрософта. Примерно такой у меня есть запрос:
use adventureworks
go
SELECT top 4 
       [SalesOrderID]
      ,[RevisionNumber]
      ,[OrderDate]
      ,[DueDate]
      ,[ShipDate]
      ,[Status]      
      ,[ContactID]
	  ,(select AccountNumber as "Ac" , CustomerType as "ctype"  from [AdventureWorks].[Sales].customer c
		where  c.customerId=o.customerid
		for xml path('cuttomer_detail'), type
       )
  FROM [AdventureWorks].[Sales].[SalesOrderHeader] o
for xml raw('record'), elements
Суть тут в том, что этих вложенных селектов (столбцов) много. И таких запросов у меня 3.
Каждый из них возвращает что то типа этого:
<record>
  <SalesOrderID>43659</SalesOrderID>
  <RevisionNumber>1</RevisionNumber>
  <OrderDate>2001-07-01T00:00:00</OrderDate>
  <DueDate>2001-07-13T00:00:00</DueDate>
  <ShipDate>2001-07-08T00:00:00</ShipDate>
  <Status>5</Status>
  <ContactID>378</ContactID>
  <cuttomer_detail>
    <Ac>AW00000676</Ac>
    <ctype>S</ctype>
  </cuttomer_detail>
</record>
........................................
 И т.д
На их базе (запросов) я сделал представление (где то здесь наверно ошибся), столбцами от которого стали результаты этих запросов. Но, при этом столбцам мне пришлось присвоить название (название колонки):
create view myview as 
select 
	(SELECT top 2 [SalesOrderID] ,[RevisionNumber] ,[OrderDate],(select AccountNumber as "Ac" , CustomerType as "ctype"  from [AdventureWorks].[Sales].customer c where  c.customerId=o.customerid for xml path('cuttomer_detail'), type )
     FROM [AdventureWorks].[Sales].[SalesOrderHeader] o
     for xml path('record'), type
     ) as "first_q"
	,(SELECT top 2 [SalesOrderID] ,[RevisionNumber] ,[OrderDate],(select AccountNumber as "Ac" , CustomerType as "ctype"  from [AdventureWorks].[Sales].customer c where  c.customerId=o.customerid for xml path('cuttomer_detail'), type )
      FROM [AdventureWorks].[Sales].[SalesOrderHeader] o
      for xml path('record'), type
     ) as "second_q"
	,(SELECT top 2 [SalesOrderID] ,[RevisionNumber] ,[OrderDate],(select AccountNumber as "Ac" , CustomerType as "ctype"  from [AdventureWorks].[Sales].customer c where  c.customerId=o.customerid for xml path('cuttomer_detail'), type )
      FROM [AdventureWorks].[Sales].[SalesOrderHeader] o
      for xml path('record'), type
     ) as "third_q"
Потом уже забираю с этой вющки:
select getdate() as "generation_date", cast(rand() as int) as "id",* from myview
for xml raw('records'), elements
И вот что получаю:
<records>
  <generation_date>2009-07-14T22:20:02.687</generation_date>
  <id>0</id>
 [b] <first_q>[/b]
    <record>
      <SalesOrderID>43659</SalesOrderID>
      <RevisionNumber>1</RevisionNumber>
      <OrderDate>2001-07-01T00:00:00</OrderDate>
      <cuttomer_detail>
        <Ac>AW00000676</Ac>
        <ctype>S</ctype>
      </cuttomer_detail>
    </record>
    <record>
      <SalesOrderID>43660</SalesOrderID>
      <RevisionNumber>1</RevisionNumber>
      <OrderDate>2001-07-01T00:00:00</OrderDate>
      <cuttomer_detail>
        <Ac>AW00000117</Ac>
        <ctype>S</ctype>
      </cuttomer_detail>
    </record>
  </first_q>
 [b]<second_q>[/b] 
    <record>
      <SalesOrderID>43659</SalesOrderID>
      <RevisionNumber>1</RevisionNumber>
      <OrderDate>2001-07-01T00:00:00</OrderDate>
      <cuttomer_detail>
        <Ac>AW00000676</Ac>
        <ctype>S</ctype>
      </cuttomer_detail>
    </record>
    <record>
      <SalesOrderID>43660</SalesOrderID>
      <RevisionNumber>1</RevisionNumber>
      <OrderDate>2001-07-01T00:00:00</OrderDate>
      <cuttomer_detail>
        <Ac>AW00000117</Ac>
        <ctype>S</ctype>
      </cuttomer_detail>
    </record>
  </second_q>
 [b]  <third_q>[/b] 
    <record>
      <SalesOrderID>43659</SalesOrderID>
      <RevisionNumber>1</RevisionNumber>
      <OrderDate>2001-07-01T00:00:00</OrderDate>
      <cuttomer_detail>
        <Ac>AW00000676</Ac>
        <ctype>S</ctype>
      </cuttomer_detail>
    </record>
    <record>
      <SalesOrderID>43660</SalesOrderID>
      <RevisionNumber>1</RevisionNumber>
      <OrderDate>2001-07-01T00:00:00</OrderDate>
      <cuttomer_detail>
        <Ac>AW00000117</Ac>
        <ctype>S</ctype>
      </cuttomer_detail>
    </record>
  </third_q>
</records>

И вот что то не доходит как избавится от этих колонок (First_q, Second_q, third_q).
14 июл 09, 21:23    [7416110]     Ответить | Цитировать Сообщить модератору
 Re: Склеить XML (concatenating XML)  [new]
Zeda
Member

Откуда: USSR
Сообщений: 215
PaulYoung
Zeda,

как вариант, не претендующий на оптимальность

вроде как работает, но при этом удаляет все теги - завтра покажу результат (т.к. нет этого кома рядом)
14 июл 09, 21:27    [7416122]     Ответить | Цитировать Сообщить модератору
 Re: Склеить XML (concatenating XML)  [new]
daw
Member

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

> На их базе (запросов) я сделал представление (где то здесь наверно
> ошибся), столбцами от которого стали результаты этих запросов. Но, при
> этом столбцам мне пришлось присвоить название (название колонки):

название столбцам пришлось давать только потому, что это view.
отсюда вопрос - а оно вам так уж нужно? почему бы сразу нужный
результат не получать?

Posted via ActualForum NNTP Server 1.4

15 июл 09, 08:16    [7416698]     Ответить | Цитировать Сообщить модератору
 Re: Склеить XML (concatenating XML)  [new]
Zeda
Member

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

> На их базе (запросов) я сделал представление (где то здесь наверно
> ошибся), столбцами от которого стали результаты этих запросов. Но, при
> этом столбцам мне пришлось присвоить название (название колонки):

название столбцам пришлось давать только потому, что это view.
отсюда вопрос - а оно вам так уж нужно? почему бы сразу нужный
результат не получать?


Спасибо огромное. Я реально переутомился...
Вот такое дает то что нужно:
SELECT GETDATE() AS "generation_date"
      ,CAST(RAND() AS INT) AS "id"
      ,(
           SELECT TOP 2 [SalesOrderID]
                 ,[RevisionNumber]
                 ,[OrderDate]
                 ,(
                      SELECT AccountNumber AS "Ac"
                            ,CustomerType AS "ctype"
                      FROM   [AdventureWorks].[Sales].[Customer] c
                      WHERE  
                      	  c.CustomerID = o.CustomerID FOR XML PATH('customer_detail'), TYPE
                  )
           FROM   [AdventureWorks].[Sales].[SalesOrderHeader] o
                  FOR XML PATH('record'),TYPE
       ) --as "first_q"
      ,(
           SELECT TOP 2 [SalesOrderID]
                 ,[RevisionNumber]
                 ,[OrderDate]
                 ,(
                      SELECT AccountNumber AS "Ac"
                            ,CustomerType AS "ctype"
                      FROM   [AdventureWorks].[Sales].Customer c
                      WHERE  
                      	  c.CustomerID = o.CustomerID FOR XML PATH('cuttomer_detail'), TYPE
                  )
           FROM   [AdventureWorks].[Sales].[SalesOrderHeader] o
                  FOR XML PATH('record'),TYPE
       ) --as "second_q"
      ,(
           SELECT TOP 2 [SalesOrderID]
                 ,[RevisionNumber]
                 ,[OrderDate]
                 ,(
                      SELECT AccountNumber AS "Ac"
                            ,CustomerType AS "ctype"
                      FROM   [AdventureWorks].[Sales].Customer c
                      WHERE  
                      	  c.CustomerID = o.CustomerID FOR XML PATH('cuttomer_detail'), TYPE
                  )
           FROM   [AdventureWorks].[Sales].[SalesOrderHeader] o
                  FOR XML PATH('record'),TYPE
       ) --as "third_q"
       
       FOR XML RAW('batch'),ELEMENTS 

Возник попутный вопрос:
Значения некоторых полей NULL, и когда я забираю их таким запросом, он мне NULL-ы записывает так:
<ctype />
А мне бы хотелось вот так:
<ctype></ctype>
Есть ли такая возможность?
Спасибо заранее.
15 июл 09, 08:43    [7416756]     Ответить | Цитировать Сообщить модератору
 Re: Склеить XML (concatenating XML)  [new]
daw
Member

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

> Есть ли такая возможность?

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

Posted via ActualForum NNTP Server 1.4

15 июл 09, 08:47    [7416766]     Ответить | Цитировать Сообщить модератору
 Re: Склеить XML (concatenating XML)  [new]
Zeda
Member

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

> Есть ли такая возможность?

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

Спасибо.
Я знаю что нет разницы, просто поинтересовался.
15 июл 09, 09:42    [7416982]     Ответить | Цитировать Сообщить модератору
 Re: Склеить XML (concatenating XML)  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Zeda
Значения некоторых полей NULL, и когда я забираю их таким запросом, он мне NULL-ы записывает так:
<ctype />
А мне бы хотелось вот так:
<ctype></ctype>
Есть ли такая возможность?
dav
нет. потому что, смысла никакого. это ведь одно и то же.
то есть, если для вас есть какая-то разница, значит вы просто
неправильно работаете с xml.
XML совершенно разный. Во втором случае наличествует строковый узел. Парсеры бывают разными. Иногда приходиться и нормализацию делать.
SELECT '' AS ctype FOR XML Path('')
15 июл 09, 14:47    [7419153]     Ответить | Цитировать Сообщить модератору
 Re: Склеить XML (concatenating XML)  [new]
daw
Member

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

> XML совершенно разный. Во втором случае наличествует строковый узел.
> SELECT '' AS ctype FOR XML Path('')

ок. был не прав. получить можно. в sql server оно, действительно,
по-разному хранится.
этот строковый узел, правда, успешно теряется при любом
преобразовании к/из xml. отсюда и моя такая убежденность была.

> Парсеры бывают разными. Иногда приходиться и нормализацию делать.

и это таки-правильно? по крайней мере, в данном конкретном случае
обе записи одинаково - как пустой элемент - должны бы трактоваться.
в рекомендации так написано вродеб.

Posted via ActualForum NNTP Server 1.4

15 июл 09, 16:38    [7420014]     Ответить | Цитировать Сообщить модератору
 Re: Склеить XML (concatenating XML)  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
daw

> Парсеры бывают разными. Иногда приходиться и нормализацию делать.
и это таки-правильно? по рекомендации ...
Не всё йогурты ... :)
Стандарты это одно, а вот реализации это другое. Может программа-клиент капризная, которая будет получать этот XML.
15 июл 09, 19:29    [7421051]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить