Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Сравнение СУБД Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 .. 8 9 10 11 12 [13] 14 15 16 17 .. 25   вперед  Ctrl
 Re: Нужна помощь  [new]
Gluk (Kazan)
Member

Откуда:
Сообщений: 9365
Bogdanov Andrey
pkarklin
А код где?


Такой?

SQL>create table tab(c number);

Таблица создана.

SQL>create trigger trig after insert on tab
  2  for each row
  3  begin
  4    if :new.c<0 then
  5     raise_application_error(-20000,'Error!!!');
  6    end if;
  7  end;
  8  /

Триггер создан.

SQL>insert into tab values(1);

1 строка создана.

SQL>insert into tab values(-1);
insert into tab values(-1)
            *
ошибка в строке 1:
ORA-20000: Error!!!
ORA-06512: at "USR.TRIG", line 3
ORA-04088: error during execution of trigger 'USR.TRIG'


SQL>select * from tab;

         C
----------
         1

Ну или то же самое для statment-level триггера:
SQL>create table tab(c number);

Таблица создана.

SQL>create trigger trig after insert on tab  declare
  2      nCount integer;
  3    begin
  4      select count(*) into nCount from tab;
  5     if nCount >1 then
  6     raise_application_error(-20000,'Error!!!');
  7    end if;
  8  end;
  9  /

Триггер создан.

SQL>insert into tab values(1);

1 строка создана.

SQL>insert into tab values(-1);
insert into tab values(-1)
            *
ошибка в строке 1:
ORA-20000: Error!!!
ORA-06512: at "USR.TRIG", line 6
ORA-04088: error during execution of trigger 'USR.TRIG'


SQL>select * from tab;

         C
----------
         1


дык в том то и прикол, что откатывается только тот оператор что вызвал исключение
28 авг 08, 15:33    [6120756]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
Dihotom
Member

Откуда:
Сообщений: 453
Gluk (Kazan)
дык в том то и прикол, что откатывается только тот оператор что вызвал исключение

Вопрос был как раз про это (с последующей просьбой привести в пример код):
pkarklin
Вопрос. В Oracle при генерации исключения в триггере, оператор, вызвавщий срабатывание триггера, будет откачен автоматически сервером?
28 авг 08, 15:40    [6120816]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
2 Bogdanov Andrey

Транзакция осталась подвисшей?

2 Dihotom

Уберите, пожалуста обработчик ИС и повторите пример. Вставка 2ки пройдет?
28 авг 08, 15:42    [6120820]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
Dihotom
Member

Откуда:
Сообщений: 453
pkarklin
2 Bogdanov Andrey

Транзакция осталась подвисшей?

2 Dihotom

Уберите, пожалуста обработчик ИС и повторите пример. Вставка 2ки пройдет?

Если в моем примере убрать обработчик, то будет ровно то же, что в примере Bogdanov Andrey. На строке с -1 получим исключение. Транзакция, естественно, будет незакончена (собственно как и в случае отсутствия исключения, т.е. без строки со вставкой -1).

Вообще, окончание транзакции - это либо вызов COMMIT, либо ROLLBACK, либо disconnect, либо DDL. Любой следующий оператор неявно начинает новую транзакцию.
28 авг 08, 15:54    [6120912]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
Dihotom
Если в моем примере убрать обработчик, то будет ровно то же, что в примере Bogdanov Andrey. На строке с -1 получим исключение. Транзакция, естественно, будет незакончена (собственно как и в случае отсутствия исключения, т.е. без строки со вставкой -1).

Вообще, окончание транзакции - это либо вызов COMMIT, либо ROLLBACK, либо disconnect, либо DDL. Любой следующий оператор неявно начинает новую транзакцию.


Меня интересует будет ли выполнена:

    INSERT INTO tbl VALUES (1);
    INSERT INTO tbl VALUES (-1); -- оператор, вызывающий срабатывание триггера
    INSERT INTO tbl VALUES (2); -- вот эта вот инструкция
28 авг 08, 16:09    [6121024]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
Gluk (Kazan)
Member

