Подход через FROM OPENXML
(вместе с процедурами подготовки и удаления документа) устарел и больше не должен использоваться.
Гораздо лучше родные методы XML-типа .Попробуйте это:
Ваш XML
DECLARE @xml XML=
N'<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsd:schema xmlns:schema="urn:schemas-microsoft-com:sql:SqlRowSet1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes" targetNamespace="urn:schemas-microsoft-com:sql:SqlRowSet1" elementFormDefault="qualified">
<xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd" />
<xsd:element name="ogridroles">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="ogrid_cde" type="sqltypes:int" nillable="1" />
<xsd:element name="role" nillable="1">
<xsd:simpleType>
<xsd:restriction base="sqltypes:char" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="1" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<ogridroles xmlns="urn:schemas-microsoft-com:sql:SqlRowSet1">
<ogrid_cde>28</ogrid_cde>
<role>T</role>
</ogridroles>
<ogridroles xmlns="urn:schemas-microsoft-com:sql:SqlRowSet1">
<ogrid_cde>75</ogrid_cde>
<role>T</role>
</ogridroles>
<ogridroles xmlns="urn:schemas-microsoft-com:sql:SqlRowSet1">
<ogrid_cde>93</ogrid_cde>
<role>O</role>
</ogridroles>
<ogridroles xmlns="urn:schemas-microsoft-com:sql:SqlRowSet1">
<ogrid_cde>135</ogrid_cde>
<role>O</role>
</ogridroles>
</root>';
- Запрос
WITH XMLNAMESPACES(DEFAULT 'urn:schemas-microsoft-com:sql:SqlRowSet1')
SELECT OgrRol.value('(ogrid_cde/text())[1]','int') AS ogrid_cde
,OgrRol.value('(role/text())[1]','nvarchar(10)') AS [role]
FROM @xml.nodes('/*:root/ogridroles') A(ogrRol);
Результат
ogrid_cde role
28 T
75 T
93 O
135 O
Краткое объяснение
Вы можете просто проигнорировать XML-схему здесь.Это было бы полезно для проверки целостности и достоверности данных.Но если предположить, что данные верны, мы можем просто прочитать их.
Существует (неоднократно определенное) пространство имен по умолчанию .Но - это важно видеть! - сам элемент <root>
не живет в этом пространстве имен!.
Спокойно, я только что использовал подстановочный знак namespace для адресации этого элемента с *:root
.В общем, лучше избегать подстановочных знаков, но в этом случае это кажется приемлемым.
Мы используем .nodes()
, чтобы получить производную таблицу всех элементов <ogridroles>
.Затем мы .value()
будем читать text()
узлы кода и элемент роли.
Надеюсь, это поможет, удачного кодирования!