Как запретить удаление?

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

Ответить
Дмитрий
Сообщения: 127
Зарегистрирован: 26 окт 2004, 11:05

Как запретить удаление?

Сообщение Дмитрий » 23 ноя 2007, 11:10

День добрый!
Есть проблемка. Имеем две таблицы:

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

CREATE TABLE DOC_HISTORY (
    CUSTOMER_ID    INTEGER NOT NULL,
    DOC_ID         INTEGER NOT NULL,
    DOC_TYP        INTEGER NOT NULL,
    DOC_DATE       DATE NOT NULL,
    REAL_DOC_DATE  DATE NOT NULL,
    DOC_NOTE       VARCHAR(255),
    ACTUALITY      SMALLINT DEFAULT 1 NOT NULL,
    TABLE_NAME     VARCHAR(32) NOT NULL,
    CHANGER_NAME   VARCHAR(50) NOT NULL
);

ALTER TABLE DOC_HISTORY ADD CONSTRAINT PK_DOCHIS_CUSIDDOCID PRIMARY KEY (CUSTOMER_ID, DOC_ID);

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

CREATE TABLE LTR_HISTORY (
    REC_NO        INTEGER NOT NULL,
    CUSTOMER_ID   INTEGER NOT NULL,
    DOC_ID        INTEGER NOT NULL,
    INP_NUM       VARCHAR(12) NOT NULL,
    INP_DATE      DATE NOT NULL,
    OUT_NUM       VARCHAR(12),
    OUT_DATE      DATE,
    RESP_FACE     VARCHAR(50),
    NUM_DEV_WORK  VARCHAR(25),
    PRIM          VARCHAR(255)
);


ALTER TABLE LTR_HISTORY ADD CONSTRAINT FK_LTRHIS_CUSTIDDOCID FOREIGN KEY (CUSTOMER_ID, DOC_ID) REFERENCES DOC_HISTORY (CUSTOMER_ID, DOC_ID) ON DELETE CASCADE;
Как мне запретить удаление записи из LTR_HISTORY?

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 23 ноя 2007, 13:28

Вариант 1: Убери ON DELETE CASCADE
Вариант 2: не давай никому права на удаление
Вариант 3: повесь триггер, который бы возбуждал исключение.

Дмитрий
Сообщения: 127
Зарегистрирован: 26 окт 2004, 11:05

Сообщение Дмитрий » 23 ноя 2007, 15:09

Вариант 1: Убери ON DELETE CASCADE
Это мне нужно, т.к я удалаяю записи из DOC_HISTORY.
А мне надо, что бы никто не удалил запись из LTR_HISTORY. Если удалят, то в DOC_HISTORY будет висеть "бесхозная" запись.
Вариант 2: не давай никому права на удаление.
Вариант 3: повесь триггер, который бы возбуждал исключение.
Не пройдет, CASCADE не работет.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 23 ноя 2007, 15:21


Дмитрий
Сообщения: 127
Зарегистрирован: 26 окт 2004, 11:05

Сообщение Дмитрий » 23 ноя 2007, 16:22

WildSery писал(а):Тынц.
Такой триггер не рабоает. Только что пробовал. Или триггер не правильно написал.

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

CREATE TRIGGER CHILD_AD FOR CHILD ACTIVE AFTER DELETE POSITION 0 
as 
  declare variable FK_Cnt integer; 
begin 
  select count(*) from parent where id=old.parentid into :FK_Cnt; 
  if (FK_Cnt = 0) then 
    -- Это каскадное удаление 
  else 
    -- Удаление вручную 
end
Что здесь parentid? Почему бы не написать id = old.id?

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 23 ноя 2007, 17:17

Дмитрий писал(а):Что здесь parentid? Почему бы не написать id = old.id?
Потому что это ссылка на мастер-таблицу. У тебя это будут два поля - customer_id и doc_id.

Дмитрий
Сообщения: 127
Зарегистрирован: 26 окт 2004, 11:05

Сообщение Дмитрий » 24 ноя 2007, 00:27

Тогда я понял все правильно. Но не работает. Мой exception вылезает.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 24 ноя 2007, 12:28

Дмитрий писал(а):Тогда я понял все правильно. Но не работает. Мой exception вылезает.
Какой ещё exception?
Если не работает - это означает, что при каскадном удалении удаляется сперва не мастер-запись, а потом дочерние, а наоборот.
А этого не может быть, потому как что будет, если в момент после удаления дочерних, но перед удалением мастера вставить ещё одну дочернюю?
Либо механизмы в FB и IB разошлись настолько далеко? Но тогда я не представляю, как избежать описанной мной проблемы.

Дмитрий
Сообщения: 127
Зарегистрирован: 26 окт 2004, 11:05

Сообщение Дмитрий » 24 ноя 2007, 21:33

Значит так. Я написал триггер аналогичный тому, что был в примере. Создал exception на удаление. В триггере анализирую, если count <> 0, то вызываю exception. Так вот, при каскадном удалении count <> 0!!!

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

Сообщение kdv » 25 ноя 2007, 13:27

То Дмитрий: вы соседние топики читаете? мне тут по два раза обсуждения одного и того же не нужны.
Так вот, при каскадном удалении count <> 0!!!
значит в этот момент записей УЖЕ НЕТ!

триггер after delete.
И Вы вообще не читаете что вам говорят. Буде так продолжаться дальше - удалю топик и забаню, за невменяемость.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 26 ноя 2007, 10:20

Погоди. Он говорит, что наоборот, у него записи есть. Сказки какие-то.

Автор, а покажи-ка (можешь мне в PM, чтобы форум не засорять) метаданные этих двух таблиц и триггера.

Дмитрий
Сообщения: 127
Зарегистрирован: 26 окт 2004, 11:05

Сообщение Дмитрий » 26 ноя 2007, 11:50

Всем спасибо. Вопрос снят.

Ответить