Я пытаюсь извлечь информацию с помощью SQL из столбца XML, который выглядит следующим образом:
<?xml version = "1.0" encoding = "utf-16"?>
<Advertentie>
<Filter>
<Woninglabels Enabled = "True" Priority = "1">
<Woninglabel Id = "1" Type = "Huishoudgrootte" Enabled = "True" SeqNumber = "1" SortDirection = "DESC" Min = "0" Max = "99" Text = "" />
<Woninglabel Id = "2" Type = "Leeftijd" Enabled = "True" SeqNumber = "2" SortDirection = "DESC" Min = "0" Max = "999" Text = "" />
</Woninglabels>
</Filter>
</Advertentie>
Мне нужна информация о минимальных и максимальных значениях для каждого идентификатора Woninglabel (только что вставлены два, но их более 10). Проблема, с которой я сталкиваюсь, заключается в том, что вся информация находится между двумя "<" ">".
Я попробовал использовать метод .value(), но вскоре столкнулся с проблемой: вся информация находится между двумя этими "<" ">".
select TOP 100 ic,
CAST(ic AS XML).value('(<Advertentie><Filter><Woninglabels Enabled = "True" Priority = "1"><Woninglabel Id = "1" Type = "Huishoudgrootte" Enabled = "True" SeqNumber = "1" SortDirection = "DESC" Min = ")[1]','int(2)') AS Name
from adv
И получил эту ошибку: ошибка
база данных sql на сервере Windows
SQL — это язык, поддерживаемый десятками различных продуктов, даже в Windows. Возможно вы имеете в виду MS SQL Server?
Да, это то, что я имею в виду
Пожалуйста, не используйте изображения, используйте форматирование кода, табличную разметку и текст в кавычках.
Затем исправьте свои теги, включив в них sql-server.
Вам нужно использовать функцию nodes, чтобы уничтожить каждую метку, а затем получить необходимые атрибуты. Здесь полезен метод value, доступ к атрибутам осуществляется с использованием синтаксиса @name. Почему бы не просмотреть документацию Microsoft XML, там это должно быть четко указано. Кстати, не знаю, почему вы думаете, что это неструктурированные данные.
not structured XML вызывает некоторое противоречие, когда речь идет об XML, и ничего не объясняет. По определению XML имеет структуру. То, что вы опубликовали, очень хорошо структурировано: каждый элемент и атрибут имеет конкретное имя вместо ужасного name = "Price" value = "1,234" type = "good_luck_parsing_this". Вы можете использовать OPENXML для его анализа и извлечения атрибутов в виде столбцов, метод .query и XPATH для извлечения определенных частей. Проверьте примеры OPENXML в документации.
Спасибо за помощь @siggemannen. Мне это показалось неструктурированным, но я также не очень знаком с получением данных из xml.
Я углублюсь в это @PanagiotisKanavos, большое спасибо. Также для объяснения структуры этого XML.


Это очень хорошо структурированный XML. Неструктурированный — это что-то вроде name = "Price" value = "1,234" type = "good_luck_parsing_this". Существует несколько способов запроса XML. Вы можете использовать .value для извлечения определенных значений на основе пути XPath..., вы можете использовать query для извлечения элементов в формате XML или использовать .nodes() для извлечения данных в виде набора строк, который может быть частью более крупного запроса.
Если XML был сохранен в переменной, вы могли бы использовать это для извлечения данных метки:
select
a.value('./@Id','int') as Id,
a.value('./@Type','nvarchar(20)') as Type,
a.value('./@Enabled','bit') as Enabled,
a.value('./@SeqNumber','int') as SeqNumber,
a.value('./@Min','int') as Min,
a.value('./@Max','int') as Max
from @xml.nodes('//Woninglabel') x(a)
---
Id Type Enabled SeqNumber Min Max
1 Huishoudgrootte 1 1 0 99
2 Leeftijd 1 2 0 999
Или это, чтобы извлечь данные только одной метки:
select
a.value('./@Id','int') as Id,
a.value('./@Type','nvarchar(20)') as Type,
a.value('./@Enabled','bit') as Enabled,
a.value('./@SeqNumber','int') as SeqNumber,
a.value('./@Min','int') as Min,
a.value('./@Max','int') as Max
from @xml.nodes('//Woninglabel') x(a)
where a.value('./@Id','int')=1
---
Id Type Enabled SeqNumber Min Max
1 Huishoudgrootte 1 1 0 99
Если столбец таблицы имеет тип, отличный от XML, вы можете использовать CTE или подзапрос, чтобы сначала проанализировать текст в XML. Вы также можете поместить этот «измельчающий» код в представление, чтобы уменьшить сложность запроса.
declare @t table (OuterID bigint identity primary key,x nvarchar(max));
insert into @t values (@txt);
with parsed as (
select *, cast(x as xml) xx1 from @t
)
select OuterID,
a.value('./@Id','int') as Id,
a.value('./@Type','nvarchar(20)') as Type,
a.value('./@Enabled','bit') as Enabled,
a.value('./@SeqNumber','int') as SeqNumber,
a.value('./@Min','int') as Min,
a.value('./@Max','int') as Max
from parsed
cross apply xx1.nodes('//Woninglabel') x(a)
---
OuterID Id Type Enabled SeqNumber Min Max
1 1 Huishoudgrootte 1 1 0 99
1 2 Leeftijd 1 2 0 999
Эти столбцы можно использовать для фильтрации, как и любой другой столбец:
with parsed as (
select *, cast(x as xml) xx1 from @t
),
labels as (
select OuterID,
a.value('./@Id','int') as Id,
a.value('./@Type','nvarchar(20)') as Type,
a.value('./@Enabled','bit') as Enabled,
a.value('./@SeqNumber','int') as SeqNumber,
a.value('./@Min','int') as Min,
a.value('./@Max','int') as Max
from parsed
cross apply xx1.nodes('//Woninglabel') x(a)
)
select * from labels
where SeqNumber=2
Какие СУБД вы используете? (Приведенный выше запрос зависит от продукта.)