Столбец XML SQL Server - Результат без Concat - PullRequest
1 голос
/ 26 июля 2011

В моей базе данных SQL Server есть столбец xml, в котором есть записи в следующем формате

<items>
<item>
      <data alias="Number">123N</data> 
      <data alias="Description">4 sq.mm Feed Through Terminal block in Grey colour</data>   
      <data alias="Standard Packing Quantity">100</data> 
 </item>
 <item>
      <data alias="Number">234N</data> 
      <data alias="Description">Toy</data> 
      <data alias="Standard Packing Quantity">100</data> 
 </item>
 <item>
      <data alias="Number">579N</data> 
      <data alias="Description">Doll</data> 
      <data alias="Standard Packing Quantity">100</data> 
 </item>
 <item>
      <data alias="Catalouge Number">234</data> 
      <data alias="Description">Vehicle</data> 
      <data alias="Standard Packing Quantity">324234</data> 
 </item>
 </items>

Итак, для извлечения данных я использую:


SELECT 
       CatalogueNo,Description,StdPackingQty 
       from
       (select
 CAST(xml as xml).query('//data alias=''Description'']').value('.','nvarchar(225)')   [Description],   
 CAST(xml as xml).query('//data [@alias=''Catalouge Number'']')
.value('.','nvarchar(225)')[CatalogueNo],  
 CAST(xml as xml).query('//data [@alias=''Standard Packing Quantity'']').value('.','nvarchar(225)')[StdPackingQty]
        from [dbo].[cmsContentXml] )as hierarchy
Where CatalogueNo is not null

Проблема, с которой я сталкиваюсь, заключается в том, что извлекаемые данные объединяются. Мне нужны данные в отдельных строках для каждого элемента, поэтому данные должны быть в 3 столбцы и 4 строки.

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

Ответы [ 2 ]

0 голосов
/ 27 июля 2011

Если вы знаете, что порядок ваших элементов всегда одинаков, вы можете использовать position(), чтобы получить значения:

select X.N.value('data[1]', 'nvarchar(255)') as Number,
       X.N.value('data[2]', 'nvarchar(255)') as Descritpion,
       X.N.value('data[3]', 'nvarchar(255)') as Quanatity
from @T as T
  cross apply T.XMLColumn.nodes('/items/item') as X(N)

В противном случае вам нужно получить значение, используя alias. Ваша четвертая строка имеет псевдоним "Catalouge Number", который отличается от других строк, поэтому вы можете использовать его как отдельный столбец:

select X.N.value('data[@alias="Number"][1]', 'nvarchar(255)') as Number,
       X.N.value('data[@alias="Catalouge Number"][1]', 'nvarchar(255)') as CatalougeNumber,
       X.N.value('data[@alias="Description"][1]', 'nvarchar(255)') as Descritpion,
       X.N.value('data[@alias="Standard Packing Quantity"][1]', 'nvarchar(255)') as Quanatity
from @T as T
  cross apply T.XMLColumn.nodes('/items/item') as X(N)

Или вы можете объединить два в одном столбце:

select X.N.value('data[@alias=("Number","Catalouge Number")][1]', 'nvarchar(255)') as Number,
       X.N.value('data[@alias="Description"][1]', 'nvarchar(255)') as Descritpion,
       X.N.value('data[@alias="Standard Packing Quantity"][1]', 'nvarchar(255)') as Quanatity
from @T as T
  cross apply T.XMLColumn.nodes('/items/item') as X(N)

Ваше предложение where может быть добавлено к таким запросам:

where X.N.exist('data[@alias="Catalouge Number"]') = 1  

Или, если вы хотите проверить оба псевдонима номера:

where X.N.exist('data[@alias=("Number","Catalouge Number")]') = 1  

Данные испытаний:

declare @T table(XMLColumn xml)
insert into @T values
('<items>
<item>
      <data alias="Number">123N</data> 
      <data alias="Description">4 sq.mm Feed Through Terminal block in Grey colour</data>   
      <data alias="Standard Packing Quantity">100</data> 
 </item>
 <item>
      <data alias="Number">234N</data> 
      <data alias="Description">Toy</data> 
      <data alias="Standard Packing Quantity">100</data> 
 </item>
 <item>
      <data alias="Number">579N</data> 
      <data alias="Description">Doll</data> 
      <data alias="Standard Packing Quantity">100</data> 
 </item>
 <item>
      <data alias="Catalouge Number">234</data> 
      <data alias="Description">Vehicle</data> 
      <data alias="Standard Packing Quantity">324234</data> 
 </item>
 </items>
')

Edit:

Я вижу, что вы преобразовали свой столбец XML в XML. В этом нет необходимости, если столбец уже имеет тип данных XML, поэтому, я думаю, у вас есть varchar (max) или что-то еще там. Если это так, вам нужно сделать так, чтобы привести XML к перед применением функции .nodes():

select X.N.value('data[@alias=("Number","Catalouge Number")][1]', 'nvarchar(255)') as Number,
       X.N.value('data[@alias="Description"][1]', 'nvarchar(255)') as Descritpion,
       X.N.value('data[@alias="Standard Packing Quantity"][1]', 'nvarchar(255)') as Quanatity
from @T as T
  cross apply (select cast(XMLColumn as xml)) as X1(XMLColumn)
  cross apply X1.XMLColumn.nodes('/items/item') as X(N)
where X.N.exist('data[@alias=("Number","Catalouge Number")]') = 1   

Редактировать 2

select xml.value('data[@alias=("Number","Catalouge Number")][1]', 'nvarchar(255)') as Number,
       xml.value('data[@alias="Description"][1]', 'nvarchar(255)') as Descritpion,
       xml.value('data[@alias="Standard Packing Quantity"][1]', 'nvarchar(255)') as Quanatity 
from [dbo].[cmsContentXml] as Hierarchy 
  cross apply (select cast(xml as xml)) as X1(xml) 
  cross apply X1.xml.nodes('/items/item') as xml(N) 
where xml.N.exist('data[@alias=("Number","Catalouge Number")]')=1 
0 голосов
/ 26 июля 2011

Вы можете использовать Cross Apply, чтобы разбить XML на отдельные строки данных и извлечь данные из них:

SELECT 
    CatalogueNo,Description,StdPackingQty 
from (
    select 
        i.value('data[@alias="Description"][1]','nvarchar(225)') [Description],
        i.value('data[@alias="Catalouge Number"][1]','nvarchar(225)') [CatalogueNo],
        i.value('data[@alias="Standard Packing Quantity"][1]','nvarchar(225)') [StdPackingQty]
    from [Connectwell].[dbo].[cmsContentXml]
    cross apply xml.nodes('/items/item') x(i)
) as hierarchy 
--Where CatalogueNo is not null  

Примечание. В конце я извлек предложение where, как оно будетуменьшите вас до одной строки, тогда как в качестве состояния вопроса вы хотите получить 4 строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...