У меня есть таблица базы данных в SQL Server 2014 с только столбцом ID
(int
) и столбец xmldata
типа XML
.SQL Server 2014 - XQuery - получить разделенный запятой Список
xmldata
Этот столбец содержит, например:
<book>
<title>a nice Novel</title>
<author>Maria</author>
<author>Peter</author>
</book>
Как и ожидалось, у меня есть несколько книг, поэтому несколько строк с xmldata
.
Теперь я хочу выполнить запрос для всех книг, где Питер является автором. Я пробовал это в некоторых тестировщиках xPath2.0 и пришел к выводу, что:
/book/author/concat(text(), if(position() != last())then ',' else '')
работы.
Если вы пытаетесь перенести этот успех в SQL Server 2014 Express, это выглядит так, что правильно сбежавшего синтаксис и т.п .:
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
не будут затронуты) SEE EDIT
есть ли способ сделать это приста к?
С уважением,
BillDoor
EDIT:
Моя вторая ограничение сводится к следующему:
Применение конструкции ИНЕКЕ по
expression <operator> value(s)
выражение хранится в базе данных и отображается в xmlTag, например .:
| tokenname| querystring
| "author" | "xmldata.query(/book/author/text())"
значения представлены запрашивающим пользователем.так что если пользователь запрашивает у автора «Питера» с оператором «РАВНО» приложение конструирует:
xmaldata.query(/book/author/text()) = "Peter"
, как где п.
Если заказчик теперь решил, что автор должен быть вложен в элемент <authors>
, я могу просто изменить выражение в базе данных построения, и вся машина будет работать без каких-либо изменений кода, просто управляемая.
Так я нужен способ, чтобы добиться того, что
<xPath> <operator> "Peter"
или любой другой комбинации этих трех изолированных компонентов (смотри выше: "Peter" IN <xPath>...
) получает меня все книги Петерса, даже если Есть несколько несортированный авторы.
Это не хватило бы ни (его не синтаксис SQLServer, но вы получите идею):
WHERE xmldata.exist('/dossier/client[text() = "$1"]', "Peter") = 1;
, потому что оператор еще вложенный в выражении, я не мог просить <> "Peter"
.
Я знаю, что это странно, пожалуйста, не ставит под сомнение концепции в целом - это есть история:/
EDIT: дальнейшее уточнение:
Фильтр-правила вступают в приложение в структура 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')" + "=" + "Питер"
затем конструирует Выберите заявление с результатом как предложение WHERE.
он не строит его таким образом, неизолированный, нефильтрованный для инъекций и т. Д., Но это основная идея.
я могу влиять как вход Transalted, то есть я могу реализовать методы:
lookupExpressionForField(String field)
lookUpOperatorMapping(String operator)
Formatvalues(List<String> values)
|Formatvalues(String value)
constructClause(String expression,String operator,String value)
однако я выбираю сделать, я могу изменить типы параметров, я могу свободно реализовывать их. Чем меньше, тем лучше. Таким образом, простое создание разделенного запятыми списка с xPath было бы оптимальным (например, если бы я мог где-то просто отметить «enable/function() - синтаксис в xPath» в sqlserver и/concat (if ...) будет работать)
'/ текст()' не функция, даже если она синтаксически выглядит как одна. – choroba