2011-04-15 105 views
3

我们试图根据我们提供的值过滤一组XML。SQL Server 2008 XPath

在我们的数据库的XML字段中,我们有以下XML,如果传递数字“5052095050830”,我们需要在XML中找到这个特定的节点。我们提供的号码可能存在多次。

任何机构可以提供一些示例SQL来协助吗?

感谢

<Attributes> 
    <ProductVariantAttribute ID="4387"> 
    <ProductVariantAttributeValue> 
     <Value>5052095050830</Value> 
    </ProductVariantAttributeValue> 
    </ProductVariantAttribute> 
    <ProductVariantAttribute ID="9999"> 
    <ProductVariantAttributeValue> 
     <Value>5052095050830</Value> 
    </ProductVariantAttributeValue> 
    </ProductVariantAttribute> 
    <ProductVariantAttribute ID="4388"> 
    <ProductVariantAttributeValue> 
     <Value>104401330A</Value> 
    </ProductVariantAttributeValue> 
    </ProductVariantAttribute> 
    <ProductVariantAttribute ID="4389"> 
    <ProductVariantAttributeValue> 
     <Value>6905</Value> 
    </ProductVariantAttributeValue> 
    </ProductVariantAttribute> 
    <ProductVariantAttribute ID="4390"> 
    <ProductVariantAttributeValue> 
     <Value>6906</Value> 
    </ProductVariantAttributeValue> 
    </ProductVariantAttribute> 
    <ProductVariantAttribute ID="4391"> 
    <ProductVariantAttributeValue> 
     <Value>Monday, October 27, 2008</Value> 
    </ProductVariantAttributeValue> 
    </ProductVariantAttribute> 
</Attributes> 

回答

3

可以使用.exist()方法 - 是这样的:

SELECT 
(list of columns) 
FROM 
dbo.YourTable 
WHERE 
YourXmlColumn.exist('//Value[text()="5052095050830"]') = 1 

这对检查您所提供的特定值。您可以更精确地定义XPath的值,该值可以被发现,对您的性能更好。

YourXmlColumn.exist('//Value[text()="5052095050830"]') = 1 

是非常糟糕的 - 它看起来到每一个节点<Value>随时随地在XML中发现价值。

事情是这样的:

YourXmlColumn.exist('/Attributes/ProductVariantAttribute/ProductVariantAttributeValue/Value[text()="5052095050830"]') = 1 

会更加集中,从而为性能更好 - 但它只能通过非常XPath语句定义的那些那些特定的节点

+0

谢谢 - 我几乎没有了。我试图让这样的工作。这是要么零结果。我究竟做错了什么? 'DECLARE @Barcode VARCHAR SELECT @Barcode = '5052095050830' SELECT * FROM Nop_ProductVariantAttributeCombination WHERE AttributesXml.exist('/属性/ ProductVariantAttribute/ProductVariantAttributeValue /值[文本()= “SQL:可变(@Barcode)” ]')= 1' – ajbrun 2011-04-15 13:24:18

+2

@Adrian:不确定 - 但你应该尝试使用'sql:variable':'/ Value [text()= sql:variable(@Barcode)]'' - 你也可以想在声明它的时候给你的'@ Barcode'变量一个长度 - 否则它是'VARCHAR(1)',我相信... – 2011-04-15 14:03:27

0

这将返回值另一个XML,我不确定你想要它。

DECLARE @xml AS XML 
SET @xml = 
'<Attributes> 
    <ProductVariantAttribute ID="4387"> 
    <ProductVariantAttributeValue> 
     <Value>5052095050830</Value> 
    </ProductVariantAttributeValue> 
    </ProductVariantAttribute> 
    <ProductVariantAttribute ID="9999"> 
    <ProductVariantAttributeValue> 
     <Value>5052095050830</Value> 
    </ProductVariantAttributeValue> 
    </ProductVariantAttribute> 
    <ProductVariantAttribute ID="4388"> 
    <ProductVariantAttributeValue> 
     <Value>104401330A</Value> 
    </ProductVariantAttributeValue> 
    </ProductVariantAttribute> 
    <ProductVariantAttribute ID="4389"> 
    <ProductVariantAttributeValue> 
     <Value>6905</Value> 
    </ProductVariantAttributeValue> 
    </ProductVariantAttribute> 
    <ProductVariantAttribute ID="4390"> 
    <ProductVariantAttributeValue> 
     <Value>6906</Value> 
    </ProductVariantAttributeValue> 
    </ProductVariantAttribute> 
    <ProductVariantAttribute ID="4391"> 
    <ProductVariantAttributeValue> 
     <Value>Monday, October 27, 2008</Value> 
    </ProductVariantAttributeValue> 
    </ProductVariantAttribute> 
</Attributes>' 


SELECT @xml.query 
(' 
    for $text in //Attributes/ProductVariantAttribute 
    where $text/ProductVariantAttributeValue/Value[text()] = 5052095050830 
    return string($text/@ID) 
') 
+0

把它改为:''104401330A'for varchar,sorry – SQLMason 2011-04-15 15:23:19

0

如果你想在这里找回它@ID是属性:

 DECLARE @xml AS XML 
    SET @xml = 
     '<Attributes> 
     <ProductVariantAttribute ID="4387"> 
      <ProductVariantAttributeValue> 
       <Value>5052095050830</Value> 
      </ProductVariantAttributeValue> 
     </ProductVariantAttribute> 
     <ProductVariantAttribute ID="9999"> 
      <ProductVariantAttributeValue> 
       <Value>5052095050830</Value> 
      </ProductVariantAttributeValue> 
     </ProductVariantAttribute> 
     <ProductVariantAttribute ID="4388"> 
      <ProductVariantAttributeValue> 
       <Value>104401330A</Value> 
      </ProductVariantAttributeValue> 
     </ProductVariantAttribute> 
     <ProductVariantAttribute ID="4389"> 
      <ProductVariantAttributeValue> 
       <Value>6905</Value> 
     </ProductVariantAttributeValue> 
     </ProductVariantAttribute> 
     <ProductVariantAttribute ID="4390"> 
      <ProductVariantAttributeValue> 
       <Value>6906</Value> 
      </ProductVariantAttributeValue> 
      </ProductVariantAttribute> 
     <ProductVariantAttribute ID="4391"> 
      <ProductVariantAttributeValue> 
       <Value>Monday, October 27, 2008</Value> 
     </ProductVariantAttributeValue> 
     </ProductVariantAttribute> 
    </Attributes>' 


    select 
    t.x.value('@ID' ,'varchar(50)') ProductVariantAttributeID 
    from @xml.nodes('//ProductVariantAttribute') t(x) 
    where t.x.value('(ProductVariantAttributeValue/Value)[1]' , 'nvarchar(50)') = '5052095050830'