我有一個SQL Server 2014中的數據庫表,只有ID
列(int
)和XML
類型的列xmldata
。SQL Server 2014 - XQuery - 獲取逗號分隔列表
這xmldata
列包含例如:
<book>
<title>a nice Novel</title>
<author>Maria</author>
<author>Peter</author>
</book>
正如預期的那樣,我必須多本書籍,因此與xmldata
多行。
我現在要對所有書籍執行查詢,其中Peter是作者。我在一些xPath2.0測試人員嘗試了這一點,得出如下結論:
/book/author/concat(text(), if(position() != last())then ',' else '')
工作。
如果試圖端口這一成功到SQL Server 2014次特快它看起來像這樣,這是正確轉義語法等:
SELECT id
FROM books
WHERE 'Peter' IN (xmldata.query('/book/author/concat(text(), if(position() != last())then '','' else '''')'))
的SQL Server但似乎不支持像建設由於/concat(...)
的:
不支持XQuery語法'/ function()'。
我很茫然,然後但是,爲什麼會/text()
工作:
SELECT id, xmldata.query('/book/author/text()')
FROM books
它一樣。
我的約束:
- 我一定要使用SQL Server
- 我一定要XPath或別的東西可「注入」如上聲明(如果XML或結構數據庫的變化,上面的XPath可以改變隔離及以上的應用程序邏輯構建
Where
條款將不被感動)請參閱編輯
有沒有辦法讓這個WOR K +
問候,
BillDoor
編輯:
我的第二個制約因素歸結爲:
應用程序通過
expression <operator> value(s)
01構建Where子句
表達存儲在數據庫中,並且由例如xmlTag:
| tokenname| querystring
| "author" | "xmldata.query(/book/author/text())"
值由所述請求用戶呈現映射。所以如果用戶請求作者「Peter」與操作符「EQUALS」,則應用程序構造如下:
xmaldata.query(/book/author/text()) = "Peter"
作爲where子句。
如果客戶現在決定作者需要嵌套在<authors>
元素中,我可以簡單地更改構造數據庫中的表達式,並且整個機器可以在沒有對代碼進行任何更改的情況下繼續運行,只需管理即可。
所以我需要一種方法來實現這一
<xPath> <operator> "Peter"
或這三個孤立的組件的任何其他組合(見上:"Peter" IN <xPath>...
)讓我所有的彼得斯的書,即使有多個未分類作者。
這是不夠或者(它不是SQLSERVER語法,但你的想法):
WHERE xmldata.exist('/dossier/client[text() = "$1"]', "Peter") = 1;
因爲運營商仍然是嵌套在表達,我不能要求<> "Peter"
。
我知道這是奇怪的,請不要質疑這個概念作爲一個整體 - 它有一個歷史:/
編輯:進一步澄清:
過濾規則來爲應用程序在XML結構基本上是:
- 操作員: 「EQ」
- 字段: 「名稱」
- 值 「彼得」
的計算結果爲:
- 表達=
lookupExpressionForField("name")
- > 「table2.xmldata.value( '書/作者/名稱[1]', 'VARCHAR')」 - 運算符=
lookUpOperatorMapping("EQ")
- - > 「=」 - 值=
FormatValues("Peter")
- > 「彼得」(如果有多個值被傳遞FormatValues cosntructs一個逗號分隔的列表)
應用程序然後構建: - constructClause(String expression,String operator,String value)
「table2.xmldata.value( '書籍/作者/名稱[1]', 'VARCHAR')」 + 「=」 + 「彼得」
然後構建一個SELECT語句的結果作爲WHERE子句。
它不會像這樣構建,未經過濾,未經過濾等等,但這是基本思想。
我可以影響輸入是如何Transalted,這意味着我可以實現的方法:
lookupExpressionForField(String field)
lookUpOperatorMapping(String operator)
Formatvalues(List<String> values)
|Formatvalues(String value)
constructClause(String expression,String operator,String value)
但是我選擇做什麼,我可以改變參數類型,我可以自由地實現它們。當然越好越好。因此,簡單地用xPath構造逗號分隔列表將是最佳的(就像我可以在sqlserver中的某處打勾「enable/function() - xPath中的語法」)和/ concat(if ...)將工作)
'/文()'是不是函數,即使它在語法上看起來像一個。 – choroba 2014-11-05 15:42:55