Как прервать вставку данных в триггере?

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
Гость

Как прервать вставку данных в триггере?

Сообщение Гость » 29 ноя 2004, 18:39

Имею в виду вот что. Есть таблица. Триггер на вставку проверяет новые данные на какие-либо условия и, если че, прерывает вставку.
Напрашиваются исключения. Но, во-первых, пользователь увидит соответствующее сообщение, чего не хотелось-бы, а во-вторых, отменятся все действия, произведенные тригером (триггер начинается с удаления записи).
Приведу пример триггера:

Код: Выделить всё

CREATE TRIGGER TABLE_NAME_BI0 FOR TABLE_NAME
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  delete from TABLE_NAME
    where FIELD_1 = new.FIELD_1 and FIELD_2 = new.FIELD_2;
  if (new.FIELD_3 is null) then
    !!!ТИХО И МИРНО ПРЕРВАТЬ ВСТАВКУ!!!
end
Это в принципе возможно?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 29 ноя 2004, 18:56

это в принципе нельзя. используй процедуру для insert, а в ней уже или удаляй, или вставляй, или чего хочешь делай по условиям.

xaOz
Сообщения: 1
Зарегистрирован: 21 янв 2005, 16:04

Сообщение xaOz » 21 янв 2005, 16:06

kdv писал(а):это в принципе нельзя. используй процедуру для insert, а в ней уже или удаляй, или вставляй, или чего хочешь делай по условиям.
А можно с примером, а то я попробовал неполучаеться

sag
Сообщения: 116
Зарегистрирован: 02 ноя 2004, 11:42

Сообщение sag » 21 янв 2005, 20:47

kdv> это в принципе нельзя.

не совсем так. Можно, и без исключений, если в after insert триггере
выполнить банальное удаление этой записи:

Код: Выделить всё

create trigger A for X
active after insert
as
begin
    /* 
    здесь могут быть размещены dml-операции, 
    которые не будут отменены после выполнения триггера
    */
    if (...) then
    delete from X
    where id = new.id;
end 
>А можно с примером, а то я попробовал неполучаеться

имеется в виду примерно следующее:

Код: Выделить всё

CREATE PROCEDURE TBL_INS(NEW_ID INTEGER, NEW_FLD INTEGER)
AS BEGIN
  /*
  ...
  */
  If (...) Then /*вставляем, если условие верно*/
  INSERT INTO TBL(ID,FLD) VALUES (:NEW_ID,:NEW_FLD);
END

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 21 янв 2005, 21:31

sag писал(а):kdv> это в принципе нельзя.
не совсем так. Можно, и без исключений, если в after insert триггере
выполнить банальное удаление этой записи:
Можно-то можно, да только проктология это редкостная. И не без последствий на больших объёмах. Так же как и

Код: Выделить всё

CREATE TRIGGER TABLE_NAME_BI0 FOR TABLE_NAME
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  delete from TABLE_NAME
    where FIELD_1 = new.FIELD_1 and FIELD_2 = new.FIELD_2;
я так понимаю, автору не нравится апдейт атрибутов существующей записи по эстетическим соображениям и он решил написать программу без апдейтов ваще, а заодно и без делетов, то бишь свести логику клиента к инсёртам чего ни попадя ни о чём особо не задумываясь...

sag
Сообщения: 116
Зарегистрирован: 02 ноя 2004, 11:42

Сообщение sag » 21 янв 2005, 21:49

> да только проктология это редкостная

кто ж спорит, она самая. Сам предпочитаю всю логику в хп заворачивать.

> Так же как и
> CREATE TRIGGER TABLE_NAME_BI0 FOR TABLE_NAME
> ACTIVE BEFORE INSERT POSITION 0
> AS
> begin
> delete from TABLE_NAME
> where FIELD_1 = new.FIELD_1 and FIELD_2 = new.FIELD_2;

а это, к тому же, в bi-триггере и не отработает

> я так понимаю, автору не нравится апдейт атрибутов
> существующей записи по эстетическим соображениям ...

хз. не факт.

Ответить