2011-07-26 1 views
1

У меня есть столбец XML в моей базе данных SQL Server, которая имеет записи в следующем форматеSQL Server XML Column - результат свободен от Concat

<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 строках.

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

ответ

0

Вы можете использовать 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 строки в качестве результата.

0

Если вы знаете, что порядок ваших элементов всегда одни и те же вы можете использовать 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 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

выберите xml.value ('данные [@alias = ("Number" , "Cataluge Number")] [1] ',' nvarchar (255) ') как Number, xml.value (' data [@ alias = "Описание"] [1] ',' nvarchar (255) ') как Descritpion , XML.value ('data [@ alias = "Standard Packing Quantity"] [1]', 'nvarchar (255)') как Quanatity из [dbo]. [cmsContentXml] как иерархия cross apply (выберите cast (xml as xml)) как X1 (xml) cross применить X1 (xml) .nodes ('/ items/item') как xml (N) где xml.N.exist ('data [@alias = ("Number", "Cataluge Number ")] ') = 1 В столбце в БД загружены данные, поэтому я не могу добавить« объявить таблицу @T (XMLColumn xml) » – Narayana

+0

@Narayana - Вы не должны использовать' @ T'. Вы должны заменить '@ T' тем, что вы вызываете. '@ T' - это то, что я использовал, чтобы продемонстрировать, как вы можете это сделать. –

+0

Спасибо .. это прекрасно работает – Narayana