Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / PostgreSQL Новый топик    Ответить
 Транзакция на PL/pgSQL  [new]
Wasteland Rebel
Member

Откуда:
Сообщений: 17
Я написал пару SQL команд, которые должны выполняться в одной транзакции:
DELETE FROM web.cabinet_account_section;

DELETE FROM web.cabinet_account;

INSERT INTO web.cabinet_account (account_name, cabinet_id)
SELECT bca.account_name, bca.cabinet_id FROM web.buffer_cabinet_account bca;

INSERT INTO web.cabinet_account_section (section_id, cabinet_param_id, account_id)
SELECT bcsi.section_id, bcsi.cabinet_param_id, ca.id
FROM web.buffer_cabinet_account_section bcsi
JOIN web.cabinet_account ca ON bcsi.account_name = ca.account_name;

DROP TABLE web.buffer_cabinet_account;

DROP TABLE web.buffer_cabinet_account_section;

Если в одной из команд произошла ошибка, то все изменения должны откатиться.

Как правильно написать транзакцию на PL/pgSQL? С чего начать? До этого не приходилось писать подобные вещи.
1 фев 21, 12:15    [22272379]     Ответить | Цитировать Сообщить модератору
 Re: Транзакция на PL/pgSQL  [new]
mefman
Member

Откуда:
Сообщений: 3305
Wasteland Rebel
Я написал пару SQL команд, которые должны выполняться в одной транзакции:
DELETE FROM web.cabinet_account_section;

DELETE FROM web.cabinet_account;

INSERT INTO web.cabinet_account (account_name, cabinet_id)
SELECT bca.account_name, bca.cabinet_id FROM web.buffer_cabinet_account bca;

INSERT INTO web.cabinet_account_section (section_id, cabinet_param_id, account_id)
SELECT bcsi.section_id, bcsi.cabinet_param_id, ca.id
FROM web.buffer_cabinet_account_section bcsi
JOIN web.cabinet_account ca ON bcsi.account_name = ca.account_name;

DROP TABLE web.buffer_cabinet_account;

DROP TABLE web.buffer_cabinet_account_section;

Если в одной из команд произошла ошибка, то все изменения должны откатиться.

Как правильно написать транзакцию на PL/pgSQL? С чего начать? До этого не приходилось писать подобные вещи.

begin;
...
commit;
profit.
А при чем тут PL/pgSQL?
1 фев 21, 12:21    [22272386]     Ответить | Цитировать Сообщить модератору
 Re: Транзакция на PL/pgSQL  [new]
Wasteland Rebel
Member

Откуда:
Сообщений: 17
mefman
Wasteland Rebel
Я написал пару SQL команд, которые должны выполняться в одной транзакции:
DELETE FROM web.cabinet_account_section;

DELETE FROM web.cabinet_account;

INSERT INTO web.cabinet_account (account_name, cabinet_id)
SELECT bca.account_name, bca.cabinet_id FROM web.buffer_cabinet_account bca;

INSERT INTO web.cabinet_account_section (section_id, cabinet_param_id, account_id)
SELECT bcsi.section_id, bcsi.cabinet_param_id, ca.id
FROM web.buffer_cabinet_account_section bcsi
JOIN web.cabinet_account ca ON bcsi.account_name = ca.account_name;

DROP TABLE web.buffer_cabinet_account;

DROP TABLE web.buffer_cabinet_account_section;

Если в одной из команд произошла ошибка, то все изменения должны откатиться.

Как правильно написать транзакцию на PL/pgSQL? С чего начать? До этого не приходилось писать подобные вещи.

begin;
...
commit;
profit.
А при чем тут PL/pgSQL?

Я читал, что PostgreSQL не откатит изменения, если хоть в одном statement выше произойдет ошибка в блоке begin->commit без rollback. Т.е. он выполнит то, что может выполнить. И подумал, что здесь нужно что-то более сложное с применение pl/pgsql.

Сообщение было отредактировано: 1 фев 21, 12:25
1 фев 21, 12:31    [22272392]     Ответить | Цитировать Сообщить модератору
 Re: Транзакция на PL/pgSQL  [new]
tip78
Member

Откуда: Москва
Сообщений: 1260
наоборот - откатит все, если хоть в одном ошибка. В этом и суть транзакции.
функция (plpgsql) - всегда транзакция, насколько я помню.

зы: DELETE FROM, в данном случае, можно (нужно) заменить на TRUNCATE.
А для читаемости лучше так писать:
TRUNCATE web.cabinet_account;

INSERT INTO web.cabinet_account (account_name, cabinet_id)
SELECT bca.account_name, bca.cabinet_id FROM web.buffer_cabinet_account bca;


Сообщение было отредактировано: 1 фев 21, 12:30
1 фев 21, 12:34    [22272395]     Ответить | Цитировать Сообщить модератору
 Re: Транзакция на PL/pgSQL  [new]
Wasteland Rebel
Member

Откуда:
Сообщений: 17
tip78,

Попробовал с BEGIN ... COMMIT.
Если происходит ошибка, то вроде как действительно ничего не применяется. Но если ошибок не возникает, точнее не должны (так как не возникали без блока begin...commit), то получаю ошибку:
ERROR:  ОШИБКА:  текущая транзакция прервана, команды до конца блока транзакции игнорируются


SQL state: 25P02
1 фев 21, 12:41    [22272401]     Ответить | Цитировать Сообщить модератору
 Re: Транзакция на PL/pgSQL  [new]
tip78
Member

Откуда: Москва
Сообщений: 1260
значит есть ошибка
1 фев 21, 12:46    [22272406]     Ответить | Цитировать Сообщить модератору
 Re: Транзакция на PL/pgSQL  [new]
Wasteland Rebel
Member

Откуда:
Сообщений: 17
tip78
значит есть ошибка

Да, мой косяк был.
1 фев 21, 13:00    [22272418]     Ответить | Цитировать Сообщить модератору
 Re: Транзакция на PL/pgSQL  [new]
Wasteland Rebel
Member

Откуда:
Сообщений: 17
tip78,
Кстати, почему TRUNCATE предпочтительнее?
1 фев 21, 13:13    [22272427]     Ответить | Цитировать Сообщить модератору
 Re: Транзакция на PL/pgSQL  [new]
tip78
Member

Откуда: Москва
Сообщений: 1260
потому быстрее и менее ресурсоёмок
1 фев 21, 18:07    [22272760]     Ответить | Цитировать Сообщить модератору
Все форумы / PostgreSQL Ответить