繁体   English   中英

如何解析多个xml节点到sql服务器

[英]How to parse multiple xml node to sql server

实际上我想使用以下 883812976388 节点将 xml 解析为 sql 我想要 xml 输入参数然后进入表中。

<root>
 <Header>
<RqID>20220210125441</RqID>
</Header>
<Item>
<element>
<FromCrcy>JPY</FromCrcy>
<Rate>0.00886</Rate>
<RatioFrom>0</RatioFrom>
<RatioTo>0</RatioTo>
<ToCrcy>EUR</ToCrcy>
<ValidFrom>26.07.2010</ValidFrom>
</element>      
</Item>
<ResponseStatus>
<StatusCode>I000000</StatusCode>
<StatusDesc>Success</StatusDesc>
</ResponseStatus>
</root>

以下脚本我正在使用将 xml 获取到 sql 服务器中的表但获取为 null 所以请解决它。

Set @StrMessage = ''
    Declare @intPointer int

    Exec sp_xml_preparedocument @intPointer  OUTPUT, @MessageXML
    --PRINT CONVERT(NVARCHAR(MAX),@MessageXML)

    Create Table #Currency_bas 
    (
        RowID int Identity, RqID nvarchar(50), FromCrcy nvarchar(3), Rate Decimal(13,3), RatioFrom int, RatioTo int
        , ToCrcy nvarchar(3), ValidFrom date,StatusCode nvarchar(50),StatusDesc nvarchar(50)
    )   
    Insert Into #Currency_bas
    (
         --RqID,
         --StatusCode,StatusDesc --, --
         FromCrcy, Rate, RatioFrom, RatioTo 
        , ToCrcy, ValidFrom 
    )

    Select  
    --RqID,StatusCode,StatusDesc --, 
    FromCrcy, Rate, RatioFrom, RatioTo 
        ,ToCrcy, ValidFrom  
    From OPENXML(@intPointer, '/root',2)
    WITH 
    (
       --RqID nvarchar(50),
       --StatusCode nvarchar(50),
       --StatusDesc nvarchar(50)
        FromCrcy nvarchar(3), 
        Rate Decimal(13,3), 
        RatioFrom int, 
        RatioTo int, 
        ToCrcy nvarchar(3), 
        ValidFrom   date
    )


    SELECT FromCrcy, Rate, RatioFrom, RatioTo 
        ,ToCrcy, ValidFrom FROM #Currency_bas

如何在 sql 表中解析这个 xml 所以请给我一个例子来解决这个问题。

如果你检查你的数据,你会发现它不是从root开始的,而是从root/Item/element开始的

还要注意额外的日期转换步骤。

获取RqIDStatus所需的语法示例位于此处

https://learn.microsoft.com/en-us/sql/t-sql/functions/openxml-transact-sql?view=sql-server-ver15#b-specifying-colpattern-for-mapping-between-columns-和-the-xml-属性

DECLARE @MessageXML VARCHAR(8000)

SET @MessageXML = '
<root>
 <Header><RqID>20220210125441</RqID></Header>
 <Item>
    <element>
        <FromCrcy>JPY</FromCrcy>
        <Rate>0.00886</Rate>
        <RatioFrom>0</RatioFrom>
        <RatioTo>0</RatioTo>
        <ToCrcy>EUR</ToCrcy>
        <ValidFrom>26.07.2010</ValidFrom>
    </element>      
 </Item>
 <ResponseStatus>
        <StatusCode>I000000</StatusCode>
        <StatusDesc>Success</StatusDesc>
 </ResponseStatus>
</root>
'

Declare @intPointer int

    Exec sp_xml_preparedocument @intPointer  OUTPUT, @MessageXML

    Select  
    RqID,
    StatusCode,StatusDesc, 
    FromCrcy, Rate, RatioFrom, RatioTo 
        ,ToCrcy, CONVERT(DATE,ValidFrom,104) as ValidFrom
    From OPENXML(@intPointer, '/root/Item/element',2)
    WITH 
    (
       RqID nvarchar(50) '../../Header/RqID',
       StatusCode nvarchar(50) '../../ResponseStatus/StatusCode',
       StatusDesc nvarchar(50) '../../ResponseStatus/StatusDesc',
        FromCrcy nvarchar(3), 
        Rate Decimal(13,3), 
        RatioFrom int, 
        RatioTo int, 
        ToCrcy nvarchar(3), 
        ValidFrom   varchar(100)
    )

保留 Microsoft 专有的OPENXML及其伙伴sp_xml_preparedocumentsp_xml_removedocument只是为了与过时的 SQL Server 2000 向后兼容。它们的使用减少到极少数边缘情况。

此外,人们通常忘记调用sp_xml_removedocument 它导致了 memory 泄漏。

从SQL Server 2005开始,强烈建议重写你的SQL,改用XQuery。

SQL

DECLARE @MessageXML XML = 
N'<root>
    <Header>
        <RqID>20220210125441</RqID>
    </Header>
    <Item>
        <element>
            <FromCrcy>JPY</FromCrcy>
            <Rate>0.00886</Rate>
            <RatioFrom>0</RatioFrom>
            <RatioTo>0</RatioTo>
            <ToCrcy>EUR</ToCrcy>
            <ValidFrom>26.07.2010</ValidFrom>
        </element>
    </Item>
    <ResponseStatus>
        <StatusCode>I000000</StatusCode>
        <StatusDesc>Success</StatusDesc>
    </ResponseStatus>
</root>';

SELECT RqID = @MessageXML.value('(/root/Header/RqID/text())[1]', 'VARCHAR(50)')
    , StatusCode = @MessageXML.value('(/root/ResponseStatus/StatusCode/text())[1]', 'VARCHAR(50)')
    , StatusDesc = @MessageXML.value('(/root/ResponseStatus/StatusDesc/text())[1]', 'VARCHAR(50)')
    , FromCrcy = c.value('(FromCrcy/text())[1]', 'CHAR(3)')
    , Rate = c.value('(Rate/text())[1]', 'DECIMAL(13,5)')
    , RatioFrom = c.value('(RatioFrom/text())[1]', 'INT')
    , RatioTo = c.value('(RatioTo/text())[1]', 'INT')
    , ToCrcy = c.value('(ToCrcy/text())[1]', 'CHAR(3)')
    , ValidFrom = TRY_CONVERT(DATE, c.value('(ValidFrom/text())[1]', 'VARCHAR(10)'), 104)
FROM @MessageXML.nodes('/root/Item/element') AS t(c);

Output

+----------------+------------+------------+----------+---------+-----------+---------+--------+------------+
|      RqID      | StatusCode | StatusDesc | FromCrcy |  Rate   | RatioFrom | RatioTo | ToCrcy | ValidFrom  |
+----------------+------------+------------+----------+---------+-----------+---------+--------+------------+
| 20220210125441 | I000000    | Success    | JPY      | 0.00886 |         0 |       0 | EUR    | 2010-07-26 |
+----------------+------------+------------+----------+---------+-----------+---------+--------+------------+

暂无
暂无

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

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