将 XML 数据上传到 SQL Server
Posted
技术标签:
【中文标题】将 XML 数据上传到 SQL Server【英文标题】:Uploading XML data into SQL Server 【发布时间】:2021-12-02 03:50:16 【问题描述】:这对我来说是一项新任务,过去一周我读了很多关于 OPENXML、xpath 和各种有趣的东西,但我仍在努力将这些 XML 数据推送到我的数据库中。我不能共享 XML 数据,因为它很敏感,但它大部分都是元素,有几个兄弟节点和几个子节点。这是我的代码:
SELECT DISTINCT
MY_XML.Inspection.query('inspectionId').value('.', 'INT'),
MY_XML.Inspection.query('InspReportID').value('.', 'VARCHAR(50)'),
MY_XML.Inspection.query('InspectionPostDate').value('.', 'DATE'),
MY_XML.Inspection.query('InspStartDate').value('.', 'DATE'),
MY_XML.Inspection.query('InspStartTime').value('.', 'INT'),
MY_XML.Inspection.query('InspEndTime').value('.', 'INT'),
MY_XML.Inspection.query('InspectionLevelId').value('.', 'INT'),
MY_XML.Inspection.query('InspectionLevelDesc').value('.', 'VARCHAR(50)'),
MY_XML.Inspection.query('PostAccidentIndicator').value('.', 'VARCHAR(20)'),
Location.L.query('InspLocationCode').value('.', 'VARCHAR(50)'),
Location.L.query('InspLocationText').value('.', 'VARCHAR(50)'),
Violations.V.query('InspTotalOOSVioNum').value('.', 'INT'),
Driver.D.query('DriverLastName').value('.','VARCHAR(100)')
FROM (SELECT CAST(MY_XML AS xml)
FROM OPENROWSET(BULK 'C:\InspectionXML2.xml', SINGLE_BLOB) AS T(MY_XML)) AS T(MY_XML)
OUTER APPLY MY_XML.nodes('Inspections/Inspection/InspMain') AS MY_XML (Inspection)
OUTER APPLY MY_XML.nodes('Inspections/Inspection/InspMain/InspLocation') AS Location (L)
OUTER APPLY MY_XML.nodes('Inspections/Inspection/InspMain/InspTotalCounts') AS Violations (V)
OUTER APPLY MY_XML.nodes('Inspections/Inspection/Drivers/Driver') AS Driver (D)
ORDER BY 1;
此代码非常适合上传一个检查,但我需要上传几个,并且数据混合和匹配都错了!请帮忙,我对新方法持开放态度。我正在研究自动转换器,所以请帮忙!
1)
<?xml version="1.0"?>
-<Inspections schemaVersionCode="2.3" sourceSystemCode="COMPASS">
-<Inspection>
-<InspMain>
<inspectionId>123</inspectionId>
<InspReportID>OH-123</InspReportID>
<InspectionPostDate>10/07/2021</InspectionPostDate>
<InspStartDate>10/07/2021</InspStartDate>
<InspStartTime>0945</InspStartTime>
<InspEndTime>1200</InspEndTime>
<InspectionLevelId>1</InspectionLevelId>
<InspectionLevelDesc>FULL</InspectionLevelDesc>
<PostAccidentIndicator>NO</PostAccidentIndicator>
-<InspLocation>
<InspLocationCode>FIXED SITE</InspLocationCode>
<InspLocationText>CAMBRIDGES</InspLocationText>
</InspLocation>
<InspHazmatTypeCode/>
-<InspTotalCounts>
<InspTotalOOSVioNum>2</InspTotalOOSVioNum>
</InspTotalCounts>
</InspMain>
-<Drivers>
-<Driver>
<DriverLastName>RODNEY</DriverLastName>
<DriverBirthDate>12/31/1900</DriverBirthDate>
<DriverLicenseID>123</DriverLicenseID>
<DriverLicenseStateCode>OH</DriverLicenseStateCode>
</Driver>
</Drivers>
-<Vehicles>
-<Vehicle>
<VehicleUnitNum>1</VehicleUnitNum>
<VehicleUnitTypeCode>TRUCK TRACTOR</VehicleUnitTypeCode>
<VehicleMakeCode>INTL</VehicleMakeCode>
<VehicleCompanyID>123</VehicleCompanyID>
<VehicleLicenseID>AG123</VehicleLicenseID>
<VehicleLicenseStateCode>PA</VehicleLicenseStateCode>
<IEPDotNumber/>
</Vehicle>
-<Vehicle>
<VehicleUnitNum>2</VehicleUnitNum>
<VehicleUnitTypeCode>SEMI-TRAILER</VehicleUnitTypeCode>
<VehicleMakeCode>TRLK</VehicleMakeCode>
<VehicleCompanyID>1234</VehicleCompanyID>
<VehicleLicenseID>1234</VehicleLicenseID>
<VehicleLicenseStateCode>OK</VehicleLicenseStateCode>
<IEPDotNumber/>
</Vehicle>
</Vehicles>
-<Violations>
-<Violation>
<VioseqID>5</VioSeqID>
<VioRegSectionCode>NO</VioRegSectionCode>
<VioDescText>NO</VioDescText>
<VioOOSFlag>YES</VioOOSFlag>
<VehicleUnitCode>D</VehicleUnitCode>
<ViolPartSection>395.8(a)(1)</ViolPartSection>
<StateCitationNumber/>
<ViolationCategory>NO LOG BOOK,LOG NOT CURRENT,GENERAL LOG VIOLATIONS</ViolationCategory>
<SectionDesc>ELD - No record of duty status (ELD Required)</SectionDesc>
<IEPAttrFlag/>
<StateCitationResult>N/A</StateCitationResult>
</Violation>
-<Violation>
<VioSeqID>1</VioSeqID>
<VioRegSectionCode>NO</VioRegSectionCode>
<VioDescText>NO</VioDescText>
<VioOOSFlag>NO</VioOOSFlag>
<VehicleUnitCode>D</VehicleUnitCode>
<ViolPartSection>392.2</ViolPartSection>
<StateCitationNumber/>
<ViolationCategory>ALL OTHER DRIVER VIOLATIONS</ViolationCategory>
<SectionDesc>Miscellaneous Traffic Law Violation</SectionDesc>
<IEPAttrFlag/>
<StateCitationResult>N/A</StateCitationResult>
</Violation>
-<Violation>
<VioSeqID>3</VioSeqID>
<VioRegSectionCode>NO</VioRegSectionCode>
<VioDescText>NO</VioDescText>
<VioOOSFlag>NO</VioOOSFlag>
<VehicleUnitCode>1</VehicleUnitCode>
<ViolPartSection>393.45(d)</ViolPartSection>
<StateCitationNumber/>
<ViolationCategory>BRAKES, ALL OTHERS</ViolationCategory>
<SectionDesc>Brake Connections with Leaks Under Vehicle</SectionDesc>
<IEPAttrFlag/>
<StateCitationResult>N/A</StateCitationResult>
</Violation>
-<Violation>
<VioSeqID>2</VioSeqID>
<VioRegSectionCode>NO</VioRegSectionCode>
<VioDescText>NO</VioDescText>
<VioOOSFlag>NO</VioOOSFlag>
<VehicleUnitCode>1</VehicleUnitCode>
<ViolPartSection>393.45(d)</ViolPartSection>
<StateCitationNumber/>
<ViolationCategory>BRAKES, ALL OTHERS</ViolationCategory>
<SectionDesc>Brake Connections with Leaks - Connection to Power Unit</SectionDesc>
<IEPAttrFlag/>
<StateCitationResult>N/A</StateCitationResult>
</Violation>
-<Violation>
<VioSeqID>4</VioSeqID>
<VioRegSectionCode/>
<VioDescText>NO</VioDescText>
<VioOOSFlag>YES</VioOOSFlag>
<VehicleUnitCode>1</VehicleUnitCode>
<ViolPartSection>396.3(a)(1)</ViolPartSection>
<StateCitationNumber/>
<ViolationCategory>BRAKES, ALL OTHERS</ViolationCategory>
<SectionDesc>Brake system pressure loss</SectionDesc>
<IEPAttrFlag/>
<StateCitationResult>N/A</StateCitationResult>
</Violation>
-<Violation>
<VioSeqID>6</VioSeqID>
<VioRegSectionCode>NO</VioRegSectionCode>
<VioDescText>NO</VioDescText>
<VioOOSFlag>NO</VioOOSFlag>
<VehicleUnitCode>1</VehicleUnitCode>
<ViolPartSection>393.9(a)</ViolPartSection>
<StateCitationNumber/>
<ViolationCategory>LIGHTING</ViolationCategory>
<SectionDesc>Inoperative turn signal</SectionDesc>
<IEPAttrFlag/>
<StateCitationResult>N/A</StateCitationResult>
</Violation>
</Violations>
<StatusCode>YES</StatusCode>
</Inspection>
-<Inspection>
-<InspMain>
<inspectionId>12345</inspectionId>
<InspReportID>NC-1234</InspReportID>
<InspectionPostDate>10/08/2021</InspectionPostDate>
<InspStartDate>10/08/2021</InspStartDate>
<InspStartTime>0800</InspStartTime>
<InspEndTime>0900</InspEndTime>
<InspectionLevelId>3</InspectionLevelId>
<InspectionLevelDesc>DRIVER-ONLY</InspectionLevelDesc>
<PostAccidentIndicator>NO</PostAccidentIndicator>
-<InspLocation>
<InspLocationCode>ROADSIDE</InspLocationCode>
<InspLocationText>GOLden</InspLocationText>
</InspLocation>
<InspHazmatTypeCode/>
-<InspTotalCounts>
<InspTotalOOSVioNum>0</InspTotalOOSVioNum>
</InspTotalCounts>
</InspMain>
-<Drivers>
-<Driver>
<DriverLastName>joe schmoe</DriverLastName>
<DriverBirthDate>05/05/1888</DriverBirthDate>
<DriverLicenseID>1234</DriverLicenseID>
<DriverLicenseStateCode>FL</DriverLicenseStateCode>
</Driver>
</Drivers>
-<Vehicles>
-<Vehicle>
<VehicleUnitNum>1</VehicleUnitNum>
<VehicleUnitTypeCode>TRUCK TRACTOR</VehicleUnitTypeCode>
<VehicleMakeCode>PTRB</VehicleMakeCode>
<VehicleCompanyID>1234</VehicleCompanyID>
<VehicleLicenseID>1234</VehicleLicenseID>
<VehicleLicenseStateCode>TX</VehicleLicenseStateCode>
<IEPDotNumber/>
</Vehicle>
-<Vehicle>
<VehicleUnitNum>2</VehicleUnitNum>
<VehicleUnitTypeCode>SEMI-TRAILER</VehicleUnitTypeCode>
<VehicleMakeCode>FONA</VehicleMakeCode>
<VehicleCompanyID>1234</VehicleCompanyID>
<VehicleLicenseID>1234</VehicleLicenseID>
<VehicleLicenseStateCode>TX</VehicleLicenseStateCode>
<IEPDotNumber/>
</Vehicle>
</Vehicles>
-<Violations>
-<Violation>
<VioSeqID>1</VioSeqID>
<VioRegSectionCode>NO</VioRegSectionCode>
<VioDescText>NO</VioDescText>
<VioOOSFlag>NO</VioOOSFlag>
<VehicleUnitCode>D</VehicleUnitCode>
<ViolPartSection>392.2</ViolPartSection>
<StateCitationNumber/>
<ViolationCategory>FAILURE TO OBEY TRAFFIC CONTROL DEVICE</ViolationCategory>
<SectionDesc>Failure to obey traffic control device</SectionDesc>
<IEPAttrFlag/>
<StateCitationResult>N/A</StateCitationResult>
</Violation>
</Violations>
<StatusCode>NO</StatusCode>
</Inspection>
</Inspections>
2) 将检查上传到数据库 3)每次检查一排,无错配 4) SQL Server 2016
【问题讨论】:
提问时,您需要提供minimal reproducible example: (1) DDL 和样本数据填充,即 CREATE 表和 INSERT T-SQL 语句。 (2) 你需要做什么,即逻辑和你的代码尝试在 T-SQL 中实现它。 (3) 期望的输出,基于上述#1 中的样本数据。 (4) 您的 SQL Server 版本 (SELECT @@version;)。 请提供 (1) 您的目标表 DDL,(2) 带有混淆值的真实输入 XML。 目标表目前不是问题,只需选择即可,一旦结果看起来不错,我就可以构建表并插入数据。 (2) 即将推出。 XML 已启动!谢谢! 【参考方案1】:请尝试以下解决方案。
SQL
WITH rs (xmlData) AS
(
SELECT TRY_CAST(BulkColumn AS XML)
FROM OPENROWSET(BULK N'e:\Temp\InspectionXML2.xml', SINGLE_BLOB) AS x
)
--INSERT INTO targetTable (...)
SELECT c.value('(InspMain/inspectionId/text())[1]', 'INT') AS inspectionId
, c.value('(InspMain/InspReportID/text())[1]', 'VARCHAR(50)') AS InspReportID
, c.value('(InspMain/InspectionPostDate/text())[1]', 'VARCHAR(20)') AS InspectionPostDate
, c.value('(InspMain/InspStartDate/text())[1]', 'DATE') AS InspStartDate
, c.value('(InspMain/InspStartTime/text())[1]', 'INT')AS InspStartTime
, c.value('(InspMain/InspEndTime/text())[1]', 'INT') AS InspEndTime
, c.value('(InspMain/InspectionLevelId/text())[1]', 'INT') AS InspectionLevelId
, c.value('(InspMain/InspectionLevelDesc/text())[1]', 'VARCHAR(50)') AS InspectionLevelDesc
, c.value('(InspMain/PostAccidentIndicator/text())[1]', 'VARCHAR(20)') AS PostAccidentIndicator
, c.value('(InspMain/InspLocation/InspLocationCode/text())[1]', 'VARCHAR(50)') AS InspLocationCode
, c.value('(InspMain/InspLocation/InspLocationText/text())[1]', 'VARCHAR(50)') AS InspLocationText
, c.value('(InspMain/InspTotalCounts/InspTotalOOSVioNum/text())[1]', 'INT') AS InspTotalOOSVioNum
, c.value('(Drivers/Driver/DriverLastName/text())[1]','VARCHAR(100)') AS DriverLastName
FROM rs
CROSS APPLY xmlData.nodes('/Inspections/Inspection') AS t(c);
输出
+--------------+--------------+--------------------+---------------+---------------+-------------+-------------------+---------------------+-----------------------+------------------+------------------+--------------------+----------------+
| inspectionId | InspReportID | InspectionPostDate | InspStartDate | InspStartTime | InspEndTime | InspectionLevelId | InspectionLevelDesc | PostAccidentIndicator | InspLocationCode | InspLocationText | InspTotalOOSVioNum | DriverLastName |
+--------------+--------------+--------------------+---------------+---------------+-------------+-------------------+---------------------+-----------------------+------------------+------------------+--------------------+----------------+
| 123 | OH123 | 10/07/2021 | 2021-10-07 | 945 | 1200 | 1 | FULL | NO | FIXED SITE | CAMBRIDGES | 2 | RODNEY |
| 12345 | NC1234 | 10/08/2021 | 2021-10-08 | 800 | 900 | 3 | DRIVERONLY | NO | ROADSIDE | GOLden | 0 | joe schmoe |
+--------------+--------------+--------------------+---------------+---------------+-------------+-------------------+---------------------+-----------------------+------------------+------------------+--------------------+----------------+
【讨论】:
这太棒了,干得好!非常感谢你,我很聪明,可以从这里推断其余的信不信由你,哈哈。标记为解决方案。保重,我希望宇宙用业力祝福你。以上是关于将 XML 数据上传到 SQL Server的主要内容,如果未能解决你的问题,请参考以下文章
将数据从 webscraper 上传到 SQL server
将数据从 sql server 增量上传到 Amazon Redshift [关闭]
Winforms:如何使用 C# 将图片上传到 SQL Server 数据库
从C#中的数据中删除特殊字符后如何将dbf文件中的数百万行数据上传到SQL Server