T SQL Парсить из XML узлов - PullRequest
1 голос
/ 14 июля 2020

Этот XML поступает из государственной казны c. SQL Сервер кажется думает, что это не XML? Мой результат говорит, что метод XLT может быть задействован только с типом столбца XML. Действительно ли этот результат получен из казначейства XML?

Как мне преобразовать его в таблицу SQL?

ежедневная рыночная доходность казначейства

DECLARE @XML NVARCHAR(MAX)
SELECT @XML = 
'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<feed xml:base="http://data.treasury.gov/Feed.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
  <title type="text">DailyTreasuryYieldCurveRateData</title>
  <id>http://data.treasury.gov/feed.svc/DailyTreasuryYieldCurveRateData</id>
  <updated>2020-07-14T05:40:26Z</updated>
  <link rel="self" title="DailyTreasuryYieldCurveRateData" href="DailyTreasuryYieldCurveRateData"/>
  <entry>
    <id>http://data.treasury.gov/Feed.svc/DailyTreasuryYieldCurveRateData(7633)</id>
    <title type="text"/>
    <updated>2020-07-14T05:40:26Z</updated>
    <author>
      <name/>
    </author>
    <link rel="edit" title="DailyTreasuryYieldCurveRateDatum" href="DailyTreasuryYieldCurveRateData(7633)"/>
    <category term="TreasuryDataWarehouseModel.DailyTreasuryYieldCurveRateDatum" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
    <content type="application/xml">
      <m:properties>
        <d:Id m:type="Edm.Int32">7633</d:Id>
        <d:NEW_DATE m:type="Edm.DateTime">2020-07-01T00:00:00</d:NEW_DATE>
        <d:BC_1MONTH m:type="Edm.Double">0.12</d:BC_1MONTH>
        <d:BC_2MONTH m:type="Edm.Double">0.12</d:BC_2MONTH>
        <d:BC_3MONTH m:type="Edm.Double">0.14</d:BC_3MONTH>
        <d:BC_6MONTH m:type="Edm.Double">0.17</d:BC_6MONTH>
        <d:BC_1YEAR m:type="Edm.Double">0.16</d:BC_1YEAR>
        <d:BC_2YEAR m:type="Edm.Double">0.17</d:BC_2YEAR>
        <d:BC_3YEAR m:type="Edm.Double">0.19</d:BC_3YEAR>
        <d:BC_5YEAR m:type="Edm.Double">0.31</d:BC_5YEAR>
        <d:BC_7YEAR m:type="Edm.Double">0.52</d:BC_7YEAR>
        <d:BC_10YEAR m:type="Edm.Double">0.69</d:BC_10YEAR>
        <d:BC_20YEAR m:type="Edm.Double">1.2</d:BC_20YEAR>
        <d:BC_30YEAR m:type="Edm.Double">1.43</d:BC_30YEAR>
        <d:BC_30YEARDISPLAY m:type="Edm.Double">1.43</d:BC_30YEARDISPLAY>
      </m:properties>
    </content>
  </entry>
</feed>'
   
SELECT  b.value('@d:Id', 'varchar(28)') as d_id
       ,b.value('@d:BC_30YEAR', 'double') as d_BC_30YEAR
  FROM @XML.nodes('feed/entry/content type/m:properties/') as a(b)

1 Ответ

5 голосов
/ 14 июля 2020

Сначала определите ваш @XML как тип XML:

DECLARE @XML XML;

Затем: вам нужно определить соответствующие задействованные XML пространства имен!

Попробуйте этот фрагмент кода:

-- define XML namespaces!
;WITH XMLNAMESPACES(DEFAULT 'http://www.w3.org/2005/Atom', 
                    'http://schemas.microsoft.com/ado/2007/08/dataservices/metadata' AS m,
                    'http://schemas.microsoft.com/ado/2007/08/dataservices' AS d)
SELECT  
    b.value('(d:Id)[1]', 'varchar(28)') as d_id,
    b.value('(d:BC_30YEAR)[1]', 'decimal(20,2)') as d_BC_30YEAR
FROM 
    @XML.nodes('feed/entry/content/m:properties') as a(b)

Это возвращает следующее значение:

введите описание изображения здесь

Исправления, которые я сделал:

FROM @XML.nodes('feed/entry/content type/m:properties/') as a(b)  
                            ^^^^^^^^^^^^

Неверное имя узла - это узел <content> (не «тип содержимого») - type - это просто атрибут на node, здесь нет никакого отношения к этому XPath.

SELECT b.value('@d:Id', 'varchar(28)') as d_id  
                ^^^^^^

Вы действительно хотите выбрать XML элемент (node) d:Id - не атрибут - @ в @d:Id обозначает атрибут!

b.value('@d:BC_30YEAR', 'double') as d_BC_30YEAR  
                        ^^^^^^^^^

Вам необходимо использовать правильный тип данных T- SQL - например, decimal(20,2) - здесь не "double" ....

...