Про хранимую процедуру

sochiman
Дата: 27.08.2012 15:59:42
В хранимой процедуре последовательно выполняются несколько update и delete. Решил, что в программе удобнее вызвать единожды stored procedure, чем многократно query.
В этой связи возникли вопросы:
1. будет ли в процедуре каждый новый запрос выполняться по окончании предыдущего или начнет выполняться еще до окончания предыдущего?
2. если на последнем запросе возникнет ошибка, то будет выполнен откат по всем запросам, входящим в процедуру, или только по последнему?
pastor
Дата: 27.08.2012 16:20:01
sochiman,

Процедура атомарна. - т.е. все или ничего.

В случае, если есть suspend - атомарна до первого suspend.

Почему не execute block?
kdv
Дата: 27.08.2012 16:21:12
sochiman
будет ли в процедуре каждый новый запрос выполняться по окончании предыдущего или начнет выполняться еще до окончания предыдущего?

никакого распараллеливания в процедурах или триггерах нет, это был бы тихий ужас.
WildSery
Дата: 27.08.2012 16:21:29
pastor
В случае, если есть suspend - атомарна до первого suspend.
До каждого. Не до первого.
sochiman
Дата: 27.08.2012 16:36:39
pastor
Почему не execute block?

Хочется вынести запросы за пределы прикладной программы, чтобы в случае ошибки не перекомпилировать программный код.
Basil A. Sidorov
Дата: 27.08.2012 16:39:59
sochiman
Хочется вынести запросы за пределы прикладной программы, чтобы в случае ошибки не перекомпилировать программный код.
Вынесите код запросов в ресурсы. Перелинковать - не перекомпилять.
sochiman
Дата: 27.08.2012 16:41:20
WildSery
pastor
В случае, если есть suspend - атомарна до первого suspend.
До каждого. Не до первого.

Если suspend явно не указан, он не подразумевается?
К примеру, тело процедуры:
update ...
update ...
delete ...
delete ...
На последнем delete происходит ошибка. Происходит откат всего или только последнего ошибочного запроса?
Таблоид
Дата: 27.08.2012 16:47:43
sochiman
Происходит откат всего или только последнего ошибочного запроса?
Всего.

SQL> create database 'tmp120827.fdb'; commit;
SQL> create table t(id int primary key, f01 int check(f01>0));
SQL> commit;
SQL> set term ^;
SQL> execute block as
CON> begin
CON> insert into t values(1, 100);
CON> insert into t values(2, 200);
CON> insert into t values(3, 300);
CON> update t set f01=400 where id=2;
CON> update t set f01=-99 where id=3;
CON> end^
Statement failed, SQLSTATE = 23000
Operation violates CHECK constraint INTEG_3 on view or table T
-At trigger 'CHECK_2'
SQL> set term ;^
SQL> select * from t;
SQL> select count(*) from t;

COUNT
============
0
Таблоид
Дата: 27.08.2012 17:09:33
PS. Если надо, чтобы откатывался только оператор с ошибкой, делайте что-то типа этого:

SQL> delete from t;
SQL> commit;
SQL>
SQL> set term ^;
SQL> execute block as
CON> begin
CON> insert into t values(1, 100);
CON> insert into t values(2, 200);
CON> insert into t values(3, 300);
CON> update t set f01=400 where id=2;
CON> update t set f01=-99 where id=3;
CON> when any do begin end
CON> end^
SQL> set term ;^
SQL> select * from t;

ID F01
============ ============
1 100
2 400
3 300

SQL>

А если надо обязательно докатить до финиша, то вот так:
SQL> delete from t;
SQL> commit;
SQL>
SQL> set term ^;
SQL> execute block as
CON> begin
CON> insert into t values(1, 100);
CON> insert into t values(2, 200);
CON> insert into t values(3, 300);
CON>
CON> begin update t set f01=400 where id=2; when any do begin end end
CON> begin update t set f01=-99 where id=3; when any do begin end end
CON> begin update t set f01=777 where id=1; when any do begin end end
CON> end^
SQL> set term ;^
SQL> select * from t;

ID F01
============ ============
1 777
2 400
3 300
kdv
Дата: 27.08.2012 17:16:34
да все в статье написано
http://www.ibase.ru/devinfo/savepoints.htm

но я бы советовал в дебри when не лезть, как минимум поначалу.
Ну и за факт принять, что все действия, выполненные оператором, при ошибке внутри оператора, отменяются.

update - оператор
delete - оператор
execute procedure - тоже оператор
"срабатывание триггера" - тоже в своем роде оператор, там такие же правила действуют.

Например, update вызвывает срабатывание триггера, в триггере вызывается процедура, в процедуре есть insert и delete.
И этот update обновляет 100 записей. 99 прошло успешно, а на 100ой delete в процедуре выдал ошибку. Так вот, автоматом
- отменится insert в процедуре (а delete не надо отменять, он не прошел) и все остальное в процедуре
- отменится все, что делалось в триггере
- отменится все, что было сделано исходным update (к 99 записям).