我已成功将大部分XML文件解析到我的数据库中,但是我遇到以下节点/数据的问题。
XML数据示例:
我为每个不同的旅行类型设置了一个案例,但是它为每个案例时刻重复了数据库中的行。关于如何避免这种想法的任何想法?
SELECT
XC.value('../../@TransactionType', 'varchar(50)') TransactionType,
XC.value('../../@OrderItemRef', 'bigint')OrderRef,
XC.value('../../@TransactionDate', 'datetime')TransDate,
XC.value('../@JourneyTime', 'int')JourneyTime,
XC.value('../@Distance', 'nvarchar(10)' )Distance,
XC.value('@Ref', 'varchar(50)' )TicketRef,
ADC.value('@Organisation', 'varchar(50)' )Client,
ACC.value('@ExternalRef', 'varchar(50)' )Account,
DCC.value('@Address[1]', 'varchar(50)' )contactEmail,
BAC.value('@FirstName','varchar(50)' ) + ' ' + BAC.value ('@LastName','varchar(50)' ) Booker,
PC.value('@FirstName','varchar(50)' )travellerforename,
PC.value('@LastName','varchar(50)' )travellersurname,
ORC.value('@Name','Varchar(50)' )Origin,
DESTC.value('@Name','Varchar(50)' )Destination,
XC.value('@Route', 'varchar(50)' )Route,
XC.value('@Class' , 'varchar(50)' )Class,
XC.value('@Code' , 'varchar(50)' )TicketCode,
XC.value('@Name' , 'varchar(50)' )TicketType,
TOPC.value('@Name' , 'varchar(50)' )TrainOperator,
LEGC.value('@Departure' , 'Datetime' )TravelDate,
FAREC.value('@TotalAmount' , 'nvarchar(10)' )Fare,
FAREXC.value('@OfferedFare' , 'nvarchar(10)' )LowFare,
FAREXC.value('@NormalFare' , 'nvarchar(10)' )HighFare,
IDC.value('../@DeliveryMethod' , 'nvarchar(10)' )fulfilmentType,
FAREXC.value('@Reason' , 'varchar(50)' ) travelreason,
case when(CEC.value('@TransportType' , 'varchar(50)') = 'Rail') then
CEC.value('@Emissions', 'decimal(4,2)')
END AS [railCo2],
case when(CEC.value('@TransportType' , 'varchar(50)') = 'Aeroplane') then
CEC.value('@Emissions', 'decimal(4,2)')
END AS [airCo2],
case when(CEC.value('@TransportType' , 'varchar(50)') = 'Car - Diesel') then
CEC.value('@Emissions', 'decimal(4,2)')
END AS [CarDieselCo2],
case when(CEC.value('@TransportType' , 'varchar(50)') = 'Car - Petrol') then
CEC.value('@Emissions', 'decimal(4,2)')
END AS [CarDieselCo2],
case when(CEC.value('@TransportType' , 'varchar(50)') = 'Motorcycle') then
CEC.value('@Emissions', 'decimal(4,2)')
END AS [MotorcycleCo2]
FROM TempXML
cross apply
XMLData.nodes('my:Handoff/ImmediateDetail') AS IDT(IDC)
Cross Apply
IDC.nodes('Segment[1]/Ticket') AS XT(XC)
Cross apply
IDC.nodes('AccountContact/Address') AS ADT(ADC)
Cross apply
IDC.nodes('Account') AS ACT(ACC)
Cross apply
IDC.nodes('DeliveryContact/Email') AS DCT(DCC)
cross apply
IDC.nodes('BookingAgent/Person') AS BAT(BAC)
cross apply
IDC.nodes('PassengerGroup/Passenger/Person') AS PT(PC)
cross apply
IDC.nodes('Segment[1]/Origin') AS ORT(ORC)
cross apply
IDC.nodes('Segment[1]/Destination') AS DESTT(DESTC)
cross apply
IDC.nodes('Segment[1]/Leg[1]') AS LEGT(LEGC)
cross apply
IDC.nodes('Segment[1]/Leg[1]/TOC') AS TOPT(TOPC)
cross apply
IDC.nodes('Segment[1]/Ticket/Sale/Fare') AS FARET(FAREC)
cross apply
IDC.nodes('Segment[1]/Ticket/FareException') AS FAREXT(FAREXC)
cross apply
IDC.nodes('Segment[1]/CarbonEmissionDetails/CarbonEmissions') AS CET(CEC)
WHERE
LEGC.value('@Direction' , 'varchar(50)' ) = 'Outbound'
输出如下:
答案 0 :(得分:1)
您没有显示足够多的查询,但我的神奇玻璃灯泡告诉我,您正在使用APPLY YourXML.nodes(...) AS x(CEC)
来逐行检索值。每行都带有一个值,因此您的结果集每行将有一个值。
取消此.nodes()
- 致电并尝试使用以下内容:
SELECT SomeColumns
,YourXml.value(N'(//CarbonEmissions[@TransportType="Rail"]/@Emission)[1]',N'decimal(10,4)') AS railCo2
,YourXml.value(N'(//CarbonEmissions[@TransportType="Aeroplane"]/@Emission)[1]',N'decimal(10,4)') AS airCo2
,more columns like this
这个想法是:执行深度搜索(因此//
之前的CarbonEmissions
)并找到第一个元素,其中TransportType
等于字符串。
一般情况下,最好指定完整(或相对)XPath
而不是执行深度搜索,因此最好使用较长的路径而不是//CarbonEmissions
,但我不喜欢&# 39;不知道你的XML ......
我的神奇玻璃灯泡低声说出这样的话:
apply .nodes()
case
SELECT
XC.value('../../@TransactionType', 'varchar(50)') TransactionType,
XC.value('../../@OrderItemRef', 'bigint')OrderRef,
XC.value('../../@TransactionDate', 'datetime')TransDate,
XC.value('../@JourneyTime', 'int')JourneyTime,
XC.value('../@Distance', 'nvarchar(10)' )Distance,
XC.value('@Ref', 'varchar(50)' )TicketRef,
ADC.value('@Organisation', 'varchar(50)' )Client,
ACC.value('@ExternalRef', 'varchar(50)' )Account,
DCC.value('@Address[1]', 'varchar(50)' )contactEmail,
BAC.value('@FirstName','varchar(50)' ) + ' ' + BAC.value ('@LastName','varchar(50)' ) Booker,
PC.value('@FirstName','varchar(50)' )travellerforename,
PC.value('@LastName','varchar(50)' )travellersurname,
ORC.value('@Name','Varchar(50)' )Origin,
DESTC.value('@Name','Varchar(50)' )Destination,
XC.value('@Route', 'varchar(50)' )Route,
XC.value('@Class' , 'varchar(50)' )Class,
XC.value('@Code' , 'varchar(50)' )TicketCode,
XC.value('@Name' , 'varchar(50)' )TicketType,
TOPC.value('@Name' , 'varchar(50)' )TrainOperator,
LEGC.value('@Departure' , 'Datetime' )TravelDate,
FAREC.value('@TotalAmount' , 'nvarchar(10)' )Fare,
FAREXC.value('@OfferedFare' , 'nvarchar(10)' )LowFare,
FAREXC.value('@NormalFare' , 'nvarchar(10)' )HighFare,
IDC.value('../@DeliveryMethod' , 'nvarchar(10)' )fulfilmentType,
FAREXC.value('@Reason' , 'varchar(50)' ) travelreason,
CEC.value(N'(CarbonEmissions[@TransportType="Rail"]/@Emission)[1]',N'decimal(10,4)') AS railCo2,
CEC.value(N'(CarbonEmissions[@TransportType="Aeroplane"]/@Emission)[1]',N'decimal(10,4)') AS airCo2
--more of the same
FROM TempXML
cross apply
XMLData.nodes('my:Handoff/ImmediateDetail') AS IDT(IDC)
Cross Apply
IDC.nodes('Segment[1]/Ticket') AS XT(XC)
Cross apply
IDC.nodes('AccountContact/Address') AS ADT(ADC)
Cross apply
IDC.nodes('Account') AS ACT(ACC)
Cross apply
IDC.nodes('DeliveryContact/Email') AS DCT(DCC)
cross apply
IDC.nodes('BookingAgent/Person') AS BAT(BAC)
cross apply
IDC.nodes('PassengerGroup/Passenger/Person') AS PT(PC)
cross apply
IDC.nodes('Segment[1]/Origin') AS ORT(ORC)
cross apply
IDC.nodes('Segment[1]/Destination') AS DESTT(DESTC)
cross apply
IDC.nodes('Segment[1]/Leg[1]') AS LEGT(LEGC)
cross apply
IDC.nodes('Segment[1]/Leg[1]/TOC') AS TOPT(TOPC)
cross apply
IDC.nodes('Segment[1]/Ticket/Sale/Fare') AS FARET(FAREC)
cross apply
IDC.nodes('Segment[1]/Ticket/FareException') AS FAREXT(FAREXC)
cross apply
IDC.nodes('Segment[1]/CarbonEmissionDetails') AS CET(CEC)
WHERE
LEGC.value('@Direction' , 'varchar(50)' ) = 'Outbound'