【问题标题】:Parsing XML data using Transact-SQL in SQL Server 2014在 SQL Server 2014 中使用 Transact-SQL 解析 XML 数据
【发布时间】:2019-12-05 19:08:09
【问题描述】:

我需要解析下面显示的代码中包含的 XML 数据。请问 SELECT 语句后面的五行代码应该是什么?

我已阅读 Frederic Brouard 等人在 SQL Server 2014 中关于 XML 的部分。根据这篇阅读,我尝试在五行代码中输入不同的内容,但它们不起作用。

DECLARE @ForexXML

SET @ForexXML = N'

<rates>
  <date2019-07-23>
    <USD>0.7605336601</USD>
  </date2019-07-23>
  <date2019-07-25>
    <USD>0.7617709547</USD>
  </date2019-07-25>
  <date2019-07-26>
    <USD>0.758719346</USD>
  </date2019-07-26>
  <date2019-07-24>
    <USD>0.7616052506</USD>
  </date2019-07-24>
  <date2019-07-22>
    <USD>0.7647459939</USD>
  </date2019-07-22>
</rates>
<start_at>2019-07-20</start_at>
<base>CAD</base>
<end_at>2019-07-26</end_at>'

INSERT INTO dbo.destinationTable (Date, Base, Currency, Rate)
    SELECT
        Node.Dt.value('SUBSTRING(date[1], 5, 10)', 'DATE') AS Date,
        Node.Dt.value('.', 'NVARCHAR(10)') AS Base,
        Node.Dt.value('date[1]/@USD', 'NVARCHAR(20)') AS Currency,
        Node.Dt.value('.', 'NVARCHAR(MAX)') AS Rate
    FROM 
        @ForexXMLData.nodes('.') Node(Dt)

预期结果:

解析后的数据将进入一个包含以下四列的 SQL Server 表,每列都有显示的值:

Date          Base    Currency    Rate
----------------------------------------------
2019-07-23    CAD     USD         0.7605336601
2019-07-25    CAD     USD         0.7617709547
2019-07-26    CAD     USD         0.758719346
2019-07-24    CAD     USD         0.7616052506
2019-07-22    CAD     USD         0.7647459939 

目前的实际结果:

Date         Base         Currency   Rate
---------------------------------------------
1900-01-01   0.76053366   NULL       0.76053366010.76177095470.7587193460.76160525060.76474599392019-07-20CAD2019-07-26

【问题讨论】:

    标签: xml tsql sql-server-2014


    【解决方案1】:

    试试这个:

    SELECT
        Date = CAST(SUBSTRING(xc.value('local-name(.)', 'nvarchar(25)'), 5, 15) AS DATE),
        Base = @ForexXMLData.value('(base)[1]', 'varchar(10)'),
        Currency = xc2.value('local-name(.)', 'nvarchar(25)'),
        ExchangeRate = xc.value('.', 'decimal(20, 12)')
    FROM
        @ForexXMLData.nodes('/rates/*') AS XT(XC)
    CROSS APPLY
        XC.nodes('*') AS XT2(XC2)
    

    .nodes() 的第一次调用获取&lt;rates&gt; 元素内每个节点的XML 片段列表——那些&lt;date2019-07-23&gt; 元素(顺便说一句,这是一个糟糕的设计——封装将日期值添加到 XML 元素的名称中;如果它是一个 属性 - 类似 &lt;date value="2019-07-23"&gt; 或类似的东西,它会更容易和更简洁!)。

    CROSS APPLY 中第二次调用.nodes() 然后获取每个&lt;dateXXXXX&gt; 元素的所有子元素 - 这些是您的&lt;USD&gt; 元素,并首先打印出它们的元素名称(local-name(.) ),以及它们的价值。

    【讨论】:

    • 嗨,马克。非常感谢您在这方面的帮助。非常感激。您的代码运行良好,除了“Base = @input.value('(base)[1]', 'varchar(10)')” 行。系统要求声明 @input 变量,我这样做了。我将它声明为 varchar(10),但我收到一条错误消息,大意是无法在 varchar 上调用方法。然后我尝试了 nvarchar(10) 并得到了相同的消息。然后我尝试了 XML,它似乎工作。但是,当我尝试代码时,我在目标表的 Base 列中得到了“NULL”值。还有其他想法吗?再次感谢您!
    • @JH-Developer:抱歉——我的错——我将我的 XML 变量命名为 @input。那应该用你的变量名替换,@ForexXMLData- 然后它应该可以正常工作。
    • @marc_s 你好,马克。哇,效果很好!你回答了我的问题。再次非常感谢您的帮助!最好的问候。
    猜你喜欢
    • 2017-07-29
    • 1970-01-01
    • 1970-01-01
    • 2013-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多