2011-07-08 26 views
3

我已經根據XML值中的特定條件獲取數據。 想法是有一個包含兩列ID和數據(XML數據類型)的表。我必須獲取特定ID的數據。像Where子句那樣的XQuery過濾器

下面是這個例子,我希望只將結果作爲Sears Tower的第一行。我得到兩排。

IF OBJECT_ID('tempdb..#ExistExample') IS NOT NULL 
DROP TABLE #ExistExample 
GO 

CREATE TABLE #ExistExample 
(
    XMLID Int, 
    XMLDocument xml 
) 

INSERT INTO #ExistExample 
VALUES (100,'<Buildings> 
    <Building> 
    <Name>Sears Tower</Name> 
    <Floor1>Yes</Floor1> 
    <Floor2>Yes</Floor2> 
    <Floor3>No</Floor3> 
    </Building> 
    <Building> 
    <Name>IDS Building</Name> 
     <Floor1>Yes</Floor1> 
     <Floor2>Yes</Floor2> 
     <Floor3>Yes</Floor3> 
    </Building> 
</Buildings>') 

DECLARE @data varchar(1000) 
DECLARE @ID INT 
SET @ID = 101 
SET @data = 'Sears Tower' 

INSERT INTO #ExistExample 
VALUES (101,'<Buildings> 
    <Building> 
    <Name>Sears Tower</Name> 
    <Floor1>Yes</Floor1> 
    <Floor2>Yes</Floor2> 
    <Floor3>No</Floor3> 
    </Building> 
    <Building> 
    <Name>IDS Building</Name> 
     <Floor1>Yes</Floor1> 
     <Floor2>Yes</Floor2> 
     <Floor3>Yes</Floor3> 
    </Building> 
</Buildings>') 

--SELECT * FROM #ExistExample 

SELECT 
c.value('(Name/text())[1]','varchar(25)') AS BuildingName, 
c.value('(Floor1/text())[1]','varchar(25)') AS Floor1, 
c.value('(Floor2/text())[1]','varchar(25)') AS Floor2, 
c.value('(Floor3/text())[1]','varchar(25)') AS Floor3 
FROM #ExistExample 
CROSS APPLY XMLDocument.nodes('/Buildings/Building') as t(c) 
WHERE c.exist('//Building/Name[.=sql:variable("@data")]') = 1 
AND XMLID = @ID 
+0

好問題,+1。看到我的答案兩種解決方案。 :) –

+0

請考慮註冊一個帳戶,以便您可以編輯您的問題並發表評論。謝謝,歡迎來到Stack Overflow。 –

+0

@Annie:我爲您的問題提供了正確的XPath解決方案。我不明白SQL足以知道你正在詢問你的更新問題,而且問題似乎是SQL特有的。就XQuery而言(不是它的舊的SQL服務器方言)而言,我已經爲您提供了2個能夠生成所需數據的答案。 –

回答

1

使用

DriverDetails/DriverDetail[ID eq 1]/*[not(self::ID)] 

,或者,如果你認爲這是簡單的:

DriverDetails/DriverDetail[ID eq 1]/(PRN | Name)) 

這裏假設(用於XPath表達式)計算表達式具有如初始上下文節點爲DriverDetails的父節點。

+0

請參閱問題的更新。 –

0

得到了答案。這應該是這樣的:

SELECT c.value('(Name/text())[1]','varchar(25)') AS BuildingName, 
c.value('(Floor1/text())[1]','varchar(25)') AS Floor1, 
c.value('(Floor2/text())[1]','varchar(25)') AS Floor2, 
c.value('(Floor3/text())[1]','varchar(25)') AS Floor3 
FROM #ExistExample 
CROSS APPLY XMLDocument.nodes('/Buildings/Building') as t(c) 
WHERE c.value('(Name/text())[1]','varchar(25)') = @data 
AND XMLID = @ID 

我不確定這是更好的方法還是有任何其他方式來實現這一點。