我有一个要加载到 SQL 中的 xml 文件。我可以毫无问题地加载 xml 文件并将顶级节点放入 sql 表中。我很难到达下一级子节点。
这是一个示例 xml 文件(类似于我试图进入表格的内容):
<RSR:ROOT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:RSR="urn:rsrNamespace" xsi:schemaLocation="urn:rsrNamespace SomeSchema.xsd">
<ClientReport>
<ClientID>05929</ClientID>
<ClientFirstName>Eric</ClientFirstName>
<ClientLastName>Jones</ClientLastName>
<ClientService>
<ClientServices>
<ServiceID>250</ServiceID>
<Salesperson>Charlie</Salesperson>
<Cost>15.95</Cost>
</ClientServices>
<ClientServices>
<ServiceID>356</ServiceID>
<Salesperson>Jane</Salesperson>
<Cost>34.25</Cost>
</ClientServices>
</ClientService>
</ClientReport>
</RSR:ROOT>
我可以毫无问题地将顶级节点 ClientID 和 ClientName 放入表中。我可以运行此 sql 并将值存入临时表 CLIENTREPORT:
CREATE TABLE ##XMLTable (XMLData XML)
SET @cmd = 'INSERT INTO ##XMLTable SELECT CONVERT(XML, BulkColumn) AS Bulkcolumn FROM OPENROWSET (BULK ''' + @FullPathName + ''', SINGLE_BLOB) as X'
SET @cmd = 'WITH XMLNAMESPACES (''urn:rsrNamespace'' AS p)
INSERT INTO ##CLIENTREPORT (ClientID, ClientFullName)
SELECT
CLIENTDATA.ClientReport.value(''(./ClientID)[1]'', ''VARCHAR(100)''),
CLIENTDATA.ClientReport.value(''(./ClientFirstName)[1]'', ''VARCHAR(100)'') + '' '' + CLIENTDATA.ClientReport.value(''(./ClientLastName)[1]'', ''VARCHAR(100)'')
FROM ##XMLTable X
CROSS APPLY X.XMLData.nodes(''p:ROOT/ClientReport'') AS CLIENTDATA (ClientReport)'
我在访问那些较低级别的节点时遇到问题 - ServiceID、Salesperson、Cost。这是我所拥有的不起作用的东西:
SET @cmd = 'WITH XMLNAMESPACES (''urn:rsrNamespace'' AS p)
INSERT INTO ##CLIENTREPORTSERVICES (ClientID, Salesperson)
SELECT
CLIENTDATA.ClientReport.value(''(./ClientID)[1]'', ''VARCHAR(100)''),
CLIENTSERVICEDATA.ClientServices.value(''(./Salesperson)[1]'', ''VARCHAR(25)'')
FROM ##XMLTable X
CROSS APPLY X.XMLData.nodes(''p:ROOT/ClientReport'') AS CLIENTDATA (ClientReport)
CROSS APPLY CLIENTDATA.ClientReport.nodes(''ClientService/ClientServices'') AS CLIENTSERVICEDATA (ClientServices)'
我得到的只是 Salesperson 字段中的空值。关于 XQuery 和导航到较低级别的节点,我缺少什么?
请尝试以下操作。
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (XMLData XML);
INSERT @tbl (XMLData) VALUES
(N'<QSR:ROOT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:QSR="urn:qsrNamespace" xsi:schemaLocation="urn:qsrNamespace SomeSchema.xsd">
<ClientReport>
<ClientID>05929</ClientID>
<ClientFirstName>Eric</ClientFirstName>
<ClientLastName>Jones</ClientLastName>
<ClientService>
<ClientServices>
<ServiceID>250</ServiceID>
<Salesperson>Charlie</Salesperson>
<Cost>15.95</Cost>
</ClientServices>
<ClientServices>
<ServiceID>356</ServiceID>
<Salesperson>Jane</Salesperson>
<Cost>34.25</Cost>
</ClientServices>
</ClientService>
</ClientReport>
</QSR:ROOT>');
-- DDL and sample data population, end
;WITH XMLNAMESPACES ('urn:qsrNamespace' AS QSR)
SELECT c.value('(ClientID/text())[1]', 'VARCHAR(20)') AS ClientID
, c.value('(ClientFirstName/text())[1]', 'VARCHAR(20)') AS ClientFirstName
, c.value('(ClientLastName/text())[1]', 'VARCHAR(20)') AS ClientLastName
FROM @tbl
CROSS APPLY XMLData.nodes('/QSR:ROOT/ClientReport') AS t(c);
;WITH XMLNAMESPACES ('urn:qsrNamespace' AS QSR)
SELECT p.value('(ClientID/text())[1]', 'VARCHAR(20)') AS ClientID
, c.value('(ServiceID/text())[1]', 'VARCHAR(20)') AS ServiceID
, c.value('(Salesperson/text())[1]', 'VARCHAR(20)') AS Salesperson
, c.value('(Cost/text())[1]', 'DECIMAL(10,2)') AS Cost
FROM @tbl
CROSS APPLY XMLData.nodes('/QSR:ROOT/ClientReport') AS t1(p)
CROSS APPLY p.nodes('ClientService/ClientServices') AS t2(c);
输出#1
客户ID | 客户名字 | 客户姓氏 |
---|---|---|
05929 | 埃里克 | 琼斯 |
输出#2
客户ID | 服务编号 | 营业员 | 费用 |
---|---|---|---|
05929 | 250 | 查理 | 15.95 |
05929 | 356 | 简 | 34.25 |