То, что вы предоставляете, недостаточно ... Для вашего следующего вопроса попробуйте создать mcve ( автономный образец для воспроизведения вашей проблемы) .
вызов: ColumnReference доступен в нескольких иерархиях, необходимо извлечь их все
В качестве быстрого снимка вы можете попробовать что-то подобное:
SELECT AnyColRef.value('@Database','nvarchar(250)') AS [Database]
,AnyColRef.value('@Schema','nvarchar(250)') AS [Schema]
,AnyColRef.value('@Table','nvarchar(250)') AS [Table]
,AnyColRef.value('@Column','nvarchar(250)') AS [Column]
FROM YourTable t
CROSS APPLY t.YourXMLColumn.nodes('//ColumnReference') A(AnyColRef);
Идея вкратце:
Глубокий поиск 1016 * (вызванный двойной косой чертой в //ColumnReference
) будет искать любой элемент с таким именем в любом месте вашего XML.Все эти элементы возвращаются как производное множество , где каждый элемент возвращается в свою собственную строку (это делается с помощью .nodes()
).Собственный метод XML .value()
, наконец, извлечет внутренние значения атрибутов (обозначенные @
).
UPDATE
Лучше всего было предоставить образец XML, который вы хотите прочитать, но спасибо за приведенный выше код, чтобы воспроизвести вашу проблему, это тоже помогло.
Ваша проблема: XML объявляет пространство имен по умолчанию.Существует три подхода для решения этой проблемы:
- a) Использование
WITHXMLNAMESPACES
с префиксом - b) Использование
WITHXMLNAMESPACES
с DEFUALT
- a) Используйте внутреннюю декларацию с префиксом
- b) Используйте внутреннюю декларацию для
default element namespace
- Используйте подстановочный знак
Либо это
WITH XMLNAMESPACES('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS ns)
SELECT
AnyColRef.value('@Table', 'nvarchar(250)') AS [Table],
AnyColRef.value('@Column', 'nvarchar(250)') AS [Column]
FROM
#t t
CROSS APPLY t.query_plan.nodes('//ns:ColumnReference') A(AnyColRef);
- или это
WITH XMLNAMESPACES(DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
SELECT
AnyColRef.value('@Table', 'nvarchar(250)') AS [Table],
AnyColRef.value('@Column', 'nvarchar(250)') AS [Column]
FROM
#t t
CROSS APPLY t.query_plan.nodes('//ColumnReference') A(AnyColRef);
- или это
SELECT
AnyColRef.value('@Table', 'nvarchar(250)') AS [Table],
AnyColRef.value('@Column', 'nvarchar(250)') AS [Column]
FROM
#t t
CROSS APPLY t.query_plan.nodes('declare namespace ns="http://schemas.microsoft.com/sqlserver/2004/07/showplan";//ns:ColumnReference') A(AnyColRef);
- или это
SELECT
AnyColRef.value('@Table', 'nvarchar(250)') AS [Table],
AnyColRef.value('@Column', 'nvarchar(250)') AS [Column]
FROM
#t t
CROSS APPLY t.query_plan.nodes('declare default element namespace "http://schemas.microsoft.com/sqlserver/2004/07/showplan" ;//ColumnReference') A(AnyColRef);
- или это
SELECT
AnyColRef.value('@Table', 'nvarchar(250)') AS [Table],
AnyColRef.value('@Column', 'nvarchar(250)') AS [Column]
FROM
#t t
CROSS APPLY t.query_plan.nodes('//*:ColumnReference') A(AnyColRef);
Общий совет: будьте как можно точнее.Пространства имен являются не просто модным дополнением, но очень важны для работы с различными элементами с одинаковыми именами (часто при объединении различных XML).Используйте подстановочный знак easy-cheesy только в тех случаях, когда вы можете быть уверены, что пространство имен не требуется.Лично я предпочитаю подход WITH XMLNAMESPACES
с DEFAULT
, так как он наиболее близок к данному XML.