Откуда:
Сообщений: 9365
pkarklin
2 Bogdanov Andrey

Транзакция осталась подвисшей?

2 Dihotom

Уберите, пожалуста обработчик ИС и повторите пример. Вставка 2ки пройдет?


В Oracle любой DML окружается неявными Savepoint-ами. Если при выполнении оператора вылезло исключение, происходит частичный откат и можно, например попробовать снова в той-же транзакции. Собственно эту нехитрую мысль и хотят довести
28 авг 08, 16:10    [6121033]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
Gluk (Kazan)
Member

Откуда:
Сообщений: 9365
pkarklin
Dihotom
Если в моем примере убрать обработчик, то будет ровно то же, что в примере Bogdanov Andrey. На строке с -1 получим исключение. Транзакция, естественно, будет незакончена (собственно как и в случае отсутствия исключения, т.е. без строки со вставкой -1).

Вообще, окончание транзакции - это либо вызов COMMIT, либо ROLLBACK, либо disconnect, либо DDL. Любой следующий оператор неявно начинает новую транзакцию.


Меня интересует будет ли выполнена:

    INSERT INTO tbl VALUES (1);
    INSERT INTO tbl VALUES (-1); -- оператор, вызывающий срабатывание триггера
    INSERT INTO tbl VALUES (2); -- вот эта вот инструкция


да, после чего будет две записи (1,2)
28 авг 08, 16:11    [6121036]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
2 Gluk (Kazan)

Ничуть не сомневаюсь, но хотелось бы услышать Dihotom.

автор
В Oracle любой DML окружается неявными Savepoint-ами. Если при выполнении оператора вылезло исключение, происходит частичный откат и можно, например попробовать снова в той-же транзакции. Собственно эту нехитрую мысль и хотят довести


Еще раз RAISERROR - это не генерация исключения, поэтому его использование в триггере не откатывает оператор, вызвавший его срабатывание. С делкративными ограничениями поведение аналогично Oracle.
28 авг 08, 16:25    [6121154]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
Dihotom
Member

Откуда:
Сообщений: 453
pkarklin
Меня интересует будет ли выполнена:

    INSERT INTO tbl VALUES (1);
    INSERT INTO tbl VALUES (-1); -- оператор, вызывающий срабатывание триггера
    INSERT INTO tbl VALUES (2); -- вот эта вот инструкция


INSERT INTO tbl VALUES (0);

1 row created.

BEGIN
    INSERT INTO tbl VALUES (1);
    INSERT INTO tbl VALUES (-1);
    INSERT INTO tbl VALUES (2);
    COMMIT;
END;
/

BEGIN
*
ERROR at line 1:
ORA-20001: Attempt to insert negative value
ORA-06512: at "TRG_TBL", line 2
ORA-04088: error during execution of trigger 'TRG_TBL'
ORA-06512: at line 3


SELECT *
  FROM tbl;

         F
----------
         0
В данном случае не вставилась и строка с 1, т.к. то, что заключено в BEGIN END - это единый оператор, который был откачен. Вот это, кстати, интересный момент. Если транзакция реализована как ХП (т.е. её можно рассматривать как единый большой оператор), то при генерации исключения и его дальнейшем "неперехвате" Oracle автоматом её откатывает. Значит, мои вчерашние рассуждения об инструментах разработки были не совсем верны - не подумал вчера об этом. Но сути это не меняет - 2-ка никогда не вставится.

Gluk (Kazan)
да, после чего будет две записи (1,2)

Ну, например, если мы напишем нашу транзакцию так:

BEGIN
    INSERT INTO tbl VALUES (1);
    BEGIN
        INSERT INTO tbl VALUES (-1);
    EXCEPTION
        WHEN OTHERS THEN NULL; -- т.е. загасим это исключение и посчитаем, 
                               -- что транзакция может отработать и без 
                               -- выполнения этого оператора (но это мы решаем в транзакции, 
                               -- а не в триггере!).
    END;
    INSERT INTO tbl VALUES (2);
    COMMIT;
