[英]SQL - Using a variable as the entire XQuery path in XML.value()
在XML字段上使用.value()
時,是否可以使用變量來定義整個XQuery路徑?
使用[local-name()=sql:variable("@FilterA")]
,我可以將要應用的過濾器定義為一對變量,但是我無法獲得使整個XQuery路徑正常工作的有效語法。
例
DECLARE @myData AS TABLE (myID INT, Parameter XML)
INSERT INTO @myData VALUES
(1, '<paramdata><Date>19/06/15</Date><term>1</term></paramdata>'),
(2, '<paramdata><Date>19/06/15</Date><term>5</term></paramdata>')
--This works as expected
SELECT * FROM @myData
WHERE Parameter.value('/paramdata/term=5','bit') = 1
--Two variables is possible
DECLARE @FilterA VARCHAR(255) = 'term'
DECLARE @FilterB VARCHAR(255) = '5'
SELECT * FROM @myData
WHERE Parameter.value('(/paramdata/*[local-name()=sql:variable("@FilterA")])[1]','int') = @FilterB
--but a single variable isn't
DECLARE @Filter1 VARCHAR(255) = '/paramdata/term=5'
SELECT * FROM @myData
WHERE Parameter.value('[local-name()=sql:variable("@Filter1")]','bit') = 1
我知道將整個查詢強制轉換為字符串並執行“ EXEC”即可,但這可能不適用於我要應用此查詢的較大情況。
編輯
在閱讀了關於XY問題后,該問題應改為:
“是否可以使用SomeNode=SomeValue
格式的參數對XML列進行過濾?”
如上所述,除了動態sql和EXEC
之外,絕對不可能使用變量路徑。
但是您可能會執行以下操作:
DECLARE @myData AS TABLE (myID INT, Parameter XML)
INSERT INTO @myData VALUES
(1, '<paramdata><Date>19/06/15</Date><term>1</term></paramdata>'),
(2, '<paramdata><Date>19/06/15</Date><term>5</term></paramdata>')
DECLARE @Filter1 VARCHAR(255) = 'term=5';
WITH Splitted AS
(
SELECT LEFT(@Filter1,CHARINDEX('=',@Filter1)-1) AS NodeName
,RIGHT(@Filter1,CHARINDEX('=',REVERSE(@Filter1))-1) AS SearchValue
)
SELECT md.myID
,md.Parameter
,md.Parameter.value('(/paramdata/*[local-name()=sql:column("NodeName")])[1]','nvarchar(max)')
FROM Splitted
CROSS APPLY @myData AS md
(您也可以在WHERE
子句中使用此表達式
另一種方法可能是這樣的:
DECLARE @myData AS TABLE (myID INT, Parameter XML)
INSERT INTO @myData VALUES
(1, '<paramdata><Date>19/06/15</Date><term>1</term></paramdata>'),
(2, '<paramdata><Date>19/06/15</Date><term>5</term></paramdata>')
DECLARE @Filter1 VARCHAR(255) = 'term=5';
WITH TheRightID AS
(
SELECT md.myID
FROM @myData AS md
CROSS APPLY md.Parameter.nodes('/paramdata/*') AS A(Nd)
WHERE Nd.value('local-name(.)','nvarchar(max)') + N'=' + Nd.value('.','nvarchar(max)')=@Filter1
)
SELECT * FROM @myData WHERE myID IN(SELECT x.myID FROM TheRightID AS x)
您甚至可以使用它來完全回答最初的問題:
WHERE N'/' + Nd.value('local-name(..)','nvarchar(max)')
+ N'/' +Nd.value('local-name(.)','nvarchar(max)')
+ N'=' + Nd.value('.','nvarchar(max)')=@Filter1
但我的建議是閱讀有關XY問題的信息 :-)
無法使用動態XQuery路徑。 .value()方法和其他方法的path參數被視為字符串文字,而不是變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.