powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Получить значение
5 сообщений из 5, страница 1 из 1
Получить значение
    #40116783
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте!

Есть исходные данные. Таблица из трех полей. Номер объекта, тип объекта и описание объекта как xml.
SQL. Исходные данные
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
WITH Table1 AS
(
	SELECT
		ID,
		TypeData,
		CAST(XMLData AS XML) AS XMLData
	FROM
		(VALUES 
			(1, 1,
				'<РодительскийЭлемент>
					<Элемент1_1 АтрибутЗначение="101"></Элемент1_1>					
				</РодительскийЭлемент>')
			,(2, 2,
				'<РодительскийЭлемент>
					<Элемент1_1 Атрибут="101"></Элемент1_1>
					<Элемент1_2>
						<Элемент1_2_1 АтрибутЗначение = "232"></Элемент1_2_1> 
						<Элемент1_2_2 АтрибутЗначение = "234"></Элемент1_2_2>
						<Элемент1_2_3 АтрибутЗначение = "239"></Элемент1_2_3>
					</Элемент1_2>
				</РодительскийЭлемент>')
			,(3, 3,
				'<РодительскийЭлемент>					
					<Элемент1_1>
						<Элемент1_1_1>
							<Элемент1_1_1_ АтрибутИмя="Name19" АтрибутЗначение="123"></Элемент1_1_1_>
							<Элемент1_1_1_ АтрибутИмя="Name20" АтрибутЗначение="127"></Элемент1_1_1_>
							<Элемент1_1_1_ АтрибутИмя="Name21" АтрибутЗначение="129"></Элемент1_1_1_>
						</Элемент1_1_1> 						
					</Элемент1_1>
				</РодительскийЭлемент>')
			,(4, 4,
				'<РодительскийЭлемент>					
					<Элемент1_1>
						<Элемент1_1_1>
							<Элемент1_1_1_ АтрибутИмя="Name19" АтрибутЗначение="123"></Элемент1_1_1_>
							<Элемент1_1_1_ АтрибутИмя="Name20" АтрибутЗначение="127"></Элемент1_1_1_>
							<Элемент1_1_1_ АтрибутИмя="Name21" АтрибутЗначение="129"></Элемент1_1_1_>
						</Элемент1_1_1>
						<Элемент1_1_2>
							<Элемент1_1_2_ АтрибутИмя="Name19" АтрибутЗначение="223"></Элемент1_1_2_>
							<Элемент1_1_2_ АтрибутИмя="Name20" АтрибутЗначение="227"></Элемент1_1_2_>
							<Элемент1_1_2_ АтрибутИмя="Name21" АтрибутЗначение="229"></Элемент1_1_2_>
						</Элемент1_1_2> 
						<Элемент1_1_3>
							<Элемент1_1_3_ АтрибутИмя="Name19" АтрибутЗначение="223"></Элемент1_1_3_>
							<Элемент1_1_3_ АтрибутИмя="Name20" АтрибутЗначение="227"></Элемент1_1_3_>
							<Элемент1_1_3_ АтрибутИмя="Name21" АтрибутЗначение="229"></Элемент1_1_3_>
						</Элемент1_1_3> 
					</Элемент1_1>
				</РодительскийЭлемент>')
			,(5, 5,
				'<РодительскийЭлемент>					
					<Элемент1_1>
						<Элемент1_1_1>
							<Элемент1_1_1_1>
								<Элемент1_1_1_1_1>
									<Элемент1_1_1_1_1_ АтрибутИмя="Name19" АтрибутЗначение="123"></Элемент1_1_1_1_1_>
									<Элемент1_1_1_1_1_ АтрибутИмя="Name20" АтрибутЗначение="127"></Элемент1_1_1_1_1_>
									<Элемент1_1_1_1_1_ АтрибутИмя="Name21" АтрибутЗначение="129"></Элемент1_1_1_1_1_>
								</Элемент1_1_1_1_1>
							</Элемент1_1_1_1>
						</Элемент1_1_1>	
						<Элемент1_1_2>
							<Элемент1_1_2_1>
								<Элемент1_1_2_1_ АтрибутИмя="Name19" АтрибутЗначение="23"></Элемент1_1_2_1_>
								<Элемент1_1_2_1_ АтрибутИмя="Name20" АтрибутЗначение="27"></Элемент1_1_2_1_>
								<Элемент1_1_2_1_ АтрибутИмя="Name21" АтрибутЗначение="29"></Элемент1_1_2_1_>										
							</Элемент1_1_2_1>
						</Элемент1_1_2>					
					</Элемент1_1>					
				</РодительскийЭлемент>')
		) t (ID, TypeData, XMLData)
)


Есть SQL-код, который получает значение определенного атрибута из колонки XMLData в зависимости от типа.
SQL
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
SELECT
	ID,
	TypeData,
	XMLData,
	CASE
		--В типе 1 в Элемент1_1 получить АтрибутЗначение
		WHEN TypeData = 1 THEN
			XMLData.value('/РодительскийЭлемент[1]/Элемент1_1[1]/@АтрибутЗначение',
							'NVARCHAR(MAX)')
		--В типе 2 в Элемент1_2_2 получить АтрибутЗначение
		WHEN TypeData = 2 THEN
			XMLData.value('/РодительскийЭлемент[1]/Элемент1_2[1]/Элемент1_2_2[1]/@АтрибутЗначение',
							'NVARCHAR(MAX)')
		--В типе 3 в Элемент1_1_1 получить значение атрибута в той строке, где АтрибутИмя="Name20"
		WHEN TypeData = 3 THEN
			XMLData.value('(/РодительскийЭлемент[1]/Элемент1_1[1]/Элемент1_1_1/Элемент1_1_1_[@АтрибутИмя="Name20"])
								[1]/@АтрибутЗначение',			
							'NVARCHAR(MAX)')			
		--В типе 4 в Элемент1_1 найти все уникальные значении атрибутов, где
		--АтрибутИмя="Name20", и вывести через запятую
		WHEN TypeData = 4 THEN
			(SELECT
				STRING_AGG (value, ', ')
			FROM
				(SELECT DISTINCT
					value
				FROM
					(VALUES
						(XMLData.value('(/РодительскийЭлемент[1]/Элемент1_1[1]/Элемент1_1_1/Элемент1_1_1_[@АтрибутИмя="Name20"])
											[1]/@АтрибутЗначение',
										'NVARCHAR(MAX)'))
						,(XMLData.value('(/РодительскийЭлемент[1]/Элемент1_1[1]/Элемент1_1_2/Элемент1_1_2_[@АтрибутИмя="Name20"])
											[1]/@АтрибутЗначение',
										'NVARCHAR(MAX)'))
						,(XMLData.value('(/РодительскийЭлемент[1]/Элемент1_1[1]/Элемент1_1_3/Элемент1_1_3_[@АтрибутИмя="Name20"])
											[1]/@АтрибутЗначение',
										'NVARCHAR(MAX)'))
					) t1 (value)
				) t2
			)
		--В типе 5 в Элемент1_1 найти все уникальные значении атрибутов в разных уровнях, где
		--АтрибутИмя="Name20", и вывести через запятую
		WHEN TypeData = 5 THEN
			--XMLData.value('(//Элемент1_1[@АтрибутИмя="Name20"])[1]/@АтрибутЗначение',
			XMLData.value('(//Элемент1_1[contains(@АтрибутИмя, "Name20")])[1]/@АтрибутЗначение',
							'NVARCHAR(MAX)')
		END AS Value
FROM
	Table1

Для 1-го, 2-го и 3-ого типа работает.

1. Для 4-го типа работает, но код в формуле получился громоздким и учитывает до трех значений. И, возможно, что в XML может быть больше трех АтрибутЗначение при АтрибутИмя ="Name20". Скажите, как оптимальнее написать, чтобы формула была динамичной?

2. А также не работает формула для 5-ого типа. Еще не отображает уникальные значения, так как пока не находит все значения. Скажите, как правильно написать?
...
Рейтинг: 0 / 0
Получить значение
    #40116785
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вам сильно полегчает, если вы перестанете хранить данные в именах таблиц/колонок.
И будете хранить их ВНУТРИ таблиц.
...
Рейтинг: 0 / 0
Получить значение
    #40116798
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikk,

попробуйте звездочку, она означает поиск на всех уровнях вложенности.
...
Рейтинг: 0 / 0
Получить значение
    #40117364
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав Колосов
попробуйте звездочку, она означает поиск на всех уровнях вложенности.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
DECLARE @XMP_Temp xml = CAST(
				'<РодительскийЭлемент>					
					<Элемент1_1>
						<Элемент1_1_1>
							<Элемент1_1_1_ АтрибутИмя="Name19" АтрибутЗначение="123"></Элемент1_1_1_>
							<Элемент1_1_1_ АтрибутИмя="Name20" АтрибутЗначение="127"></Элемент1_1_1_>
							<Элемент1_1_1_ АтрибутИмя="Name21" АтрибутЗначение="129"></Элемент1_1_1_>
						</Элемент1_1_1>
						<Элемент1_1_2>
							<Элемент1_1_2_ АтрибутИмя="Name19" АтрибутЗначение="223"></Элемент1_1_2_>
							<Элемент1_1_2_ АтрибутИмя="Name20" АтрибутЗначение="227"></Элемент1_1_2_>
							<Элемент1_1_2_ АтрибутИмя="Name21" АтрибутЗначение="229"></Элемент1_1_2_>
						</Элемент1_1_2> 
						<Элемент1_1_3>
							<Элемент1_1_3_ АтрибутИмя="Name19" АтрибутЗначение="223"></Элемент1_1_3_>
							<Элемент1_1_3_ АтрибутИмя="Name20" АтрибутЗначение="227"></Элемент1_1_3_>
							<Элемент1_1_3_ АтрибутИмя="Name21" АтрибутЗначение="229"></Элемент1_1_3_>
						</Элемент1_1_3> 
					</Элемент1_1>
				</РодительскийЭлемент>' 
				AS xml);

Использую query .

Это работает
Код: sql
1.
SELECT @XMP_Temp.query('//*[@АтрибутИмя="Name20"]')



А вот если задавать для определенных верхних уровней, то это не работает.
Код: sql
1.
2.
SELECT @XMP_Temp.query('/РодительскийЭлемент/Элемент1_1/*[@АтрибутИмя="Name20"]')
SELECT @XMP_Temp.query('//Элемент1_1/*[@АтрибутИмя="Name20"]')


Звездочка не предназначена для определенных уровней?
...
Рейтинг: 0 / 0
Получить значение
    #40117387
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikk,

я без понятия. Попробуйте подойти творчески, например , выбрать запросом из запроса.
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Получить значение
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]