获取 SQL 中 XML 文件的所有值
Get all values for the XML file in SQL
<MEMBER>
<LABEL>[None]</LABEL>
<AT Name="DefCurrency">[None]</AT>
<AT Name="AllowAdjs">N</AT>
<AT Name="IsICP">N</AT>
<AT Name="AllowAdjFromChildren">N</AT>
<AT Name="SecurityClass">NONE</AT>
<AT Name="UserDefined1"> </AT>
<AT Name="UserDefined2"> </AT>
<AT Name="UserDefined3"> </AT>
<AT Name="HoldingCompany"></AT>
<AT Name="SecurityAsPartner"></AT>
<DEFAULTPARENT>#root</DEFAULTPARENT>
<DESCRIPTION Language="English">None</DESCRIPTION>
</MEMBER>
我尝试了 @Name
,我得到了所有值,例如 DefCurrency、IsICP 等,但我没有得到这些值。
请参阅下面的代码。
DECLARE @XML AS XML, @hDoc AS INT
SELECT @XML = XMLData FROM XMLwithOpenXML
EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML
SELECT
LABEL,
val
FROM OPENXML(@hDoc, '/MEMBER/AT')
WITH
(
LABEL [varchar](50) '@Name',
val [varchar](50) '../AT'
)
提前致谢
所有受支持的 Microsoft SQL Server 版本都有 nodes() and value() 方法可用于查询 XML 数据类型,例如:
declare @xml xml = '<MEMBER>
<LABEL>[None]</LABEL>
<AT Name="DefCurrency">[None]</AT>
<AT Name="AllowAdjs">N</AT>
<AT Name="IsICP">N</AT>
<AT Name="AllowAdjFromChildren">N</AT>
<AT Name="SecurityClass">NONE</AT>
<AT Name="UserDefined1"> </AT>
<AT Name="UserDefined2"> </AT>
<AT Name="UserDefined3"> </AT>
<AT Name="HoldingCompany"></AT>
<AT Name="SecurityAsPartner"></AT>
<DEFAULTPARENT>#root</DEFAULTPARENT>
<DESCRIPTION Language="English">None</DESCRIPTION>
</MEMBER>';
select
at.value(N'@Name', N'nvarchar(128)') as LABEL,
at.value(N'(text())[1]', N'nvarchar(128)') as val
from @xml.nodes(N'/MEMBER/AT') member(at);
产生输出:
LABEL
val
DefCurrency
[None]
AllowAdjs
N
IsICP
N
AllowAdjFromChildren
N
SecurityClass
NONE
UserDefined1
UserDefined2
UserDefined3
HoldingCompany
SecurityAsPartner
如@Charlieface 所述,您还可以直接查询 table 并 cross apply
使用 nodes()
方法:
select
at.value(N'@Name', N'nvarchar(128)') as LABEL,
at.value(N'(text())[1]', N'nvarchar(128)') as val
from XMLwithOpenXML
cross apply XMLData.nodes(N'/MEMBER/AT') member(at);
可以叠加多层cross apply ... .nodes()
,所以要包含LABEL
元素的内容可以修改如下代码:
select
label.value(N'(text())[1]', 'nvarchar(128)') as LabelValue,
at.value(N'@Name', N'nvarchar(128)') as LABEL,
at.value(N'(text())[1]', N'nvarchar(128)') as val
from XMLwithOpenXML
cross apply XMLData.nodes(N'/MEMBER') nodes1(member)
cross apply member.nodes(N'LABEL') nodes2(label)
cross apply member.nodes(N'AT') nodes3(at);
产生输出:
LabelValue
LABEL
val
[None]
DefCurrency
[None]
[None]
AllowAdjs
N
[None]
IsICP
N
[None]
AllowAdjFromChildren
N
[None]
SecurityClass
NONE
[None]
UserDefined1
[None]
UserDefined2
[None]
UserDefined3
[None]
HoldingCompany
[None]
SecurityAsPartner
不过,您很可能不想在多行中重复 LABEL
元素的值,因此您可以改用 XQuery 来过滤 Name
属性并有效地转换数据具有以下内容:
select
label.value(N'(text())[1]', 'nvarchar(128)') as LabelValue,
member.value(N'(AT[@Name="DefCurrency"]/text())[1]', N'nvarchar(128)') as DefCurrency,
member.value(N'(AT[@Name="AllowAdjs"]/text())[1]', N'nvarchar(128)') as AllowAdjs,
member.value(N'(AT[@Name="IsICP"]/text())[1]', N'nvarchar(128)') as IsICP,
member.value(N'(AT[@Name="AllowAdjFromChildren"]/text())[1]', N'nvarchar(128)') as AllowAdjFromChildren,
member.value(N'(AT[@Name="SecurityClass"]/text())[1]', N'nvarchar(128)') as SecurityClass,
member.value(N'(AT[@Name="UserDefined1"]/text())[1]', N'nvarchar(128)') as UserDefined1,
member.value(N'(AT[@Name="UserDefined2"]/text())[1]', N'nvarchar(128)') as UserDefined2,
member.value(N'(AT[@Name="UserDefined3"]/text())[1]', N'nvarchar(128)') as UserDefined3,
member.value(N'(AT[@Name="HoldingCompany"]/text())[1]', N'nvarchar(128)') as HoldingCompany,
member.value(N'(AT[@Name="SecurityAsPartner"]/text())[1]', N'nvarchar(128)') as SecurityAsPartner
from XMLwithOpenXML
cross apply XMLData.nodes(N'/MEMBER') nodes1(member)
cross apply member.nodes(N'LABEL') nodes2(label);
LabelValue
DefCurrency
AllowAdjs
IsICP
AllowAdjFromChildren
SecurityClass
UserDefined1
UserDefined2
UserDefined3
HoldingCompany
SecurityAsPartner
[None]
[None]
N
N
N
NONE
<MEMBER>
<LABEL>[None]</LABEL>
<AT Name="DefCurrency">[None]</AT>
<AT Name="AllowAdjs">N</AT>
<AT Name="IsICP">N</AT>
<AT Name="AllowAdjFromChildren">N</AT>
<AT Name="SecurityClass">NONE</AT>
<AT Name="UserDefined1"> </AT>
<AT Name="UserDefined2"> </AT>
<AT Name="UserDefined3"> </AT>
<AT Name="HoldingCompany"></AT>
<AT Name="SecurityAsPartner"></AT>
<DEFAULTPARENT>#root</DEFAULTPARENT>
<DESCRIPTION Language="English">None</DESCRIPTION>
</MEMBER>
我尝试了 @Name
,我得到了所有值,例如 DefCurrency、IsICP 等,但我没有得到这些值。
请参阅下面的代码。
DECLARE @XML AS XML, @hDoc AS INT
SELECT @XML = XMLData FROM XMLwithOpenXML
EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML
SELECT
LABEL,
val
FROM OPENXML(@hDoc, '/MEMBER/AT')
WITH
(
LABEL [varchar](50) '@Name',
val [varchar](50) '../AT'
)
提前致谢
所有受支持的 Microsoft SQL Server 版本都有 nodes() and value() 方法可用于查询 XML 数据类型,例如:
declare @xml xml = '<MEMBER>
<LABEL>[None]</LABEL>
<AT Name="DefCurrency">[None]</AT>
<AT Name="AllowAdjs">N</AT>
<AT Name="IsICP">N</AT>
<AT Name="AllowAdjFromChildren">N</AT>
<AT Name="SecurityClass">NONE</AT>
<AT Name="UserDefined1"> </AT>
<AT Name="UserDefined2"> </AT>
<AT Name="UserDefined3"> </AT>
<AT Name="HoldingCompany"></AT>
<AT Name="SecurityAsPartner"></AT>
<DEFAULTPARENT>#root</DEFAULTPARENT>
<DESCRIPTION Language="English">None</DESCRIPTION>
</MEMBER>';
select
at.value(N'@Name', N'nvarchar(128)') as LABEL,
at.value(N'(text())[1]', N'nvarchar(128)') as val
from @xml.nodes(N'/MEMBER/AT') member(at);
产生输出:
LABEL | val |
---|---|
DefCurrency | [None] |
AllowAdjs | N |
IsICP | N |
AllowAdjFromChildren | N |
SecurityClass | NONE |
UserDefined1 | |
UserDefined2 | |
UserDefined3 | |
HoldingCompany | |
SecurityAsPartner |
如@Charlieface 所述,您还可以直接查询 table 并 cross apply
使用 nodes()
方法:
select
at.value(N'@Name', N'nvarchar(128)') as LABEL,
at.value(N'(text())[1]', N'nvarchar(128)') as val
from XMLwithOpenXML
cross apply XMLData.nodes(N'/MEMBER/AT') member(at);
可以叠加多层cross apply ... .nodes()
,所以要包含LABEL
元素的内容可以修改如下代码:
select
label.value(N'(text())[1]', 'nvarchar(128)') as LabelValue,
at.value(N'@Name', N'nvarchar(128)') as LABEL,
at.value(N'(text())[1]', N'nvarchar(128)') as val
from XMLwithOpenXML
cross apply XMLData.nodes(N'/MEMBER') nodes1(member)
cross apply member.nodes(N'LABEL') nodes2(label)
cross apply member.nodes(N'AT') nodes3(at);
产生输出:
LabelValue | LABEL | val |
---|---|---|
[None] | DefCurrency | [None] |
[None] | AllowAdjs | N |
[None] | IsICP | N |
[None] | AllowAdjFromChildren | N |
[None] | SecurityClass | NONE |
[None] | UserDefined1 | |
[None] | UserDefined2 | |
[None] | UserDefined3 | |
[None] | HoldingCompany | |
[None] | SecurityAsPartner |
不过,您很可能不想在多行中重复 LABEL
元素的值,因此您可以改用 XQuery 来过滤 Name
属性并有效地转换数据具有以下内容:
select
label.value(N'(text())[1]', 'nvarchar(128)') as LabelValue,
member.value(N'(AT[@Name="DefCurrency"]/text())[1]', N'nvarchar(128)') as DefCurrency,
member.value(N'(AT[@Name="AllowAdjs"]/text())[1]', N'nvarchar(128)') as AllowAdjs,
member.value(N'(AT[@Name="IsICP"]/text())[1]', N'nvarchar(128)') as IsICP,
member.value(N'(AT[@Name="AllowAdjFromChildren"]/text())[1]', N'nvarchar(128)') as AllowAdjFromChildren,
member.value(N'(AT[@Name="SecurityClass"]/text())[1]', N'nvarchar(128)') as SecurityClass,
member.value(N'(AT[@Name="UserDefined1"]/text())[1]', N'nvarchar(128)') as UserDefined1,
member.value(N'(AT[@Name="UserDefined2"]/text())[1]', N'nvarchar(128)') as UserDefined2,
member.value(N'(AT[@Name="UserDefined3"]/text())[1]', N'nvarchar(128)') as UserDefined3,
member.value(N'(AT[@Name="HoldingCompany"]/text())[1]', N'nvarchar(128)') as HoldingCompany,
member.value(N'(AT[@Name="SecurityAsPartner"]/text())[1]', N'nvarchar(128)') as SecurityAsPartner
from XMLwithOpenXML
cross apply XMLData.nodes(N'/MEMBER') nodes1(member)
cross apply member.nodes(N'LABEL') nodes2(label);
LabelValue | DefCurrency | AllowAdjs | IsICP | AllowAdjFromChildren | SecurityClass | UserDefined1 | UserDefined2 | UserDefined3 | HoldingCompany | SecurityAsPartner |
---|---|---|---|---|---|---|---|---|---|---|
[None] | [None] | N | N | N | NONE |