END;
/
28 авг 08, 16:47    [6121333]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
2 Dihotom

Попробую подвести итого. Вы меня поправите, если что не так:

1. Поведение Oracle, когда триггер только генерит исключение и нет обработчика ошибок, аналогично поведению MS SQL, когда в триггере вызывается ROLLBACK - т.е. идет прерывание выполнение бача и откат всей транзакции.

2. В случие наличия и в MS SQL и в Oracle тригера только с исключением и наличием обработчика ошибок на уровне кода, вызывающего срабатывание триггера, контроль за поведением транзакции идентичен в обоих СУБД.


Отсюда вопрос, почти философский. О чем мы тут, собственно, спорили?! ;)
28 авг 08, 17:01    [6121449]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
hvlad
Member

Откуда:
Сообщений: 11553
pkarklin
2 Dihotom

Попробую подвести итого. Вы меня поправите, если что не так:

1. Поведение Oracle, когда триггер только генерит исключение и нет обработчика ошибок, аналогично поведению MS SQL, когда в триггере вызывается ROLLBACK - т.е. идет прерывание выполнение бача и откат всей транзакции.
Насколько я вижу по второму примеру с обработкой исключения на втором инсерте, вся тр-ция не откатывается. откатывается только блок, начиная от BEGIN (в IB\FB также)

pkarklin
2. В случие наличия и в MS SQL и в Oracle тригера только с исключением и наличием обработчика ошибок на уровне кода, вызывающего срабатывание триггера, контроль за поведением транзакции идентичен в обоих СУБД.


Отсюда вопрос, почти философский. О чем мы тут, собственно, спорили?! ;)
О нарушениях layering и невозможности этого не делать в mssql до 2k5, и о вредности некоторых советов
28 авг 08, 17:13    [6121536]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
hvlad
Member

Откуда:
Сообщений: 11553
hvlad
Насколько я вижу по второму примеру с обработкой исключения на втором инсерте, вся тр-ция не откатывается. откатывается только блок, начиная от BEGIN (в IB\FB также)
При отсутствии явного обработчика исключения, есс-но. Если обработчик есть, то откатывается только один statement.
28 авг 08, 17:16    [6121555]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
Dihotom
Member

Откуда:
Сообщений: 453
pkarklin
2 Dihotom

Попробую подвести итого. Вы меня поправите, если что не так:

1. Поведение Oracle, когда триггер только генерит исключение и нет обработчика ошибок, аналогично поведению MS SQL, когда в триггере вызывается ROLLBACK - т.е. идет прерывание выполнение бача и откат всей транзакции.

2. В случие наличия и в MS SQL и в Oracle тригера только с исключением и наличием обработчика ошибок на уровне кода, вызывающего срабатывание триггера, контроль за поведением транзакции идентичен в обоих СУБД.


Отсюда вопрос, почти философский. О чем мы тут, собственно, спорили?! ;)

Смотрите, логика упрощенного тествого случая (реальный я приводил вчера):
Вставить первое значение, вставить второе, вставить третье. Если второе значение нарушило ограничение целостности, то и фиг с ним - игнорируем.
Вот в такой ситуации (я думаю, что на T-SQL Вы это легко сможете перевести):
BEGIN
    INSERT INTO tbl VALUES (1);
    BEGIN
        INSERT INTO tbl VALUES (-1);
    EXCEPTION
        WHEN OTHERS THEN NULL;
    END;
    INSERT INTO tbl VALUES (2);
    COMMIT;
END;
/
что будет вставлено в таблицу при условии, что Ваш триггер откатывает транзакцию (именно этот подход пропагандируете Вы)? На сколько я понял - только 2. Либо в обработчике ошибок нужно будет заново повторить всё, что было до отката.
При генерации же только исключения (без отката в триггере) и Oracle, и SQL Server полностью выполнят то, что требуется. Единственное - в SQL Server'е, как мы и говорили, без ROLLBACKа в триггере может случиться бардак при определенных условиях (это обсудили еще вчера).
28 авг 08, 17:22    [6121592]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
Dihotom
Member

