繁体   English   中英

如何使用存储过程转换 XML 文本并插入 Microsoft SQL 服务器

[英]How to convert XML Text and insert into Microsoft SQL Server using a stored procedure

我有一个像这样的 XML 文件:

<?xml version=\"1.0\" encoding=\"utf-8\"?>
<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" 
               xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" 
               xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">
    <soap:Body>
        <Abc ">
            <Def>ID&gt;1&lt;/ID&gt;&lt;Number&gt;Not Available&lt;/Number&gt;&lt;AbcName&gt;Hello&lt;/AbcName&</Def>
        </Abc>
    </soap:Body>
</soap:Envelope>

我想编写一个存储过程,用于提取DEF标记内的文本并获取 Id、abcname 等列数据并插入 SQL 服务器数据库。

对此问题的任何帮助将不胜感激。

谢谢你!

<Def>的值提取为字符串,然后将其解析为 xml,因为 xml 没有任何根节点,将添加一个节点,因此我们可以在 sql 服务器中使用 xml function 来获取节点值。

declare @xmlstring varchar(max) 
declare @xml xml
set @xmlstring = N'<?xml version=\"1.0\" encoding=\"utf-8\"?>
<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" 
               xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" 
               xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">
    <soap:Body>
        <Abc xmlns=\"http://www.web.xds.co.za/XDSConnectWS\">
            <Def>&lt;ID&gt;1&lt;/ID&gt;&lt;Number&gt;Not Available&lt;/Number&gt;&lt;AbcName&gt;Hello&lt;/AbcName&gt;</Def>
        </Abc>
    </soap:Body>
</soap:Envelope>';

set @xmlstring = substring(@xmlstring, charindex('<Def>', @xmlstring)+5, charindex('</Def>', @xmlstring) - charindex('<Def>', @xmlstring) -5)

set @xml = concat('<root>', cast (@xmlstring as xml).value('.[1]','nvarchar(max)' ), '</root>');

select @xml;
select @xml.value('(/root/ID)[1]','varchar(30)') as ID
    ,  @xml.value('(/root/AbcName)[1]','varchar(30)') as [Name]

这里的问题是Def内部的 XML 节点没有正确编码。 它们作为内部文本存储在节点内。 所以你需要把它拉出来并转换它。

我们可以使用.valueCAST提取文本,在CROSS APPLY (VALUES .

您可以使用直接.value调用来执行此操作

DECLARE @xml xml = '<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
               xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <Abc xmlns="http://www.web.xds.co.za/XDSConnectWS">
            <Def>&lt;ID&gt;1&lt;/ID&gt;&lt;Number&gt;Not Available&lt;/Number&gt;&lt;AbcName&gt;Hello&lt;/AbcName&gt;</Def>
        </Abc>
    </soap:Body>
</soap:Envelope>';

WITH XMLNAMESPACES(
  'http://www.web.xds.co.za/XDSConnectWS' AS x,
  'http://www.w3.org/2003/05/soap-envelope' AS soap
)
SELECT
  v.InnerXml.value('(ID/text())[1]','int') as ID,
  v.InnerXml.value('(AbcName/text())[1]','varchar(30)') as Name,
  v.InnerXml.value('(Number/text())[1]','varchar(30)') as Number
FROM (VALUES(
    CAST(@xml.value('(soap:Envelope/soap:Body/x:Abc/x:Def/text())[1]','nvarchar(max)') AS xml)
)) v(InnerXml);

或者,如果您有多个节点要读取,那么您可以通过.nodes提供它:

WITH XMLNAMESPACES(
  'http://www.web.xds.co.za/XDSConnectWS' AS x,
  'http://www.w3.org/2003/05/soap-envelope' AS soap
)
SELECT
  x2.n.value('(ID/text())[1]','int') as ID,
  x2.n.value('(AbcName/text())[1]','varchar(30)') as Name,
  x2.n.value('(Number/text())[1]','varchar(30)') as Number
FROM @xml.nodes('soap:Envelope/soap:Body/x:Abc/x:Def') x1(DEF)
CROSS APPLY (VALUES(
    CAST(N'<r>' + x1.DEF.value('text()[1]','nvarchar(max)') + '</r>' AS xml)
)) v(InnerXml)
CROSS APPLY v.InnerXml.nodes('r') x2(n);

db<>小提琴

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM