将(大)XML数据加载到Azure SQL数据库表中

时间:2018-11-22 04:37:27

标签: xml tsql xml-parsing azure-sql-database azure-logic-apps

到目前为止,我一直在研究用于将大型XML文件传输到Azure SQL数据库的解决方案。通过固定的URL访问XML文件。在此项目之前,我没有使用SQL或Azure的经验,因此,如果我错过了明显的内容,我深表歉意。

我用适当的表设置了数据库,我只需要用数据填充表即可。

XML文件采用以下格式,但是有数千个作业。下载时,该文件约为1.2Mb,但是我想从URL而非本地计算机访问它。

<Response api-method="Current">
  <Status>OK</Status>
     <Jobs>
        <Job>
           <ID>N1234</ID>
           <Name>Job name here</Name>
           <Description/>Job description here</Description
           <StartDate>2018-10-08T00:00:00</StartDate>
           <DueDate>2018-10-21T00:00:00</DueDate>
           <Manager>
              <ID>12345</ID>
              <Name>John Smith</Name>
           </Manager>
        </Job>
        <Job>
            Repeat above several thousand times
        </Job>
     </Jobs>
</Response>

到目前为止,我最成功的方法是使用某些内置的Azure Logic应用程序。我正在使用HTML GET加载XML数据,然后将其传递到Liquid应用程序,该应用程序将XML转换为JSON。然后,我希望可以将JSON格式轻松加载到数据库表中。这个逻辑应用程序成功地将XML转换为JSON,但是仅当我将文件缩减为约80个作业时才如此。因此,我知道我的逻辑应用程序可以工作,并且文件大小是我的问题。

XML to JSON Logic App

有人建议采用更好的方法或允许处理较大文件的方法吗?我也尝试过使用SSMS,实现T-SQL BulkInsert,OpenRowSet等,但是我暂时放弃了这种方法。

我在尝试寻找解决方案时所用的资源很少:

非常感谢

1 个答案:

答案 0 :(得分:2)

我没有关于如何通过Azure SQL Server从URL加载XML 的经验。在 normal SQL-Server中,有一些奇怪的方法,但是我建议您从另一个应用程序中读取URL。
但是-当您设法以某种方式加载文件时-无论如何,这似乎不是问题。

您为什么需要将其转换为JSON? SQL-Server可以很好地处理本机XML。标准传输格式为NVARCHAR(MAX),它是一个UCS-2字符串,与UTF-16或简单的2-byte-unicode几乎相同。任何.Net字符串都可以按原样发送到SQL Server NVARCHAR(MAX)的大小限制足以满足您的需求...

只需创建一个如下所示的函数,然后通过您的阅读应用程序进行调用即可。您可以将参数作为字符串传递:

此函数将接受 2-byte_encoded Unicode字符串并将其隐式转换为XML:

CREATE FUNCTION dbo.ReadTheXml(@xml XML)
RETURNS TABLE
AS
RETURN
    SELECT @xml.value('(/Response/Status/text())[1]','nvarchar(max)') AS Response_Status
          ,job.value('(ID/text())[1]','nvarchar(max)') AS Job_ID
          ,job.value('(Name/text())[1]','nvarchar(max)') AS Job_Name
          ,job.value('(Description/text())[1]','nvarchar(max)') AS Job_Description
          ,job.value('(StartDate/text())[1]','datetime') AS Job_StartDate
          ,job.value('(DueDate/text())[1]','datetime') AS Job_DueDate
          ,job.value('(Manager/ID/text())[1]','int') AS Job_Manager_ID
          ,job.value('(Manager/Name/text())[1]','nvarchar(max)') AS Job_Manager_Name
    FROM @xml.nodes('/Response/Jobs/Job') A(job)
GO

-假设您已经将XML加载到字符串中,则可以像这样测试它:

DECLARE @xml NVARCHAR(MAX) =         --the xml as NVARCHAR(MAX) string
N'<Response api-method="Current">
  <Status>OK</Status>
     <Jobs>
        <Job>
           <ID>N1234</ID>
           <Name>Job name here</Name>
           <Description>Job description here</Description>
           <StartDate>2018-10-08T00:00:00</StartDate>
           <DueDate>2018-10-21T00:00:00</DueDate>
           <Manager>
              <ID>12345</ID>
              <Name>John Smith</Name>
           </Manager>
        </Job>
        <Job>
           <ID>blah</ID>
           <Name>One more</Name>
           <Description>This is one more description</Description>
           <StartDate>2018-10-08T00:00:00</StartDate>
           <DueDate>2018-10-21T00:00:00</DueDate>
           <Manager>
              <ID>12345</ID>
              <Name>John Smith</Name>
           </Manager>
        </Job>
     </Jobs>
</Response>';

-使用与使用表完全相同的方法:

SELECT * INTO #tmpStagingTable 
FROM dbo.ReadTheXml(@xml); --pass in the XML as string

--call the result from the staging table
SELECT * FROM #tmpStagingTable;  --create a staging table *on the fly*
GO

--clean up for testing
DROP FUNCTION dbo.ReadTheXml;
DROP TABLE #tmpStagingTable;

结果应插入到临时表中。针对该登台表执行任何需要的清理和业务逻辑,然后从那里开始。

结果

+-----------------+--------+---------------+------------------------------+-------------------------+-------------------------+----------------+------------------+
| Response_Status | Job_ID | Job_Name      | Job_Description              | Job_StartDate           | Job_DueDate             | Job_Manager_ID | Job_Manager_Name |
+-----------------+--------+---------------+------------------------------+-------------------------+-------------------------+----------------+------------------+
| OK              | N1234  | Job name here | Job description here         | 2018-10-08 00:00:00.000 | 2018-10-21 00:00:00.000 | 12345          | John Smith       |
+-----------------+--------+---------------+------------------------------+-------------------------+-------------------------+----------------+------------------+
| OK              | blah   | One more      | This is one more description | 2018-10-08 00:00:00.000 | 2018-10-21 00:00:00.000 | 12345          | John Smith       |
+-----------------+--------+---------------+------------------------------+-------------------------+-------------------------+----------------+------------------+