Исходный код вики Insert or update. Upsert

Редактировал(а) Alexandr Fokin 2025/06/22 17:41

Скрыть последних авторов
Alexandr Fokin 2.11 1 (% style="width:1456px" %)
2 |(% style="width:139px" %) |(% style="width:264px" %) |(% style="width:1079px" %)
Alexandr Fokin 2.9 3 |(% style="width:139px" %)insert on conflict
Alexandr Fokin 2.11 4 If not exist|(% style="width:264px" %){{code language="sql"}}INSERT INTO table1
Alexandr Fokin 2.3 5 (id)
6 SELECT 1
7 WHERE
8 NOT EXISTS (
9 SELECT 1
10 FROM table1
11 WHERE id = 1
Alexandr Fokin 2.11 12 -- for share
Alexandr Fokin 2.3 13 )
Alexandr Fokin 2.11 14 ON CONFLICT DO NOTHING{{/code}}|(% style="width:1079px" %)(((
Alexandr Fokin 2.21 15 |(% style="width:115px" %)Избыточная генерация PK.|(% style="width:924px" %)(((
Alexandr Fokin 2.4 16 Конструкция {{code language="sql"}}ON CONFLICT{{/code}} не защищает от обращения к генератору ключа (sequence). И это может привести к тому, что счетчик будет крутиться впустую.
Alexandr Fokin 2.21 17 Использование выборки с условием вроде не убирает полностью ложные срабатывания (если они проходя одновременно), но после вставки записи, обращения к генератору прекратятся.
18
19 PostgreSQL Antipatterns: накручиваем себе проблемы
20 [[https:~~/~~/habr.com/ru/companies/tensor/articles/507688/>>url:https://habr.com/ru/companies/tensor/articles/507688/]]
Alexandr Fokin 2.12 21 )))
Alexandr Fokin 2.15 22 |(% style="width:115px" %) |(% style="width:924px" %)Postgres: INSERT if does not exist already
Alexandr Fokin 2.4 23 [[https:~~/~~/stackoverflow.com/questions/4069718/postgres-insert-if-does-not-exist-already>>url:https://stackoverflow.com/questions/4069718/postgres-insert-if-does-not-exist-already]]
Alexandr Fokin 2.23 24 |(% style="width:115px" %)Взаимодействие с блокировками|(% style="width:924px" %)Поведение параллельных транзакций (Read Commited):(((
Alexandr Fokin 2.20 25 |(% style="width:248px" %)Параллельные транзакции|(% style="width:303px" %)select for update|(% style="width:348px" %)update или delete
Alexandr Fokin 2.24 26 |(% style="width:248px" %)Без where exists|(% style="width:303px" %)Не блокируется.|(% style="width:348px" %)Блокируется.
Alexandr Fokin 2.20 27 |(% style="width:248px" %)С where exsists|(% style="width:303px" %)Не блокируется|(% style="width:348px" %)Не блокируется
28 |(% style="width:248px" %)с where exsists и for share|(% style="width:303px" %)Блокируется|(% style="width:348px" %)Блокируется.
29
30 Важно подчеркнуть, {{code language="sql"}}select for update{{/code}} не всегда блокирует {{code language="sql"}}insert on conflict do nothing{{/code}} (как показано в таблице).
31 В некоторых случаях может потребоваться явное ручное обновление записи для блокировки, чтобы заблокировать параллельные вызовы upsert (чтобы они они дождались завершения текущей транзакции), причем в том числе возможно перед проверкой условий.
Alexandr Fokin 2.4 32 )))
Alexandr Fokin 2.20 33 )))
Alexandr Fokin 2.13 34 |(% style="width:139px" %)Merge|(% style="width:264px" %) |(% style="width:1079px" %)Не ждет блокировок.
35 |(% style="width:139px" %){{{WITH upsert}}}|(% style="width:264px" %) |(% style="width:1079px" %)
Alexandr Fokin 1.1 36
Alexandr Fokin 2.8 37 ----
38
39 ==== Внутренние ссылки: ====
40
41 ====== Дочерние страницы: ======
42
43 {{children/}}
44
45 ====== Обратные ссылки: ======
46
47 {{velocity}}
48 #set ($links = $doc.getBacklinks())
49 #if ($links.size() > 0)
50 #foreach ($docname in $links)
51 #set ($rdoc = $xwiki.getDocument($docname).getTranslatedDocument())
52 * [[$escapetool.xml($rdoc.fullName)]]
53 #end
54 #else
55 No back links for this page!
56 #end
57 {{/velocity}}
58
59 ----