SQLite UPSERT и получить вставку или обновленный rowid - PullRequest
0 голосов
/ 08 марта 2020

У меня есть таблица, хранящая пути к каталогам (Dirs). На эти строки каталога ссылается таблица Files с использованием rowid каталога в качестве внешнего ключа. При повторной индексации каталогов / файлов необходимо проверить, существуют ли они уже, и при необходимости вставить / обновить. После добавления пути к каталогу будут добавлены дополнительные вставки / обновления для файлов в каталоге, поэтому для этого требуется идентификатор строки каталога. В интересах оптимизации я хотел бы попытаться ВСТАВИТЬ каталог и ON CONFLICT (уже в таблице каталога) ОБНОВИТЬ другие поля, которые могли измениться. Тем не менее, мне также нужен rowid каталогов, независимо от того, были ли они вставлены или обновлены.

Сначала я попробовал REPLACE, но у него есть неприятный побочный эффект, что он изменяет rowids, тем самым нарушая отношения внешнего ключа существующих файлов и каталогов. .

Сначала я был взволнован, когда наткнулся на концепцию операции UPSERT, потому что думал, что она будет делать то, что я хочу. Тем не менее, после долгих исследований я пришел к выводу, что в текущем SQLite3 нет способа получить затронутый rowid с «INSERT .. ON CONFLICT UPDATE ..», когда происходит UPDATE, без дополнительного оператора SELECT, чтобы получить идентификатор с помощью имя каталога. Таким образом, рендеринг этой функции несколько бесполезен, когда для дополнительных вставок требуется rowid вставки / обновления. Единственное улучшение, которое он может выполнить, - это обнаружение INSERT или UPDATE, установив последний идентификатор строки вставки в 0 с помощью функции C API sqlite3_set_last_insert_rowid (), которая затем избавит от необходимости выполнять SELECT, если происходит INSERT, так как можно вызвать C API sqlite3_last_insert_rowid (), и если он не равен 0, то это идентификатор строки INSERT.

Это жаль, потому что SQLite, очевидно, знает идентификатор строки только что обновленного строка операции UPSERT, но не делает ее доступной. Возможно, хорошая функция запроса для будущих версий. Можно просто сохранить его в last_insert_rowid, так как он будет установлен в любом случае в случае ВСТАВКИ.

Если у кого-то еще есть лучший способ выполнить sh, я бы хотел услышать о них.

...