Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Найти запись или вставить / 25 сообщений из 37, страница 1 из 2
12.03.2020, 16:40
    #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
12.03.2020, 16:52
    #39936743
KreatorXXI
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Найти запись или вставить
_Vasilisk_,

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

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


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

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


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

круто!

Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
12.03.2020, 17:02
    #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
12.03.2020, 17:10
    #39936753
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Найти запись или вставить
12.03.2020 17:02, _Vasilisk_ пишет:
> По сути у меня такая логика
[...]

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

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

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

не знаю как там у MERGE с CURSOR STABILITY.
зуб не дам.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
12.03.2020, 17:44
    #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
12.03.2020, 17:45
    #39936779
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Найти запись или вставить
Мимопроходящий
нет ограничения на эту запись по PK или UNIQUE?
Есть. Но не хотелось вешать дополнительную обработку исключений
...
Рейтинг: 0 / 0
12.03.2020, 17:46
    #39936781
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Найти запись или вставить
_Vasilisk_Возможна параллельная работа. Когда запись появится из соседнего коннекта после проверки, но до вставки. Придется навешивать дополнительные проверки. А хотелось одним запросом

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

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

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

поможет?

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


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

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

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

В смысле я допускаю возможность ошибку типа deadlock. Когда мы пытаемся проапдейтить незакоммиченную запись в no wait транзакции. Но не дубликат ключа
...
Рейтинг: 0 / 0
13.03.2020, 17:22
    #39937224
hvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Найти запись или вставить
_Vasilisk_
Да. Что операция UPDATE OR INSERT не атомарна.
Она атомарна.
Но тебе, похоже, нужно сначала понять - что такое атомарность. И что такое изолированность.
Потом почитай про консистентность (согласованность).
...
Рейтинг: 0 / 0
13.03.2020, 17:23
    #39937225
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Найти запись или вставить
hvlad
Она атомарна.
Тогда откуда возьмется дубликат?
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Найти запись или вставить / 25 сообщений из 37, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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