powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Найти запись или вставить
37 сообщений из 37, показаны все 2 страниц
Найти запись или вставить
    #39936739
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Задача, найти в таблице нужную запись и вернуть ее ID. Если записи нет, то вставить новую и вернуть ID новой записи.

Хотел сделать через MERGE
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
MERGE INTO
  mytable t
USING (
  SELECT
    :in_val AS val
  FROM
    rdb$database
) sel
ON (t.val = sel.val)
WHEN NOT MATCHED THEN
  INSERT (
    t.val
  ) VALUES (
    :in_val
  )
RETURNING
  NEW.id
INTO
  :var_res;


Для новой записи ID возвращает, для существующей возвращает NULL. Можно что-то подправить?

Новая запись будет вставляться крайне редко. В основном это будет выборка существующей

С уважением, Vasilisk
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39936743
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

а не пробовали:
Код: sql
1.
2.
when matched then
returning t.id

?
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39936744
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Код: sql
1.
RETURNING  NEW.id


это пропускает парсер?
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39936745
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI,

Token unknown - line 56, column 9.
RETURNING.
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39936746
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а) Если это PSQL, то достаточно перед MERGE присвоить значение
Код: sql
1.
var_res = in_val


б) Более универсально
Код: sql
1.
2.
RETURNING
  COALESCE(NEW.id, :in_val)
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39936747
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мимопроходящий
это пропускает парсер?
ДаREADME.returning.txt5. OLD and NEW could be used in RETURNING clause of UPDATE, INSERT OR UPDATE and MERGE statements.
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39936749
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
12.03.2020 16:57, _Vasilisk_ пишет:
>> это пропускает парсер?
>
> Да
>

круто!

Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39936750
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad
а) Если это PSQL, то достаточно перед MERGE присвоить значение
Код: sql
1.
var_res = in_val

Я ищу по val, а возвращаю id.

По сути у меня такая логика
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SELECT
  t.id
FROM mytable t
WHERE t.val = :in_val
INTO :var_res;

IF (:var_res IS NULL) THEN
  INSERT INTO mytable (val)
  VALUES (:in_val)
  RETURNING id
  INTO :var_res
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39936753
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
12.03.2020 17:02, _Vasilisk_ пишет:
> По сути у меня такая логика
[...]

а не проще так и сделать?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39936758
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Я ищу по val, а возвращаю id.
Не заметил.
Но тогда, если val не уникален, запрос может не быть singleton и будут проблемы.
Это и SELECT'а касается - нужно FIRST или ROWS добавлять.
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39936768
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мимопроходящий
а не проще так и сделать?
Возможна параллельная работа. Когда запись появится из соседнего коннекта после проверки, но до вставки. Придется навешивать дополнительные проверки. А хотелось одним запросом
hvlad
Но тогда, если val не уникален
Он уникален
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39936774
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
12.03.2020 17:36, _Vasilisk_ пишет:
> Возможна параллельная работа. Когда запись появится из соседнего коннекта после проверки, но до вставки.

нет ограничения на эту запись по PK или UNIQUE?
отлуп по SNAPSHOT-у не устраивает?

> Придется навешивать дополнительные проверки. А хотелось одним запросом

не знаю как там у MERGE с CURSOR STABILITY.
зуб не дам.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39936778
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сделал так
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
SELECT
  t.id
FROM mytable t
WHERE t.val = :in_val
INTO :var_res;

IF (:var_res IS NULL) THEN
  MERGE INTO mytable t
  USING (
    SELECT
      :in_val AS val
    FROM rdb$database
  ) sel ON (t.val = sel.val)
  WHEN MATCHED THEN
    UPDATE SET
      t.val = :in_val
  WHEN NOT MATCHED THEN
    INSERT (
      t.val
    ) VALUES (
      :in_val
    )
  RETURNING
    t.id
  INTO
    :var_res;

Если на момент поиска запись есть, то SELECT вернет ее ID. Если же не было, но появилась, тогда один раз выполнится WHEN MATCHED THEN UPDATE SET и ID вернется через RETURNING.
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39936779
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мимопроходящий
нет ограничения на эту запись по PK или UNIQUE?
Есть. Но не хотелось вешать дополнительную обработку исключений
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39936781
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Возможна параллельная работа. Когда запись появится из соседнего коннекта после проверки, но до вставки. Придется навешивать дополнительные проверки. А хотелось одним запросом

ты же и так этот запрос выполняешь внутри ХП, иначе какой нафиг INTO :var_res

