将不规则的xml文件传递给存储过程

时间:2016-11-17 10:21:38

标签: sql sql-server xml stored-procedures

我有一个样本xml如下。我试图获取所有或特定数据,然后插入我的sql表,其中有相同的列表示来自xml的值。我查看了一些解决方案,但xml文件没有像我在这里那样格式化。你能救我吗?

<?xml version="1.0" encoding="UTF-8" standalone="true"?> 
<VehicleStatusResponse xmlns:ns2= 
  "http://fms-standard.com/rfms/v1.0.0/xsd/common/position" xmlns="http://fms-standard.com/rfms/v1.0.0/xsd/status"> 
<VehicleStatus> 
       <VIN>VF254ANA735752628</VIN> 
       <TriggerType>TIMER</TriggerType> 
       <CreatedDateTime>2014-09-08T09:30:20</CreatedDateTime> 
       <ReceivedDateTime>2014-09-08T09:30:57</ReceivedDateTime> 
       <GNSSPosition> 
              <ns2:Latitude>49.18557</ns2:Latitude> 
              <ns2:Longitude>11.18557</ns2:Longitude> 
              <ns2:Heading>33</ns2:Heading> 
              <ns2:Altitude>500</ns2:Altitude> 
              <ns2:Speed>16.4</ns2:Speed> 
              <ns2:PositionDateTime>2014-09-08T09:30:20</ns2:PositionDateTime> 
       </GNSSPosition> 
       <WheelBasedSpeed>16.07</WheelBasedSpeed> 
       <TachographSpeed>15.83</TachographSpeed> 
       <HRTotalVehicleDistance>817.5</HRTotalVehicleDistance> 
       <EngineTotalFuelUsed>575</EngineTotalFuelUsed> 
       <FuelLevel1>83</FuelLevel1> 
       <CatalystFuelLevel>88.48</CatalystFuelLevel> 
       <GrossCombinationVehicleWeight>10000</GrossCombinationVehicleWeight> 
</VehicleStatus> 
</VehicleStatusResponse>

2 个答案:

答案 0 :(得分:1)

首先,您需要将值放入类型为XML的声明变量或XML类型的数据表列中。由于您的XML包含名称空间,因此您必须先在WITH XMLNAMESPACES中声明它们。您可以使用通配符语法(*:),但最好尽可能具体。

.nodes()来电导航至<VehicleStatus>等级。以下所有元素都只是1:1,易于阅读......

你可以这样试试:

DECLARE @xml XML=
N'<VehicleStatusResponse xmlns:ns2= 
  "http://fms-standard.com/rfms/v1.0.0/xsd/common/position" xmlns="http://fms-standard.com/rfms/v1.0.0/xsd/status"> 
<VehicleStatus> 
       <VIN>VF254ANA735752628</VIN> 
       <TriggerType>TIMER</TriggerType> 
       <CreatedDateTime>2014-09-08T09:30:20</CreatedDateTime> 
       <ReceivedDateTime>2014-09-08T09:30:57</ReceivedDateTime> 
       <GNSSPosition> 
              <ns2:Latitude>49.18557</ns2:Latitude> 
              <ns2:Longitude>11.18557</ns2:Longitude> 
              <ns2:Heading>33</ns2:Heading> 
              <ns2:Altitude>500</ns2:Altitude> 
              <ns2:Speed>16.4</ns2:Speed> 
              <ns2:PositionDateTime>2014-09-08T09:30:20</ns2:PositionDateTime> 
       </GNSSPosition> 
       <WheelBasedSpeed>16.07</WheelBasedSpeed> 
       <TachographSpeed>15.83</TachographSpeed> 
       <HRTotalVehicleDistance>817.5</HRTotalVehicleDistance> 
       <EngineTotalFuelUsed>575</EngineTotalFuelUsed> 
       <FuelLevel1>83</FuelLevel1> 
       <CatalystFuelLevel>88.48</CatalystFuelLevel> 
       <GrossCombinationVehicleWeight>10000</GrossCombinationVehicleWeight> 
</VehicleStatus> 
</VehicleStatusResponse>';

- 这是查询

WITH XMLNAMESPACES(DEFAULT 'http://fms-standard.com/rfms/v1.0.0/xsd/status'
                          ,'http://fms-standard.com/rfms/v1.0.0/xsd/common/position' AS ns2)
SELECT vs.value('VIN[1]','nvarchar(max)') AS VehicleStatus_VIN
      ,vs.value('TriggerType[1]','nvarchar(max)') AS VehicleStatus_TriggerType
      ,vs.value('CreatedDateTime[1]','datetime') AS VehicleStatus_CreatedDateTime
      ,vs.value('ReceivedDateTime[1]','datetime') AS VehicleStatus_ReceivedDateTime
      ,vs.value('(GNSSPosition/ns2:Latitude)[1]','decimal(14,6)') AS VehicleStatus_GNSSPosition_Latitude
      ,vs.value('(GNSSPosition/ns2:Longitude)[1]','decimal(14,6)') AS VehicleStatus_GNSSPosition_Longitude
      /*other columns follow the same pattern*/
FROM @xml.nodes('/VehicleStatusResponse/VehicleStatus') AS A(vs)

更新:插入表

