让 XML 进入 SQL 服务器 table

Getting XML to feed into SQL Server table

我正试图获得一个(目前)简单的 XML 以馈入 SQL 服务器 table。

XML是:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfSafeEODBalance xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <SafeEODBalance>
        <Lane>1</Lane>
        <PouchId>06292019053041001</PouchId>
        <BusinessDay>6/29/2019</BusinessDay>
        <BusinessStartingTime>6/29/2019 5:36:58 AM</BusinessStartingTime>
        <BusinessEndingTime>6/30/2019 12:15:55 AM</BusinessEndingTime>
        <StartingBalance>0.0000</StartingBalance>
        <EndingBalance>8</EndingBalance>
    </SafeEODBalance>
    <SafeEODBalance>
        <Lane>2</Lane>
        <PouchId>06292019053042002</PouchId>
        <BusinessDay>6/29/2019</BusinessDay>
        <BusinessStartingTime>6/29/2019 5:36:58 AM</BusinessStartingTime>
        <BusinessEndingTime>6/30/2019 12:15:55 AM</BusinessEndingTime>
        <StartingBalance>100.0000</StartingBalance>
        <EndingBalance>2</EndingBalance>
    </SafeEODBalance>
</ArrayOfSafeEODBalance>

并保存到C:\Users\cj\Documents\EodBalance.xml

我已经设置了 SQL 服务器 table [dbo].[EndofDay] 其中每个列都完全相同:

这是我正在尝试的查询:

INSERT INTO [dbo].[EndofDay] ([PouchID], [Lane], [BusinessDay], BusinessStartingTime, BusinessEndingTime, [StartingBalance], [EndingBalance])
    SELECT
        MY_XML.SafeEODBalance.query('PouchId').value('.', 'VARCHAR(25)'),
        MY_XML.SafeEODBalance.query('Lane').value('.', 'NCHAR(2)'),
        MY_XML.SafeEODBalance.query('BusinessDay').value('.', 'DATE'),
        MY_XML.SafeEODBalance.query('BusinessStartingTime').value('.', 'DATETIME'),
        MY_XML.SafeEODBalance.query('BusinessEndingTime').value('.', 'DATETIME'),
        MY_XML.SafeEODBalance.query('StartingBalance').value('.', 'NCHAR(10)'),
        MY_XML.SafeEODBalance.query('EndingBalance').value('.', 'NCHAR(10)')
    FROM 
        (SELECT CAST(MY_XML AS XML)
         FROM OPENROWSET(BULK 'C:\Users\cj\Documents\EodBalance.xml',SINGLE_BLOB) AS T(MY_XML)) AS T(MY_XML)
         CROSS APPLY MY_XML.nodes('SafeEODBalance/SafeEODBalances') AS MY_XML (SafeEODBalance);

当我 运行 我得到:

    (0 rows affected)        

    Completion time: 2019-08-29T16:07:12.3361442-04:00

这显然应该向其中输入两行,但它在 table.

中什么也没有给出

这里是调整工作SQL。准备好后,只需取消注释 INSERT 行即可。

SQL

WITH XmlFile (xmlData) AS
(
   SELECT CAST(BulkColumn AS XML) 
   FROM OPENROWSET(BULK 'C:\Users\cj\Documents\EodBalance.xml', SINGLE_BLOB) AS x
)
--INSERT INTO [dbo].[EndofDay] 
--([PouchID], [Lane], [BusinessDay], BusinessStartingTime, BusinessEndingTime, [StartingBalance], [EndingBalance])
SELECT c.value('(PouchId/text())[1]', 'VARCHAR(25)') AS [PouchId]
   , c.value('(Lane/text())[1]', 'NCHAR(2)') AS [Lane]
   , c.value('(BusinessDay/text())[1]', 'DATE') AS [BusinessDay]
   , c.value('(BusinessStartingTime)[1]', 'datetime') AS [BusinessStartingTime]
   , c.value('(BusinessEndingTime/text())[1]', 'datetime') AS [BusinessEndingTime]
   , c.value('(StartingBalance/text())[1]', 'MONEY') AS [StartingBalance]
   , c.value('(EndingBalance/text())[1]', 'MONEY') AS [EndingBalance]
FROM XmlFile CROSS APPLY xmlData.nodes('/ArrayOfSafeEODBalance/SafeEODBalance') AS t(c);

** 编辑 ** 正如下面的评论所指出的,这个答案使用了遗留功能和 SP,所以不应该使用,除非你 运行 使用的是 SQL 的 2005 年前版本


这里有一个稍微不同的方法,使用变量存储来自 OPENROWSET 的 XML 和存储过程 sp_xml_preparedocument 将其转换为 XML 文档。

一旦在 XML 文档格式中,就可以使用 OPENXML() 进行查询。这样做的好处是,如果您有一个大型或复杂的 XML 结构,您希望从中提取多个内容,您可以重复使用 XML 文档,而无需重新加载原始 [=25] =] 文件.

请务必在完成 XML 文档后使用 sp_xml_removedocument 删除它以释放服务器缓存。

-- Load the XML file and convert it to an XML document
DECLARE @XML AS XML, @hXML AS INT;
SELECT @XML = CONVERT(XML, x.BulkColumn) 
    FROM OPENROWSET(BULK 'C:\Users\cj\Documents\EodBalance.xml\EodBalance.xml', SINGLE_BLOB) AS x;
EXEC sp_xml_preparedocument @hXML OUTPUT, @XML


-- Select data from the XML document
SELECT Lane, PouchID, BusinessDay, BusinessStartingTime, BusinessEndingTime,  StartingBalance, EndingBalance

    FROM OPENXML(@hXML, 'ArrayOfSafeEODBalance/SafeEODBalance') WITH
    (
        Lane                    [varchar](2)    'Lane',
        PouchId                 [varchar](50)   'PouchId',
        BusinessDay             [date]          'BusinessDay',
        BusinessStartingTime    [datetime]      'BusinessStartingTime',
        BusinessEndingTime      [datetime]      'BusinessEndingTime',
        StartingBalance         [varchar](50)   'StartingBalance',
        EndingBalance           [varchar](50)   'EndingBalance'
    );

-- Remove the XML document from the cache
EXEC sp_xml_removedocument @hXML;