将结构化XML文件导入SQL表

时间:2017-09-28 10:47:02

标签: sql sql-server xml openrowset

我尝试下载XML文件并将其导入SQL表。 下载工作正常,它会生成以下XML文件。

GeoPers.xml

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
    <Clocking_GetByDateRangeUtcResponse xmlns="http://www.geodynamics.be/webservices">
        <Clocking_GetByDateRangeUtcResult>
            <ClockingEntity>
                <Id>af261a77-a35b-4778-a175-6fd50d00cde1</Id>
                <DateTimeUtc>2017-09-28T02:37:56Z</DateTimeUtc>
                <DateTimeLocal>2017-09-28T04:37:56</DateTimeLocal>
                <User>
                    <Id>4975535a-2690-4492-bc7f-5e8a7d839cb9</Id>
                    <Name>Marcel De Doncker</Name>
                    <DayProgramId xsi:nil="true"/>
                </User>
                <Vehicle>
                    <Id>52e01d9c-96fa-46ed-98fe-f62e1792f019</Id>
                    <Code>7080</Code>
                    <Name>Auto: Dacia Dokker 1-PAE-120</Name>
                    <VehicleTypeId xsi:nil="true"/>
                    <LastSyncDateUtc xsi:nil="true"/>
                </Vehicle>
                <Type>StartMovementDriver</Type>
                <Location>
                <Address>
                    <Street>Kapelleveld</Street>
                    <HouseNumber>49</HouseNumber>
                    <PostalCode>1785</PostalCode>
                    <City>Merchtem</City>
                    <Submunicipality>Merchtem</Submunicipality>
                    <Country>Belgium</Country>
                </Address>
                <Longitude>4.2380828857421875</Longitude>
                <Latitude>50.9540901184082</Latitude>
                </Location>
                <Pois/>
                <IsManual>false</IsManual>
            </ClockingEntity>
        </Clocking_GetByDateRangeUtcResult>
    </Clocking_GetByDateRangeUtcResponse>
</soap:Body>
</soap:Envelope>

我使用以下查询将文件加载到SQL中:

SQL QUERY

DECLARE @XmlFile XML

SELECT @XmlFile = BulkColumn  
FROM OPENROWSET(BULK 'C:\Temp\GeoDynamics\Downloads\GeoPers.xml', SINGLE_BLOB) x

SELECT 
    Id = resource.value('(Id)[1]', 'varchar(255)'),
    DateTimeUtc = resource.value('(DateTimeUtc)[2]', 'varchar(255)'),
    DateTimeLocal = resource.value('(DateTimeLocal)[3]', 'varchar(255)'),
    UserID = resource.value('(User/Id)[4]', 'varchar(255)'),
    UserName = resource.value('(User/Name)[5]', 'varchar(255)'),
    VehicleID = resource.value('(Vehicle/Id)[6]', 'varchar(255)'),
    VehicleCode = resource.value('(Vehicle/Code)[7]', 'varchar(255)'),
    VehicleName = resource.value('(Vehicle/Name)[8]', 'varchar(255)')
 FROM
@XmlFile.nodes('//Clocking_GetByDateRangeUtcResponse/Clocking_GetByDateRangeUtcResult/ClockingEntity') AS XTbl1(resource)

查询没有结果,甚至没有错误代码。我不知道查询中哪里出错了。

2 个答案:

答案 0 :(得分:1)

