У меня есть связанный вопрос, но это еще одна часть моей головоломки.
Я хотел бы получить OLD VALUE из столбца из строки, которая была UPDATEd - БЕЗ использования триггеров (и хранимых процедур, а также каких-либо других дополнительных, не-SQL/-query-сущностей).
Запрос, который у меня есть, выглядит следующим образом:
UPDATE my_table
SET processing_by = our_id_info -- unique to this worker
WHERE trans_nbr IN (
SELECT trans_nbr
FROM my_table
GROUP BY trans_nbr
HAVING COUNT(trans_nbr) > 1
LIMIT our_limit_to_have_single_process_grab
)
RETURNING row_id;
Если бы я мог сделать "ДЛЯ ОБНОВЛЕНИЯ НА my_table" в конце подзапроса, это было бы devine (и исправить мой другой вопрос/проблему). Но это не сработает: не может быть этого AND "GROUP BY" (что необходимо для вычисления COUNT of trans_nbr). Тогда я мог бы просто взять эти trans_nbr и сначала выполнить запрос, чтобы получить (скоро будущие) прежние значения process_by.
Я пробовал делать:
UPDATE my_table
SET processing_by = our_id_info -- unique to this worker
FROM my_table old_my_table
JOIN (
SELECT trans_nbr
FROM my_table
GROUP BY trans_nbr
HAVING COUNT(trans_nbr) > 1
LIMIT our_limit_to_have_single_process_grab
) sub_my_table
ON old_my_table.trans_nbr = sub_my_table.trans_nbr
WHERE my_table.trans_nbr = sub_my_table.trans_nbr
AND my_table.processing_by = old_my_table.processing_by
RETURNING my_table.row_id, my_table.processing_by, old_my_table.processing_by
Но это не сработает; old_my_table
не отображается за пределами соединения; предложение RETURNING
слепо.
Я давно потерял счет всех попыток, которые я сделал; Я изучаю это буквально в течение нескольких часов.
Если бы я мог найти пуленепробиваемый способ блокировки строк в моем подзапросе - и ТОЛЬКО эти строки, а КОГДА - в подзапрос - все проблемы concurrency, которые я пытаюсь избежать, исчезнут...
ОБНОВЛЕНИЕ: [WIPES EGG OFF FACE] Хорошо, поэтому у меня была опечатка в неэквивалентном коде выше, который я написал "не работает"; он делает... благодаря Эрвину Брандстетеру, ниже, кто заявил, что я это сделал (после ночного сна, освеженных глаз и банана для bfast). Поскольку мне потребовалось столько времени/трудно найти такое решение, возможно, мое смущение стоит того? По крайней мере, это сейчас на SO для потомков...: >
Теперь у меня есть (что работает):
UPDATE my_table
SET processing_by = our_id_info -- unique to this worker
FROM my_table AS old_my_table
WHERE trans_nbr IN (
SELECT trans_nbr
FROM my_table
GROUP BY trans_nbr
HAVING COUNT(*) > 1
LIMIT our_limit_to_have_single_process_grab
)
AND my_table.row_id = old_my_table.row_id
RETURNING my_table.row_id, my_table.processing_by, old_my_table.processing_by AS old_processing_by
COUNT (*) соответствует предложению Flimzy в комментарии к моему другому (связанному выше) вопросу. (Я был более конкретным, чем необходимо. [В этом случае.])
См. мой другой вопрос для правильной реализации concurrency и даже неблокирующей версии; Этот запрос просто показывает, как получить старые и новые значения из обновления, игнорировать неправильные/неправильные бит concurrency.