Какая разница сделано оно одним запросом внутри хранимки или несколькими?
До 4.0 чтобы не нарваться на неприятности делай в snapshot транзакции. В 4.0 можно и в RC.
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39936784
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
12.03.2020 17:45, _Vasilisk_ пишет:
>
> Есть. Но не хотелось вешать дополнительную обработку исключений
>

но ведь ты же пользуешься семафорами и критическими секциями в Дельфях,
так отчего же в здесь не юзать подобные штатные конструкции ;)
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39936835
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Если на момент поиска запись есть, то SELECT вернет ее ID. Если же не было, но появилась
Ты правда думаешь, что это спасёт тебя от нарушений уникальности или конфликтов обновления при параллельной работе ?
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39936841
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_А хотелось одним запросом
это один запрос с точки зрения SQL, но совсем не одно действие с точки зрения движка сервера.
Даже простой update сначала ищет запись, а потом ее уже обновляет.
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39937180
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdv
Даже простой update сначала ищет запись, а потом ее уже обновляет.
Но действие то атомарное? Не может же запись исчезнуть после того как ее нашли, но до обновления.
hvlad
Ты правда думаешь, что это спасёт тебя от нарушений уникальности или конфликтов обновления при параллельной работе ?
Т.е. банальный INSERT OR UPDATE запущенный в двух потоках может мне задублировать записи?
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39937189
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Т.е. банальный INSERT OR UPDATE запущенный в двух потоках может мне задублировать записи?
Если нет ограничения уникальности - конечно может.
Если есть - придётся иметь дело с обработкой ошибки.
Я тебе что-то новое сейчас сказал ? ;)
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39937204
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad
Если есть - придётся иметь дело с обработкой ошибки.
Код: sql
1.
WHEN SQLCODE -803 DO

поможет?

hvlad
Я тебе что-то новое сейчас сказал ? ;)
Не то слово. А можно тынц на документацию?
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39937216
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Код: sql
1.
WHEN SQLCODE -803 DO


поможет?
Я предпочитаю GDSCODE, как более конкретные

_Vasilisk_
hvladЯ тебе что-то новое сейчас сказал ? ;)
Не то слово. А можно тынц на документацию?Не понял. Что ты хочешь узнать ?
Что два параллельных апдейта могут конфликтовать ?
Или что тр-ции изолированны друг от друга и есть разные уровни оной изолированности ?
Или что жизнь сложнее, чем хотелось бы ?
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39937222
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad
Не понял. Что ты хочешь узнать ?
Что два параллельных апдейта могут конфликтовать ?
Да. Что операция UPDATE OR INSERT не атомарна.

Для упрощения пусть конкурирующие транзакции будут READ COMMITED.

В смысле я допускаю возможность ошибку типа deadlock. Когда мы пытаемся проапдейтить незакоммиченную запись в no wait транзакции. Но не дубликат ключа
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39937224
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Да. Что операция UPDATE OR INSERT не атомарна.
Она атомарна.
Но тебе, похоже, нужно сначала понять - что такое атомарность. И что такое изолированность.
Потом почитай про консистентность (согласованность).
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39937225
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad
Она атомарна.
Тогда откуда возьмется дубликат?
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39937226
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
hvlad
Она атомарна.
Тогда откуда возьмется дубликат?
Дубликата не будет, если есть констрейнт.
Будет сообщение об ошибке.
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39937232
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad
Будет сообщение об ошибке.
Извини. Я это и имел в виду. В смысле откуда возьмется ошибка?

Давай детальнее. Таблица
Код: sql
1.
2.
3.
4.
5.
6.
7.
CREATE TABLE mytable(
    ID    INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY,
    VAL   INTEGER NOT NULL
);

ALTER TABLE mytable ADD CONSTRAINT pk_mytable PRIMARY KEY (id);
ALTER TABLE mytable ADD CONSTRAINT unq_mytable_val UNIQUE (val);

И из двух параллельных транзакций с параметрами rec_version, read_committed, wait выполняется запрос
Код: sql
1.
2.
3.
UPDATE OR INSERT INTO mytable (val)
VALUES (1)
MATCHING (val);

