У меня есть связанный вопрос , но это еще одна часть моей загадки.
Я хотел бы получить СТАРОЕ ЗНАЧЕНИЕ столбца из строки, которая была ОБНОВЛЕНА - БЕЗ использования триггеров (ни хранимых процедур, ни каких-либо дополнительных, не-SQL / -запрошенных объектов).
У меня такой запрос:
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;
Если бы я мог сделать «FOR UPDATE ON my_table» в конце подзапроса, это было бы божественным (и исправил бы мой другой вопрос / проблему). Но это не сработает: не может иметь этого И «GROUP BY» (что необходимо для определения СЧЕТА trans_nbr's). Тогда я мог бы просто взять эти trans_nbr и выполнить сначала запрос, чтобы получить (скоро, чтобы быть) прежние значения processing_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
слеп к нему.
Я давно потерял счет всех своих попыток; Я изучал это буквально часами.
Если бы я мог просто найти пуленепробиваемый способ блокировки строк в моем подзапросе - и ТОЛЬКО этих строк, и КОГДА подзапрос произойдет - все проблемы параллелизма, которые я пытаюсь избежать, исчезли бы ...
ОБНОВЛЕНИЕ: [WIPES EGG OFF OFF FACE] Хорошо, у меня была опечатка в неуниверсальном коде вышеупомянутого, который я написал "не работает"; это делает ... благодаря Эрвину Брандштеттеру , ниже, который заявил, что это будет, я сделал это заново (после ночного сна, освеженных глаз и банана для баста). Поскольку мне потребовалось так много времени / усилий, чтобы найти такое решение, возможно, мое смущение того стоит? По крайней мере, это так для потомков ...:>
То, что у меня сейчас есть (это работает), выглядит так:
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 в комментарии к моему другому (связанному выше) вопросу. (Я был более конкретным, чем необходимо. [В данном случае.))
Пожалуйста, смотрите мой другой вопрос для правильной реализации параллелизма и даже неблокирующей версии; Этот запрос просто показывает, как получить старые и новые значения из обновления, игнорируя биты неправильного / неправильного параллелизма.