将xml文件导入SQL表

时间:2016-05-18 16:12:54

标签: sql sql-server xml

我在SQL查询中有这段代码:

CREATE TABLE Products(
 P VARCHAR(30));

 Select *
 from products

 Declare @x xml

 Select @x=P
 from openrowset (BULK 'C:\xmltest.xml', Single_blob) AS Products(P)  

 Select @x

 Declare @hdoc int

 Exec sp_xml_preparedocument @hdoc OUTPUT, @x

 select *
 From openxml (@hdoc, '/reservationDetailsResponse/reservation', 2)
 with ( reservationNo int

  )

Exec sp_xml_removedocument @hdoc

我导入一个名为“xmltest”的xml文件,xml文件如下所示:

<reservationDetailsResponse xmlns="http://webservices.de/webservices/franchis/1.03" xmlns:xsi="http://www.w.org/20/XMLSchema-instance">
  <reservation>
    <reservationNo>9833591183</reservationNo>
    <securityCode>ad4badfd52</securityCode>
    <reference1 xsi:nil="true" />
    <reference2 xsi:nil="true" />
    <status>RS</status>
    <revision xsi:nil="true" />
    <language>es_ES</language>
    <group>CFMR</group>
    <duration>7</duration>
    <voucherDays xsi:nil="true" />
    <isLongterm>false</isLongterm>
    <hasOwnInsurance>false</hasOwnInsurance>
    <vipStatus xsi:nil="true" />
    <customerRemark xsi:nil="true" />
    <stationRemark>PREPAID, DRIVER MUST BE (System, 23.12.2015, 18:07:07)</stationRemark>
    <flightNo>U2</flightNo>
    <bonusProgramNo xsi:nil="true" />
    <hasOnlinePaymentGuarantee>false</hasOnlinePaymentGuarantee>
  </reservation>
</reservationDetailsResponse>

此代码适用于我拥有的另一个xml文件,但是这个不同,结果总是给出一个空表列(不显示reservationNO值)。 xml文件中还有许多保留(重复),但我只粘贴了第一部分。 xml文件reservationDetailsResponse中的第一行可能会导致这种情况,但我不确定。

2 个答案:

答案 0 :(得分:1)

如果可能的话,您应该尝试使用 ad-hoc SQL进行基于 set 的方法:

试试这个:

WITH XMLNAMESPACES('http://www.w.org/20/XMLSchema-instance' AS xsi
                   ,DEFAULT 'http://webservices.de/webservices/franchis/1.03')
,MyXML(XmlContent) AS
(
    SELECT CAST(P AS XML) FROM OPENROWSET (BULK 'C:\xmltest.xml', SINGLE_BLOB) AS Products(P)  
)
SELECT reservation.value('reservationNo[1]','bigint') AS reservationNo
      ,reservation.value('securityCode[1]','nvarchar(max)') AS securityCode
      ,reservation.value('reference1[1]/@xsi:nil','bit') AS reference1IsNull
      ,reservation.value('reference1[1]','nvarchar(max)') AS reference1
      --add other columns following this schema
FROM MyXML
CROSS APPLY MyXML.XmlContent.nodes('/reservationDetailsResponse/reservation') AS A(reservation)

简短说明

您必须定义名称空间才能使用它们。好吧,允许在所有名称前加上*:(这意味着任何命名空间),但一般建议是:尽可能具体!

BULK LOAD在CTE内完成。

由于reservation方法的使用,即使XML中有许多.nodes()个节点也可以使用。

结果将是带有XML内容的表格式结果集。

无需调用任何存储过程......

答案 1 :(得分:0)

这是definitley XML名称空间问题。您必须为文档明确定义默认命名空间(即给它一些名称,我给Exec sp_xml_preparedocument @hdoc OUTPUT, @x, '<reservationDetailsResponse xmlns:z="http://webservices.de/webservices/franchis/1.03"/>'; select * From openxml (@hdoc, '/z:reservationDetailsResponse/z:reservation', 2) with ( reservationNo bigint 'z:reservationNo' ) )并在select中指定它。

@Component({
    selector: 'app',
    templateUrl: './views/app.component.html',
    directives: [ROUTER_DIRECTIVES, NavBarComponent]
})
@Routes([
    { path: '/home', component: TestComponent }
])
export class AppComponent implements OnInit {

    constructor(private router: Router) { }

    ngOnInit() {
        this.router.navigate(['/home']);
    }
}