主要问题是您的XML有一个默认命名空间(http://www.geodynamics.be/webservices)。您需要使用the WITH XMLNAMESPACES directive为查询指定该命名空间。

正如在另一个答案中所提到的,您还需要修复XPath查询中的索引 - 它们都应该是[1]

WITH XMLNAMESPACES (DEFAULT 'http://www.geodynamics.be/webservices')
SELECT 
    Id = resource.value('(Id)[1]', 'varchar(255)'),
    DateTimeUtc = resource.value('(DateTimeUtc)[1]', 'varchar(255)'),
    DateTimeLocal = resource.value('(DateTimeLocal)[1]', 'varchar(255)'),
    UserID = resource.value('(User/Id)[1]', 'varchar(255)'),
    UserName = resource.value('(User/Name)[1]', 'varchar(255)'),
    VehicleID = resource.value('(Vehicle/Id)[1]', 'varchar(255)'),
    VehicleCode = resource.value('(Vehicle/Code)[1]', 'varchar(255)'),
    VehicleName = resource.value('(Vehicle/Name)[1]', 'varchar(255)')
FROM
    @XmlFile.nodes('//Clocking_GetByDateRangeUtcResponse/Clocking_GetByDateRangeUtcResult/ClockingEntity') AS XTbl1(resource);

输出:

Id                af261a77-a35b-4778-a175-6fd50d00cde1
DateTimeUtc       2017-09-28T02:37:56Z
DateTimeLocal     2017-09-28T04:37:56
UserID            4975535a-2690-4492-bc7f-5e8a7d839cb9
UserName          Marcel De Doncker
VehicleID         52e01d9c-96fa-46ed-98fe-f62e1792f019
VehicleCode       7080
VehicleName       Auto: Dacia Dokker 1-PAE-120

Add Namespaces to Queries with WITH XMLNAMESPACES

答案 1 :(得分:1)

这会奏效。您没有选择正确的命名空间;请使用WITH XMLNAMESPACES。其次,除Id元素外,您选择的索引错误;您指定的索引[n]将选择元素的第n次出现。你总是需要第一个。

DECLARE @x XML=N'
<soap:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
    <Clocking_GetByDateRangeUtcResponse xmlns="http://www.geodynamics.be/webservices">
        <Clocking_GetByDateRangeUtcResult>
            <ClockingEntity>
                <Id>af261a77-a35b-4778-a175-6fd50d00cde1</Id>
                <DateTimeUtc>2017-09-28T02:37:56Z</DateTimeUtc>
                <DateTimeLocal>2017-09-28T04:37:56</DateTimeLocal>
                <User>
                    <Id>4975535a-2690-4492-bc7f-5e8a7d839cb9</Id>
                    <Name>Marcel De Doncker</Name>
                    <DayProgramId xsi:nil="true"/>
                </User>
                <Vehicle>
                    <Id>52e01d9c-96fa-46ed-98fe-f62e1792f019</Id>
                    <Code>7080</Code>
                    <Name>Auto: Dacia Dokker 1-PAE-120</Name>
                    <VehicleTypeId xsi:nil="true"/>
                    <LastSyncDateUtc xsi:nil="true"/>
                </Vehicle>
                <Type>StartMovementDriver</Type>
                <Location>
                <Address>
                    <Street>Kapelleveld</Street>
                    <HouseNumber>49</HouseNumber>
                    <PostalCode>1785</PostalCode>
                    <City>Merchtem</City>
                    <Submunicipality>Merchtem</Submunicipality>
                    <Country>Belgium</Country>
                </Address>
                <Longitude>4.2380828857421875</Longitude>
                <Latitude>50.9540901184082</Latitude>
                </Location>
                <Pois/>
                <IsManual>false</IsManual>
            </ClockingEntity>
        </Clocking_GetByDateRangeUtcResult>
    </Clocking_GetByDateRangeUtcResponse>
</soap:Body>
</soap:Envelope>';
WITH XMLNAMESPACES(DEFAULT 'http://www.geodynamics.be/webservices' )
SELECT 
    Id = resource.value('(Id)[1]', 'varchar(255)'),
    DateTimeUtc = resource.value('(DateTimeUtc)[1]', 'varchar(255)'),
    DateTimeLocal = resource.value('(DateTimeLocal)[1]', 'varchar(255)'),
    UserID = resource.value('(User/Id)[1]', 'varchar(255)'),
    UserName = resource.value('(User/Name)[1]', 'varchar(255)'),
    VehicleID = resource.value('(Vehicle/Id)[1]', 'varchar(255)'),
    VehicleCode = resource.value('(Vehicle/Code)[1]', 'varchar(255)'),
    VehicleName = resource.value('(Vehicle/Name)[1]', 'varchar(255)')
 FROM
    @x.nodes('//Clocking_GetByDateRangeUtcResponse/Clocking_GetByDateRangeUtcResult/ClockingEntity') AS XTbl1(resource)