SQL SERVER:如何从XML文件进行查询

时间:2014-03-05 11:21:55

标签: sql-server xml tsql

我有两个这样的xml文件:

<?xml version="1.0"?>
<instance xmlns="http://www.ubrea.com/xforms/88668970-6edb-0131-28e9-22000a1cda92" xmlns:tm="http://www.ubrea.com/xforms" >
<inputs>
<Truck_Number_Non_Barcode>MNKSJJHDHH88728</Truck_Number_Non_Barcode>
<VIN>
  <Non_Barcode>xyz</Non_Barcode>
  <ODO>1425788</ODO> 
  <Defect>
    <Code>33J</Code>
</Defect> 
</VIN>
</inputs>
</instance>

并且

<?xml version="1.0"?>
<instance xmlns="http://www.ubrea.com/xforms/88668970-6edb-0131-28e9-22000a1cda92" xmlns:tm="http://www.ubrea.com/xforms" >
<inputs>
<Number_Non_Barcode>mnbcdsddsd3455</Number_Non_Barcode>
<VIN>
  <Non_Barcode>xyz</Non_Barcode>
  <ODO>1425788</ODO>      
</VIN>
</inputs>
</instance>

下面是我的用于解析xml文件的sqlquery:

declare @xmldata xml
set @xmldata ='
<?xml version="1.0"?>
<instance xmlns="http://www.ubrea.com/xforms/88668970-6edb-0131-28e9-22000a1cda92" xmlns:tm="http://www.ubrea.com/xforms" >
<inputs>
<Number_Non_Barcode>mnbcdsddsd3455</Number_Non_Barcode>
<VIN>
  <Non_Barcode>xyz</Non_Barcode>
  <ODO>1425788</ODO>      
</VIN>
</inputs>
</instance>'
declare @sql nvarchar(max)
declare @xmlns varchar(max)
set @xmlns=''''+SUBSTRING(cast(@xmldata as varchar(max)),CHARINDEX('http://www.ubrea.com/xforms/',cast(@xmldata as varchar(max)),1),CHARINDEX('" xmlns:dm',cast(@xmldata as varchar(max)),1)-18)+''''
set @sql='
declare @xmldata xml
set @xmldata = '''+cast(@xmldata as varchar(max))+'''
begin try
;WITH XMLNAMESPACES 
(
    DEFAULT ' + @xmlns +
     ','+'''http://www.ubrea.com/xforms''' + ' as fm 
)
select
    Number_Non_Barcode, Non_Barcode, ODO, Code
from (
select          
    x.c.value(''(../../Number_Non_Barcode)[1]'', ''varchar(100)'') as Number_Non_Barcode,       
    x.c.value(''(../Non_Barcode)[1]'', ''varchar(100)'') as Non_Barcode,
    x.c.value(''(../ODO)[1]'', ''varchar(100)'') as ODO,
    x.c.value(''(Code)[1]'', ''varchar(100)'') as Code      
from @xmldata.nodes(''/instance/inputs/VIN/Defect'') x(c)
) x  

end try
begin catch
select ERROR_NUMBER() Code, ERROR_MESSAGE() Message
end catch'
exec sp_executesql @sql;

如果<Defect>不可用且如果结果如此,如何进行查询:

Number_Non_Barcode  Non_Barcode   ODO         Defect_Code
mnbcdsddsd3455      xyz           1425788      NULL

我不熟悉xml查询,似乎无法找到如何执行此操作的示例。任何帮助,将不胜感激。感谢

1 个答案:

答案 0 :(得分:0)

我猜您的动态查询是存在的,因为您不知道默认命名空间。相反,您可以使用*在XQuery中指定命名空间。

通过在几个步骤中使用..nodes()粉碎XML,可以避免使用父轴cross apply。由于Defect节点可能丢失,因此在粉碎这些节点时必须使用outer apply

select I.X.value('(*:Number_Non_Barcode/text())[1]', 'varchar(100)') as Number_Non_Barcode,
       V.X.value('(*:Non_Barcode/text())[1]', 'varchar(100)') as Non_Barcode,
       V.X.value('(*:ODO/text())[1]', 'varchar(100)') as ODO,
       D.X.value('(*:Code/text())[1]', 'varchar(100)') as Code
from @XMLData.nodes('/*:instance/*:inputs') as I(X)
  cross apply I.X.nodes('*:VIN') as V(X)
  outer apply V.X.nodes('*:Defect') as D(X)

SQL Fiddle