使用 SQL XML 获取所有值
Getting all values with SQL XML
我目前正在处理美国财政部的特别指定国民名单 (sdn)
示例:
<sdnList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/sdnList.xsd">
<publshInformation>
<Publish_Date>01/10/2022</Publish_Date>
<Record_Count>9015</Record_Count>
</publshInformation>
<sdnEntry>
<uid>18590</uid>
<firstName>xxx</firstName>
<lastName>xxx</lastName>
<sdnType>Individual</sdnType>
<programList>
<program>SDGT</program>
</programList>
<idList>
<id>
<uid>10858</uid>
<idType>Passport</idType>
<idNumber>xxx</idNumber>
<idCountry>Morocco</idCountry>
</id>
<id>
<uid>10859</uid>
<idType>National ID No.</idType>
<idNumber>xxx</idNumber>
<idCountry>Morocco</idCountry>
</id>
</idList>
<akaList>
<aka>
<uid>28970</uid>
<type>a.k.a.</type>
<category>strong</category>
<lastName>xxx</lastName>
<firstName>xxx</firstName>
</aka>
<aka>
<uid>28971</uid>
<type>a.k.a.</type>
<category>weak</category>
<lastName>xxx</lastName>
</aka>
<aka>
<uid>28972</uid>
<type>a.k.a.</type>
<category>weak</category>
<lastName>xxx</lastName>
</aka>
<aka>
<uid>28973</uid>
<type>a.k.a.</type>
<category>weak</category>
<lastName>xxx</lastName>
</aka>
</akaList>
<citizenshipList>
<citizenship>
<uid>17970</uid>
<country>Morocco</country>
<mainEntry>true</mainEntry>
</citizenship>
</citizenshipList>
<dateOfBirthList>
<dateOfBirthItem>
<uid>17969</uid>
<dateOfBirth>26 Feb 1993</dateOfBirth>
<mainEntry>true</mainEntry>
</dateOfBirthItem>
</dateOfBirthList>
</sdnEntry>
/sdnList>
我的查询是:
;WITH XMLNAMESPACES
(
DEFAULT 'http://tempuri.org/sdnList.xsd'
)
SELECT x.n.value('uid[1]', 'int') AS UID,
x.n.value('sdnType[1]', 'char(20)') AS SdnType,
x.n.value('firstName[1]', 'varchar(200)') AS FirstName,
x.n.value('lastName[1]', 'varchar(200)') AS LastName,
x.n.value('./akaList[1]/aka[1]/lastName[1]', 'char(100)') AS akaLastName,
x.n.value('./akaList[1]/aka[1]/firstName[1]', 'varchar(200)') AS AKAFirstName,
x.n.value('./akaList[1]/aka[1]/lastName[1]', 'varchar(200)') AS AKALastName,
x.n.value('./dateOfBirthList[1]/dateOfBirthItem[1]/dateOfBirth[1]', 'varchar(20)') AS DateOfBirth,
x.n.value('./addressList[1]/address[1]/address1[1]', 'varchar(100)') AS Address1,
x.n.value('./addressList[1]/address[1]/postalCode[1]', 'varchar(100)') AS PostCode,
x.n.value('./addressList[1]/address[1]/city[1]', 'varchar(100)') AS City,
x.n.value('./addressList[1]/address[1]/country[1]', 'varchar(100)') AS Country
FROM @XMLData t
CROSS APPLY t.XMLColumn.nodes('/sdnList/sdnEntry') x(n)
我当前的查询只检索每个实体的 aka 和地址的第一个条目。我知道这是因为我在查询中使用了 [1] 个单例,但不知道如何检索每个条目的所有子条目。我需要使用子查询吗?
XML 缺失 <addressList>
。
总的来说,辅助CROSS APPLY ...
模拟了XML中的一对多关系。
SQL
DECLARE @XMLData TABLE (ID INT IDENTITY PRIMARY KEY, XMLColumn XML);
INSERT INTO @XMLData (XMLColumn) VALUES
(N'<sdnList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/sdnList.xsd">
<publshInformation>
<Publish_Date>01/10/2022</Publish_Date>
<Record_Count>9015</Record_Count>
</publshInformation>
<sdnEntry>
<uid>18590</uid>
<firstName>xxx</firstName>
<lastName>xxx</lastName>
<sdnType>Individual</sdnType>
<programList>
<program>SDGT</program>
</programList>
<idList>
<id>
<uid>10858</uid>
<idType>Passport</idType>
<idNumber>xxx</idNumber>
<idCountry>Morocco</idCountry>
</id>
<id>
<uid>10859</uid>
<idType>National ID No.</idType>
<idNumber>xxx</idNumber>
<idCountry>Morocco</idCountry>
</id>
</idList>
<akaList>
<aka>
<uid>28970</uid>
<type>a.k.a.</type>
<category>strong</category>
<lastName>xxx</lastName>
<firstName>xxx</firstName>
</aka>
<aka>
<uid>28971</uid>
<type>a.k.a.</type>
<category>weak</category>
<lastName>xxx</lastName>
</aka>
<aka>
<uid>28972</uid>
<type>a.k.a.</type>
<category>weak</category>
<lastName>xxx</lastName>
</aka>
<aka>
<uid>28973</uid>
<type>a.k.a.</type>
<category>weak</category>
<lastName>xxx</lastName>
</aka>
</akaList>
<citizenshipList>
<citizenship>
<uid>17970</uid>
<country>Morocco</country>
<mainEntry>true</mainEntry>
</citizenship>
</citizenshipList>
<dateOfBirthList>
<dateOfBirthItem>
<uid>17969</uid>
<dateOfBirth>26 Feb 1993</dateOfBirth>
<mainEntry>true</mainEntry>
</dateOfBirthItem>
</dateOfBirthList>
</sdnEntry>
</sdnList>');
;WITH XMLNAMESPACES
(
DEFAULT 'http://tempuri.org/sdnList.xsd'
)
SELECT n.value('(uid/text())[1]', 'int') AS UID,
n.value('(sdnType/text())[1]', 'char(20)') AS SdnType,
n.value('(firstName/text())[1]', 'varchar(200)') AS FirstName,
n.value('(lastName/text())[1]', 'varchar(200)') AS LastName,
a.value('(lastName/text())[1]', 'char(100)') AS akaLastName,
a.value('(firstName/text())[1]', 'varchar(200)') AS AKAFirstName,
a.value('(lastName/text())[1]', 'varchar(200)') AS AKALastName,
n.value('(dateOfBirthList/dateOfBirthItem/dateOfBirth/text())[1]', 'varchar(20)') AS DateOfBirth
--x.n.value('./addressList[1]/address[1]/address1[1]', 'varchar(100)') AS Address1,
--x.n.value('./addressList[1]/address[1]/postalCode[1]', 'varchar(100)') AS PostCode,
--x.n.value('./addressList[1]/address[1]/city[1]', 'varchar(100)') AS City,
--x.n.value('./addressList[1]/address[1]/country[1]', 'varchar(100)') AS Country
FROM @XMLData t
CROSS APPLY t.XMLColumn.nodes('/sdnList/sdnEntry') AS t1(n)
CROSS APPLY t1.n.nodes('akaList/aka') AS t2(a)
我目前正在处理美国财政部的特别指定国民名单 (sdn) 示例:
<sdnList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/sdnList.xsd">
<publshInformation>
<Publish_Date>01/10/2022</Publish_Date>
<Record_Count>9015</Record_Count>
</publshInformation>
<sdnEntry>
<uid>18590</uid>
<firstName>xxx</firstName>
<lastName>xxx</lastName>
<sdnType>Individual</sdnType>
<programList>
<program>SDGT</program>
</programList>
<idList>
<id>
<uid>10858</uid>
<idType>Passport</idType>
<idNumber>xxx</idNumber>
<idCountry>Morocco</idCountry>
</id>
<id>
<uid>10859</uid>
<idType>National ID No.</idType>
<idNumber>xxx</idNumber>
<idCountry>Morocco</idCountry>
</id>
</idList>
<akaList>
<aka>
<uid>28970</uid>
<type>a.k.a.</type>
<category>strong</category>
<lastName>xxx</lastName>
<firstName>xxx</firstName>
</aka>
<aka>
<uid>28971</uid>
<type>a.k.a.</type>
<category>weak</category>
<lastName>xxx</lastName>
</aka>
<aka>
<uid>28972</uid>
<type>a.k.a.</type>
<category>weak</category>
<lastName>xxx</lastName>
</aka>
<aka>
<uid>28973</uid>
<type>a.k.a.</type>
<category>weak</category>
<lastName>xxx</lastName>
</aka>
</akaList>
<citizenshipList>
<citizenship>
<uid>17970</uid>
<country>Morocco</country>
<mainEntry>true</mainEntry>
</citizenship>
</citizenshipList>
<dateOfBirthList>
<dateOfBirthItem>
<uid>17969</uid>
<dateOfBirth>26 Feb 1993</dateOfBirth>
<mainEntry>true</mainEntry>
</dateOfBirthItem>
</dateOfBirthList>
</sdnEntry>
/sdnList>
我的查询是:
;WITH XMLNAMESPACES
(
DEFAULT 'http://tempuri.org/sdnList.xsd'
)
SELECT x.n.value('uid[1]', 'int') AS UID,
x.n.value('sdnType[1]', 'char(20)') AS SdnType,
x.n.value('firstName[1]', 'varchar(200)') AS FirstName,
x.n.value('lastName[1]', 'varchar(200)') AS LastName,
x.n.value('./akaList[1]/aka[1]/lastName[1]', 'char(100)') AS akaLastName,
x.n.value('./akaList[1]/aka[1]/firstName[1]', 'varchar(200)') AS AKAFirstName,
x.n.value('./akaList[1]/aka[1]/lastName[1]', 'varchar(200)') AS AKALastName,
x.n.value('./dateOfBirthList[1]/dateOfBirthItem[1]/dateOfBirth[1]', 'varchar(20)') AS DateOfBirth,
x.n.value('./addressList[1]/address[1]/address1[1]', 'varchar(100)') AS Address1,
x.n.value('./addressList[1]/address[1]/postalCode[1]', 'varchar(100)') AS PostCode,
x.n.value('./addressList[1]/address[1]/city[1]', 'varchar(100)') AS City,
x.n.value('./addressList[1]/address[1]/country[1]', 'varchar(100)') AS Country
FROM @XMLData t
CROSS APPLY t.XMLColumn.nodes('/sdnList/sdnEntry') x(n)
我当前的查询只检索每个实体的 aka 和地址的第一个条目。我知道这是因为我在查询中使用了 [1] 个单例,但不知道如何检索每个条目的所有子条目。我需要使用子查询吗?
XML 缺失 <addressList>
。
总的来说,辅助CROSS APPLY ...
模拟了XML中的一对多关系。
SQL
DECLARE @XMLData TABLE (ID INT IDENTITY PRIMARY KEY, XMLColumn XML);
INSERT INTO @XMLData (XMLColumn) VALUES
(N'<sdnList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/sdnList.xsd">
<publshInformation>
<Publish_Date>01/10/2022</Publish_Date>
<Record_Count>9015</Record_Count>
</publshInformation>
<sdnEntry>
<uid>18590</uid>
<firstName>xxx</firstName>
<lastName>xxx</lastName>
<sdnType>Individual</sdnType>
<programList>
<program>SDGT</program>
</programList>
<idList>
<id>
<uid>10858</uid>
<idType>Passport</idType>
<idNumber>xxx</idNumber>
<idCountry>Morocco</idCountry>
</id>
<id>
<uid>10859</uid>
<idType>National ID No.</idType>
<idNumber>xxx</idNumber>
<idCountry>Morocco</idCountry>
</id>
</idList>
<akaList>
<aka>
<uid>28970</uid>
<type>a.k.a.</type>
<category>strong</category>
<lastName>xxx</lastName>
<firstName>xxx</firstName>
</aka>
<aka>
<uid>28971</uid>
<type>a.k.a.</type>
<category>weak</category>
<lastName>xxx</lastName>
</aka>
<aka>
<uid>28972</uid>
<type>a.k.a.</type>
<category>weak</category>
<lastName>xxx</lastName>
</aka>
<aka>
<uid>28973</uid>
<type>a.k.a.</type>
<category>weak</category>
<lastName>xxx</lastName>
</aka>
</akaList>
<citizenshipList>
<citizenship>
<uid>17970</uid>
<country>Morocco</country>
<mainEntry>true</mainEntry>
</citizenship>
</citizenshipList>
<dateOfBirthList>
<dateOfBirthItem>
<uid>17969</uid>
<dateOfBirth>26 Feb 1993</dateOfBirth>
<mainEntry>true</mainEntry>
</dateOfBirthItem>
</dateOfBirthList>
</sdnEntry>
</sdnList>');
;WITH XMLNAMESPACES
(
DEFAULT 'http://tempuri.org/sdnList.xsd'
)
SELECT n.value('(uid/text())[1]', 'int') AS UID,
n.value('(sdnType/text())[1]', 'char(20)') AS SdnType,
n.value('(firstName/text())[1]', 'varchar(200)') AS FirstName,
n.value('(lastName/text())[1]', 'varchar(200)') AS LastName,
a.value('(lastName/text())[1]', 'char(100)') AS akaLastName,
a.value('(firstName/text())[1]', 'varchar(200)') AS AKAFirstName,
a.value('(lastName/text())[1]', 'varchar(200)') AS AKALastName,
n.value('(dateOfBirthList/dateOfBirthItem/dateOfBirth/text())[1]', 'varchar(20)') AS DateOfBirth
--x.n.value('./addressList[1]/address[1]/address1[1]', 'varchar(100)') AS Address1,
--x.n.value('./addressList[1]/address[1]/postalCode[1]', 'varchar(100)') AS PostCode,
--x.n.value('./addressList[1]/address[1]/city[1]', 'varchar(100)') AS City,
--x.n.value('./addressList[1]/address[1]/country[1]', 'varchar(100)') AS Country
FROM @XMLData t
CROSS APPLY t.XMLColumn.nodes('/sdnList/sdnEntry') AS t1(n)
CROSS APPLY t1.n.nodes('akaList/aka') AS t2(a)