Откуда:
Сообщений: 453
Представляете, открыл для себя Америку. Сейчас ради интереса попытался откатить транзакцию в триггере, оказывается, Оракл запрещает использовать ROLLBACK в триггере :)
Только не надо говорить, что поэтому мы и не используем ROLLBACK в триггере.
Это означает лишь то, за 5 лет мне ни разу не пришло в голову его там написать :)
28 авг 08, 17:28    [6121628]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
2 Dihotom

Начнем с того, что я ничего не пропагандирую, а рассказываю о свих подходах, в ответ на "моветон".

Более того, я уже писАл, что если разработчик пишет ROLLBACK в триггере и отстутсвует обработчик ошибки откатится все.

Если же будет обработчик ошибки и ROLLBACK в триггере, то придеться все повторять заново.
28 авг 08, 17:30    [6121635]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
Gluk (Kazan)
Member

Откуда:
Сообщений: 9365
hvlad
pkarklin
2 Dihotom

Попробую подвести итого. Вы меня поправите, если что не так:

1. Поведение Oracle, когда триггер только генерит исключение и нет обработчика ошибок, аналогично поведению MS SQL, когда в триггере вызывается ROLLBACK - т.е. идет прерывание выполнение бача и откат всей транзакции.
Насколько я вижу по второму примеру с обработкой исключения на втором инсерте, вся тр-ция не откатывается. откатывается только блок, начиная от BEGIN (в IB\FB также)


именно
откатывается только оператор или блок, вызвавший исключение
никакого соответствия rollback-у в триггере
28 авг 08, 17:30    [6121640]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
Gluk (Kazan)
именно
откатывается только оператор или блок, вызвавший исключение
никакого соответствия rollback-у в триггере


Гм... Ну так как тогда добиться, чтобы 2ка вставилась в описанном ранее примере из без обработчика ошибок?
28 авг 08, 17:32    [6121646]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
Bogdanov Andrey
Member

Откуда: Да уже и сам не знаю...
Сообщений: 2203
Dihotom
В данном случае не вставилась и строка с 1, т.к. то, что заключено в BEGIN END - это единый оператор, который был откачен. Вот это, кстати, интересный момент. Если транзакция реализована как ХП (т.е. её можно рассматривать как единый большой оператор), то при генерации исключения и его дальнейшем "неперехвате" Oracle автоматом её откатывает.
Да, тут есть тонкий момент - если pl/sql блок отправлен серверу Oracle с клиента, то блок рассматривается сервером, как единый "оператор" и для него работает та самая атомарноcть уровня оператора. То есть все взаимодействие клиента с сервером, построено по этому принципу - каждый вызов (специально для pkarlin отмечу, что именно вызов, а не транзакция) с клиента либо целиком выполнится, либо целиком нет (конечно, исключая те случаи, когда внутри блока явно указаны операторы завершения или отката транзакции).
28 авг 08, 17:41    [6121690]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
Dihotom
Member

Откуда:
Сообщений: 453
pkarklin
2 Dihotom

Начнем с того, что я ничего не пропагандирую, а рассказываю о свих подходах, в ответ на "моветон".

Более того, я уже писАл, что если разработчик пишет ROLLBACK в триггере и отстутсвует обработчик ошибки откатится все.

Если же будет обработчик ошибки и ROLLBACK в триггере, то придеться все повторять заново.

Всё это понятно. Но отсюда (из последней фразы) вывод напрашивается такой: хороший (расширяемый, сопровождаемый) подход - генерировать в триггере исключение, а не делать ROLLBACK. И это утверждение не зависит от СУБД. Однако в некоторых СУБД (к которым относится и SQL Server) желательно делать в триггере ROLLBACK, потому что только это гарантирует целостность данных, независимо от того, как поступает разработчик транзакции.

P.S.: На счет пропаганды - извинясь, некорректно выразился.
28 авг 08, 17:44    [6121697]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
Dihotom
Member

