| Начало » Использование СУБД » Firebird, HQbird, InterBase » Странность с исключениями в EB (Выколупано из теста на CORE-3029) Переход к форуму:
	| 
		
			| Странность с исключениями в EB [сообщение #5069] | Fri, 17 May 2024 00:56  |  
			| 
				
				
					|  SD Сообщений: 452
 Зарегистрирован: August 2022
 | Senior Member |  |  |  
	| Вот вводная: 
 Вот собственно блок:create sequence test_gen;
recreate table test_row
(id int not null,
 did int not null,
 pid int not null,
 dep int not null
);
alter table test_row add constraint pk_test_row primary key(id);
create unique index ix_test_row1 on test_row(did, pid, dep);
commit;
insert into test_row(id, did, pid,dep) values(1, 2, 3, 4);
commit;
 Вопрос на засыпку: почему он перед ошибкой возвращает две строки?set term !!;
execute block returns(id int, did int, dep int, pid int)
as
declare variable xid int;
begin
  select id,did, pid,dep
    from test_row
   where id=(select min(id) from test_row)
    into :xid, :did, pid, :dep;
  while (1=1) do
  begin
    delete from test_row r where r.id = :xid;
    insert into test_row(id, did, dep, pid)
    values (gen_id(test_gen, 1), :did, :dep, :pid);
    suspend;
  when any do
    exception;
  end
end !!
 Совершенно аналогичная процедура:
 
 Возвращает одну строку.create or alter procedure sp_test
  returns(id int, did int, dep int, pid int)
as
declare variable xid int;
begin
  select id,did, pid,dep
    from test_row
   where id=(select min(id) from test_row)
    into :xid, :did, pid, :dep;
  while (1=1) do
  begin
    delete from test_row r where r.id = :xid;
    insert into test_row(id, did, dep, pid)
    values (gen_id(test_gen, 1), :did, :dep, :pid);
    suspend;
  when any do
    exception;
  end
end !!
select * from sp_test !!
 Чего я не понимаю?
 |  
	|  |  |  
	|  |  
	| 
		
			| Re: Странность с исключениями в EB [сообщение #5075 является ответом на сообщение #5072] | Fri, 17 May 2024 14:44   |  
			| 
				
				
					|  SD Сообщений: 452
 Зарегистрирован: August 2022
 | Senior Member |  |  |  
	| А при чём здесь он, если идёт выброс нарушения уникальности ix_test_row1, а не pk_test_row? 
 Первый delete полностью очищает таблицу (поскольку в ней всего одна запись (1, 2, 3, 4)). Далее в неё пытаются вставиться (1, 2, 3, 4) и (2, 2, 3, 4) в EB. Первая вставка успешна, вторая вставка обламывается, транзакция полностью откатывается, восстанавливая запись (1, 2, 3, 4).
 
 Последующий вызов процедуры снова удаляет запись (1, 2, 3, 4) и пытается вставить записи (3, 2, 3, 4) и (4, 2, 3, 4). Первая вставка успешна, вторая вставка обламывается, транзакция откатывается.
 
 Так почему блок возвращает две записи, а процедура - одну?
 |  
	|  |  |  
	|  |  
	|  |  
	|  | 
 
 
 Текущее время: Fri Oct 31 03:44:39 GMT+3 2025 
 Общее время, затраченное на создание страницы: 0.00758 секунд |