Поддерживает ли XQuery
Update атрибуты автоинкремента, как поля автоинкремента в SQL
?
Я использую BaseX
в качестве базы данных.
Поддерживает ли XQuery
Update атрибуты автоинкремента, как поля автоинкремента в SQL
?
Я использую BaseX
в качестве базы данных.
Учитывая ответ от Кристиана Грюн из списка рассылки BaseX, это выполнимо, когда добавляемый узел определен в операторе XQuery Update и, следовательно, может быть расширен с помощью {enclosed expression}
перед его вставкой:
Вы можете указать счетчик атрибутов в вашем файле/базе данных XML и увеличивать его каждый раз, когда вы вставляете элемент. Простой пример:
ввод.xml:
<root count="0"/>
вставка.xq:
let $root := doc('input.xml')/root let $count := $root/@count return ( insert node <node id='{ $count }'/> into $root, replace value of node $count with $count + 1 )
Мне не удалось добиться того же с помощью внешнего org.w3c.dom.Document
, созданного на Java и добавленного в базу данных XML с помощью XQJ и declare variable $doc external
. Здесь может возникнуть соблазн обновить данные «автоинкремента» после добавления документа. Однако модель обработки определяет, что изменения не видны до тех пор, пока все команды не будут поставлены в очередь (Ожидающее обновление Список). Следовательно, новый документ или узел по определению просто невидим для обновлений в том же выражении FLWOR. Так:
db:add('db1', '<counters comment-id="0"/>', 'counters')
... с последующим повторным выполнением следующего НЕ будет работать:
let $doc := document{ <note id=""><text>Hello world</text></note> }
let $count := /counters/@comment-id
return (
db:add('db1', $doc, 'dummy'),
replace value of node $count with $count + 1
for $note in /note[@id='']
return replace value of node $note/@id with $count (: WRONG! :)
)
Выше последний вставленный документ всегда будет иметь <note id="">
и не будет обновляться до тех пор, пока не будет добавлен следующий документ. (Кроме того, это не сработало бы, если бы каким-то образом существовало несколько документов с <note id="">
.)
Хотя в приведенном выше примере можно было бы успешно удалить часть for $note in ...
и использовать:
let $doc := document{ <note id="{ $count }"><text>Hello world</text></note> }
... Мне не удалось установить <note id="{ $count }">
в документе в коде Java, поскольку вложенное выражение тогда не будет заменено.
Наконец, некоторые указывают похожие решения:
[...] работать плохо, так как он блокирует одновременные обновления. Вам следует рассмотреть возможность использования xdmp:random() для генерации 64-битного случайного числа для вашего уникального идентификатора.
В нашем случае идентификатор также будет использоваться в URL-адресах; тогда не очень красиво.
См. также Идентификатор файла XRX/Autoincrement и Использование XQuery для возврата идентификаторов документов.
Это будет зависеть от реализации базового хранилища данных, поскольку атрибут автоинкремента находится в определении столбца в реляционных базах данных.
Вероятно, да".