Документация Oracle на русском языке





Сайт посвящен разработке информационных систем с использованием технологий Oracle. На сайте можно найти полезную литературу и документацию на русском языке по программированию и администрированию Oracle.Программирование баз данных на Oracle, техническая документация, литература, статьи и публикации.

Главная :: Карта


Oracle Database или Oracle RDBMS — объектно-реляционная система управления базами данных компании Oracle.



 

DeepEdit!

Программирование баз данных на Oracle, техническая документация, литература, статьи и публикации

  • Увеличить размер шрифта
  • Размер шрифта по умолчанию
  • Уменьшить размер шрифта

Атомарность уровня оператора


Рассмотрим следующий оператор: 
Insert into t values(1); 
Достаточно ясно, что он должен завершиться неудачей при нарушении ограни­чений — строка не будет вставлена. Однако рассмотрим следующий пример, где INSERT или DELETE по таблице T возбуждает триггер, который соответственно из­меняет значение столбца CNT в таблице T2: 
ops$tkyte@ORA10G> create table t2 ( cnt int );Table created. 
Таблица создана. 
ops$tkyte@ORA10G> insert into t2 values ( 0 );
1 row created. 
1 строка создана. 
ops$tkyte@ORA10G> commit;
Commit complete.
Фиксация завершена. 
ops$tkyte@ORA10G> create table t ( x int check ( x>0 ) );
Table created. 
Таблица создана. 
ops$tkyte@ORA10G> create trigger t_trigger
2 before insert or delete on t for each row
 3 begin
4 if ( inserting ) then
5 update t2 set cnt = cnt +1;
6 else
 7 update t2 set cnt = cnt -1;
8 end if;
9 dbms_output.put_line( 'Я вставил и обновил ' ||
10 sql%rowcount || ' строк(у)' );
11 end;
12 /
Trigger created.
Триггер создан. 
В этой ситуации уже не так ясно, что должно случиться. Если ошибка случится после срабатывания триггера, должен ли эффект от триггера оставаться в силе или нет? То есть, если триггер активизирован и обновил T2, но строка не была встав­лена в T, каким должен быть результат? Ясно, что мы не хотим, чтобы в этом слу­чае значение столбца CNT в T2 было увеличено, если строка не была действительно вставлена в T. К счастью, в Oracle исходный оператор, введенный клиентом — в этом случае INSERT INTO T— либо полностью проходит, либо полностью не прохо­дит. То есть он является атомарным. Это можно подтвердить следующим образом: 
ops$tkyte@ORA10G> set serveroutput on
ops$tkyte@ORA10G> insert into t values (1);
I fired and updated 1 rows
1 row created. 
1 строка создана. 
ops$tkyte@ORA10G> insert into t values(-1);
Я вставил и обновил 1 строк(у)
insert into t values(-1)
ERROR at line 1: 
ORA-02290: check constraint (OPS$TKYTE.SYS_C009597) violated
ОШИБКА в строке 1: 
ORA-02290: нарушение проверочного ограничения целостности (OPS$TKYTE.SYS_C009597) 
ops$tkyte@ORA10G> select * from t2;       CNT 
На заметку! При использовании SQL*Plus из Oracle9i Release 2 и предшествующих версий для того, чтобы увидеть, что триггер сработал, вам нужно добавить строку кода exec null после второй вставки. Это связано с тем, что SQL*Plus в этой версии не извлекает и не отображает информацию DBMS_OUTPUT после неудачного оператора DML, тогда как в Oracle 10g — ото­бражает. 
Итак, одна строка была успешно вставлена в T, и мы получили надлежащее со­общение — “Я вставил и обновил 1 строк(у)”. Следующий оператор INSERT наруша­ет ограничение целостности, установленное для T. Сообщение DBMS_OUTPUT свиде­тельствует, что триггер T фактически сработал, и мы видим тому подтверждение. Он успешно выполнил свои обновления T2. Возможно, вы ожидали, что T2 теперь содержит значение 2, но на самом деле мы видим, что оно равно 1. СУБД Oracle делает исходный оператор INSERT атомарным — то есть первоначальный INSERT INTO T является оператором, а любой сторонний эффект этого оператора рассма­тривается как его часть. 
СУБД Oracle достигает такой атомарности уровня оператора за счет того, что молча снабжает конструкцией SAVEPOINT каждый вызов в базе данных. Преды ду­щие два INSERT на самом деле трактуются так: 
Savepoint statement1;
Insert into t values ( 1 );
If error then rollback to statement1;
Savepoint statement2;
Insert into t values ( -1 );
If error then rollback to statement2; 
Для программистов, работавших с Sybase или SQL Server, поначалу это может показаться непонятным. В этих СУБД как раз истинно в точности обратное. В этих системах триггеры выполняются независимо от вызвавшего их оператора. Если возникает ошибка, триггеры должны явно откатить свою собственную работу и затем возбудить другую ошибку, чтобы откатить исходный оператор, который их инициирует. В противном случае работа, выполненная триггером, может остаться в силе, даже если вызвавший их оператор или другая его часть, в конечном счете, завершилась сбоем. 
В Oracle атомарность уровня оператора распространяется так глубоко, как это должно быть. Если в предыдущем примере INSERT INTO T возбудит триггер, об­новляющий другую таблицу, а та таблица снабжена триггером, выполняющим уда­ление в третьей таблице (и так далее, и тому подобное), то либо вся работа будет выполнена успешно, либо никакая выполнена не будет. Вам не нужно ничего до­полнительно кодировать, чтобы обеспечить это — просто так оно работает. 
 


вызов такси и такси 2 2 .
jAntivirus