Если операция атомарна, то откуда возьмется ошибка?
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39937236
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Если операция атомарна
Что такое атомарность, по твоему ?
И что такое изолированность ?
Каким боком вторая тр-ция узнает о том, что первая что-то вставила, если ей нельзя видеть незакомиченное ?
Может уже изучить азы ?
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39937240
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LangRef 3.0Столбцы идентификации (автоинкремент)
Столбцы идентификации могут быть определены с помощью предложения GENERATED BY DEFAULT AS IDENTITY.
Столбец идентификации представляет собой столбец, связанный с внутренним генератором последовательностей.Ключевое я подчеркнул.
Генератор - вне транзакций и обращение к нему выстраивает (в) очередь. Следовательно, если не задавать значение руками (а зачем бы, в нормальной ситуации), то две любые вставки гарантированно получат два разных значения для поля с автоинкрементом.
На атомарность и изоляцию это всё не влияет.
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39937252
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad
Что такое атомарность, по твоему ?
Фиксация состояния таблицы на момент выполнения конкретного оператора
hvlad
Каким боком вторая тр-ция узнает о том, что первая что-то вставила, если ей нельзя видеть незакомиченное ?
А каким боком она узнает о наличии дубликата?

Сейчас провел эксперимент.

1. Стартуем транзакцию
2. Выполняем
Код: sql
1.
2.
3.
UPDATE OR INSERT INTO mytable (val)
VALUES (1)
MATCHING (val);

3. получаем 1 record(s) was(were) inserted into MYTABLE4. Стартуем вторую транзакцию
5. Выполняем
Код: sql
1.
2.
3.
UPDATE OR INSERT INTO mytable (val)
VALUES (1)
MATCHING (val);

получаем Invalid insert or update value(s): object columns are constrained - no 2 table rows can have duplicate column values.
violation of PRIMARY or UNIQUE KEY constraint "UNQ_MYTABLE_VAL" on table "MYTABLE".
Problematic key value is ("VAL" = 1).Т.е. изолированности транзакции хватает на то, чтобы не найти запись при поиске, но найти при попытке вставить и выкинуть ошибку дубликата.

Т.е. тут вопрос даже не в атомарности. Т.к. сейчас никакого race condition нет. Есть обычный конкурентный допуск
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39937257
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

Влад сказал что при отсутствии ограничения уникальности, отсутствие дубликатов таким оператором не гарантируется.
У тебя оно есть о чём и говорит ошибка.
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39937259
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис
Влад сказал что при отсутствии ограничения уникальности, отсутствие дубликатов таким оператором не гарантируется.
Уникальность есть
Симонов Денис
У тебя оно есть о чём и говорит ошибка.
Меня удивляет сам факт ошибки
_Vasilisk_
изолированности транзакции хватает на то, чтобы не найти запись при поиске, но найти при попытке вставить и выкинуть ошибку дубликата.
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39937262
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

транзакции изолированы друг от друга. Ну не может вторая транзакция увидеть запись, которая вставила первая, но не подтвердила вставку. Что тут удивительного? Проверка ограничения уникальности производится вне контекста транзакции, поэтому ты получаешь ошибку.
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39937266
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
hvladЧто такое атомарность, по твоему ?
Фиксация состояния таблицы на момент выполнения конкретного оператораНет никакого "состояния таблицы".
Нет никакого "момента выполнения конкретного оператора".
Вообще всё не так.
Срочно читать определение ACID.

_Vasilisk_
Сейчас провел эксперимент.

1. Стартуем транзакцию
2. Выполняем
...
4. Стартуем вторую транзакцию
5. Выполняем
Я уже писал, что в жизни всё намного сложнее ?
Не думал о том, что 2 и 5 в жизни могут выполняться "одновременно", а не после того, как ты нажмёшь enter ?
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39937270
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad
Не думал о том, что 2 и 5 в жизни могут выполняться "одновременно", а не после того, как ты нажмёшь enter ?
Легко. Но я говорю о конкретном опыте

Симонов Денис
Проверка ограничения уникальности производится вне контекста транзакции
Спасибо. Это именно тот ответ, что я хотел услышать.
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39937283
Фотография Старый плюшевый мишка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_

Симонов Денис
Проверка ограничения уникальности производится вне контекста транзакции
Спасибо. Это именно тот ответ, что я хотел услышать.


Вообще-то ответу больше лет, чем моему опыту работы с IB-FB. И не только по факту реализации, но и в обсуждениях на всякоразных ресурсах. Почему снова и снова это становится откровением даже для вовсе не неофитов - для меня загадка. Был случАй, когда мне пришлось это объяснять аж Хелен
...
Рейтинг: 0 / 0
Найти запись или вставить
    #39937284
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

последний раз говорю - изучай основы. Без них - никуда.
Я могу расжевать тебе этот конкретный случай, но не буду.
Ибо это тебя ничему не научит.
Появится понимание основ, появятся нетривиальные вопросы - приходи, поговорим.
...
Рейтинг: 0 / 0
37 сообщений из 37, показаны все 2 страниц
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Найти запись или вставить
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]