Sql 使用xml.nodes解析xml文件时,数据库中存在重复行
我已成功地将大部分XML文件解析到数据库中,但我对以下节点/数据有问题 XML数据示例: 我为每种不同的旅行类型设置了一个case when,但是它为每种case when复制了数据库中的行。有没有办法避免这种情况Sql 使用xml.nodes解析xml文件时,数据库中存在重复行,sql,xml,duplicates,Sql,Xml,Duplicates,我已成功地将大部分XML文件解析到数据库中,但我对以下节点/数据有问题 XML数据示例: 我为每种不同的旅行类型设置了一个case when,但是它为每种case when复制了数据库中的行。有没有办法避免这种情况 SELECT XC.value('../../@TransactionType', 'varchar(50)') TransactionType, XC.value('../../@OrderItemRef', 'bigint')OrderRef, XC.value('..
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'
输出如下所示:
您没有显示足够的查询,但我的魔镜灯泡告诉我,您正在使用
将xml.nodes(…)作为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
其思想是:进行深入搜索(因此在碳排放
之前进行/
)并找到第一个元素,其中传输类型
等于给定的字符串
一般来说,最好指定完整(或相对)的XPath
而不是执行深度搜索,因此最好使用较长的路径,而不是///CarbonEmissions
,但我不知道您的XML
更新
我的魔幻玻璃灯泡像这样低语:
- 刚刚从最后一个
apply.nodes()
- 直接调用元素,无需使用
大小写
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'
很抱歉,我知道其余的SQL作品,所以我并没有真正考虑把它全部发布——我会在几分钟内把整个事情发布出来。Cheers@DaveEdmonds这将有助于提供一个可复制粘贴(简化)的XML样本。嗨,恐怕不行。数据安全性很高。我很感激它限制了你能提供多少帮助。我会看看你上面的建议,看看是否能奏效。谢谢Dave@DaveEdmonds如果我看到这个XML,我很确定这可以做得更好/更直接。。。也许-如果性能很重要-你想准备一个测试样本。。。不管怎样,我只是在问了我的魔镜灯泡后更新了一下。。。