Откуда:
Сообщений: 453
И вообще мы уже на 13-ти страницах (хотя я чуть позже подключился) спорим об элементарных вещах для любого "не-СУБД-программиста".
Представьте себе систему, в которой некая функция захватывает ресурс (~начинает транзакцию), а далее - абсолютно любая другая функция может его освободить (~откатить транзакцию). Я работал на сопровождении таких систем и со всей ответственность заявляю - желание повеситься становится перманентным.
28 авг 08, 17:58    [6121778]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
Bogdanov Andrey
Member

Откуда: Да уже и сам не знаю...
Сообщений: 2203
pkarklin
Более того, я уже писАл, что если разработчик пишет ROLLBACK в триггере и отстутсвует обработчик ошибки откатится все.

Если же будет обработчик ошибки и ROLLBACK в триггере, то придеться все повторять заново.
Вот ксати пример из реальной практики - обеспечить формирование заказа при условии, что может быть выполнено не менее половины. Несколько упрощая приходим к такой задаче - есть таблица tab, которая при вставке, естественно, выполняет некоторые проверки. Я как разработчик приложения понятия не имею о сути и способе реализации этих проверок. Работая с базой данных Oracle я пишу примерно такой код (пример привожу на pl/sql, но с равным успехом он бы мог быть и на любом другом языке).
begin
  k:=0;
  for i in 1..n loop
    begin
      insert into tab values(i);
      k:=k+1;
    exception
       when others the null;
    end;
  end loop;
  if k>n/2 then
    commit;
  else
    rollback;
  end if;
end;
Как в данном случае должен поступить разработчик приложения работая с MSSQL?
28 авг 08, 18:02    [6121793]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
Dihotom
Member

Откуда:
Сообщений: 453
В ответ на возможные "Огромное количество работает на SQL Server, использует откат в триггере и не вешаются" скажу: всё-таки в СУБД-программировании есть своя специфика и количество таких мест, освобождающих ресурсы, ограничено триггерами (это по-хорошему).
28 авг 08, 18:05    [6121797]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
hvlad
Member

Откуда:
Сообщений: 11553
Dihotom
В ответ на возможные "Огромное количество работает на SQL Server, использует откат в триггере и не вешаются" скажу: всё-таки в СУБД-программировании есть своя специфика и количество таких мест, освобождающих ресурсы, ограничено триггерами (это по-хорошему).
Очень добрый вы :) Я бы вспомнил крыс и кактусы :)
28 авг 08, 18:13    [6121817]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
Gluk (Kazan)
Member

Откуда:
Сообщений: 9365
pkarklin
Gluk (Kazan)
именно
откатывается только оператор или блок, вызвавший исключение
никакого соответствия rollback-у в триггере


Гм... Ну так как тогда добиться, чтобы 2ка вставилась в описанном ранее примере из без обработчика ошибок?


А зачем ? Тут кто-то за пропуск исключений до клиента предлагал наказывать.
Речь о том, что savepoint-ы важная часть логики обработки транзакций в Oracle.
Точно также все работает и в PL/SQL-ом коде. Исключения, транзакции и блоки
ортогональны. При исключении, откатывается только незавершенный оператор.
Разработчик не связан какой либо реакцией сервера (в смысле управления
транзакциями) на ошибки и сам решает, как ему обработать исключение.
И все ошибки - это исключения. Все единообразно, а не тут играем, а тут
рыбу заворачивали (c)
29 авг 08, 08:24    [6123098]     Ответить | Цитировать Сообщить модератору
 Re: Нужна помощь  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
Bogdanov Andrey
Как в данном случае должен поступить разработчик приложения работая с MSSQL?


Все очень просто. Проверку (любую) из триггера выносим в CHECK ограничение на основании пользовательской функции (тем самым делая такие проверки декларативными) и код на MS SQL будет мало чем отличаться от Oracle.
29 авг 08, 10:02    [6123363]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 .. 8 9 10 11 12 [13] 14 15 16 17 .. 25   вперед  Ctrl
Все форумы / Сравнение СУБД Ответить