最简单的方法是将此调用包装为CTE,如

WITH XMLNAMESPACES(...)
,DerivedTableCTE AS
(
   The query here
)
INSERT INTO YourTable (col1, col2, col3, ...)
SELECT col1, col2, col3, ...
FROM DerivedTableCTE

答案 1 :(得分:1)

如果删除或修改声明,则可以使用XML类型和XML方法。 SQL Server XML类型仅支持UCS-2编码,不识别“独立”。下面的示例使用字符串操作来调整声明。您需要根据实际的列类型更改数据类型,并应在INSERT语句中指定显式列列表。我在此示例中省略了这一点,因为我不想假设您的实际表列与XML中的元素名称匹配。

DECLARE @xml xml;
DECLARE @xmlString nvarchar(MAX) = N'<?xml version="1.0" encoding="UTF-8" standalone="true"?> 
<VehicleStatusResponse xmlns:ns2= 
  "http://fms-standard.com/rfms/v1.0.0/xsd/common/position" xmlns="http://fms-standard.com/rfms/v1.0.0/xsd/status"> 
<VehicleStatus> 
       <VIN>VF254ANA735752628</VIN> 
       <TriggerType>TIMER</TriggerType> 
       <CreatedDateTime>2014-09-08T09:30:20</CreatedDateTime> 
       <ReceivedDateTime>2014-09-08T09:30:57</ReceivedDateTime> 
       <GNSSPosition> 
              <ns2:Latitude>49.18557</ns2:Latitude> 
              <ns2:Longitude>11.18557</ns2:Longitude> 
              <ns2:Heading>33</ns2:Heading> 
              <ns2:Altitude>500</ns2:Altitude> 
              <ns2:Speed>16.4</ns2:Speed> 
              <ns2:PositionDateTime>2014-09-08T09:30:20</ns2:PositionDateTime> 
       </GNSSPosition> 
       <WheelBasedSpeed>16.07</WheelBasedSpeed> 
       <TachographSpeed>15.83</TachographSpeed> 
       <HRTotalVehicleDistance>817.5</HRTotalVehicleDistance> 
       <EngineTotalFuelUsed>575</EngineTotalFuelUsed> 
       <FuelLevel1>83</FuelLevel1> 
       <CatalystFuelLevel>88.48</CatalystFuelLevel> 
       <GrossCombinationVehicleWeight>10000</GrossCombinationVehicleWeight> 
</VehicleStatus> 
</VehicleStatusResponse>';

SET @xmlString = REPLACE(@xmlString, 'encoding="UTF-8"', 'encoding="UCS-2"');
SET @xmlString = REPLACE(@xmlString, 'standalone="true"', '');
SET @xml = @xmlString;

WITH XMLNAMESPACES (
      DEFAULT 'http://fms-standard.com/rfms/v1.0.0/xsd/status'
    ,'http://fms-standard.com/rfms/v1.0.0/xsd/common/position' AS ns2
    )
INSERT INTO dbo.YourTable
    SELECT
          @xml.value('(/VehicleStatusResponse/VehicleStatus/VIN)[1]', 'varchar(50)')
        , @xml.value('(/VehicleStatusResponse/VehicleStatus/TriggerType)[1]', 'varchar(50)')
        , @xml.value('(/VehicleStatusResponse/VehicleStatus/CreatedDateTime)[1]', 'datetime2(3)')
        , @xml.value('(/VehicleStatusResponse/VehicleStatus/ReceivedDateTime)[1]', 'datetime2(3)')
        , @xml.value('(/VehicleStatusResponse/VehicleStatus/GNSSPosition/ns2:Latitude)[1]', 'decimal(8,5)')
        , @xml.value('(/VehicleStatusResponse/VehicleStatus/GNSSPosition/ns2:Longitude)[1]', 'decimal(8,5)')
        , @xml.value('(/VehicleStatusResponse/VehicleStatus/GNSSPosition/ns2:Heading)[1]', 'int')
        , @xml.value('(/VehicleStatusResponse/VehicleStatus/GNSSPosition/ns2:Altitude)[1]', 'int')
        , @xml.value('(/VehicleStatusResponse/VehicleStatus/GNSSPosition/ns2:Speed)[1]', 'decimal(8,3)')
        , @xml.value('(/VehicleStatusResponse/VehicleStatus/GNSSPosition/ns2:PositionDateTime)[1]', 'datetime2(3)')
        , @xml.value('(/VehicleStatusResponse/VehicleStatus/WheelBasedSpeed)[1]', 'decimal(8,3)')
        , @xml.value('(/VehicleStatusResponse/VehicleStatus/TachographSpeed)[1]', 'decimal(8,3)')
        , @xml.value('(/VehicleStatusResponse/VehicleStatus/HRTotalVehicleDistance)[1]', 'decimal(8,3)')
        , @xml.value('(/VehicleStatusResponse/VehicleStatus/EngineTotalFuelUsed)[1]', 'int')
        , @xml.value('(/VehicleStatusResponse/VehicleStatus/CatalystFuelLevel)[1]', 'decimal(8,3)')
        , @xml.value('(/VehicleStatusResponse/VehicleStatus/GrossCombinationVehicleWeight)[1]', 'int');