RTTI в триггерах Oracle

#oracle #plsql #oracle11g #triggers #oracle-objects

#Oracle #plsql #oracle11g #триггеры #oracle-объекты

Вопрос:

У меня есть эти фиктивные типы :

 create or replace type Service_TY as object(
  code INTEGER,
  visit_analysis char(1)
)FINAL;
/
 
 create or replace type Employee_TY as object(
   dummy varchar(30)
)NOT FINAL;
/

create or replace type Doctor_TY UNDER Employee_TY(
  ID INTEGER
)FINAL;
/

create or replace type Assistant_TY UNDER Employee_TY(
  ID INTEGER
)FINAL;
/

create or replace type Habilitation_TY as object(
  employee ref Employee_TY,
  service ref Service_TY
)FINAL;
/
 

И эти фиктивные таблицы:

 CREATE TABLE Service of Service_TY(
  code primary key,
  visit_analysis not null check (visit_analysis in ('v', 'a'))
);
/

CREATE TABLE Doctor of Doctor_TY(
  ID primary key
);
/

CREATE TABLE Assistant of Assistant_TY(
  ID primary key
);
/

CREATE TABLE Habilitation of Habilitation_TY;
/

 

Я хочу создать триггер, который при вставке нового кортежа в Habilitation должен проверять, что, если сотрудник является ассистентом (а не врачом), атрибут visit_analysis равен «a», чтобы узнать, является ли это законным кортежем.

Я не знаю, как проверить тип сотрудника (если это врач или помощник).

Я бы сделал что-то подобное:

 create or replace
TRIGGER CHECK_HABILITATION
BEFORE INSERT ON HABILITATION
FOR EACH ROW
DECLARE
BEGIN
    IF (:NEW.EMPLOYEE is of ASSISTANT_TY)
    THEN
      IF :NEW.SERVICE.visit_analysis = 'v'
         THEN
             raise_application_error(-10000, 'invalid tuple');
    END IF;
END;
 

Но это не работает.
Как я должен проверить этот тип?
Ошибка, которую я получаю,:
Error(14,4): PLS-00103: Encountered the symbol ";" when expecting one of the following: if

Комментарии:

1. Я заметил, что у вас нет / следующего CREATE TRIGGER оператора, в отличие от всех ваших других операторов. Вы действительно выполнили его и создали триггер?

2. да, я выполнил его, компилятор сообщает мне о некоторых случайных ошибках в операторе IF

3. Ошибка (14,4): PLS-00103: обнаружен символ «;» при ожидании одного из следующих действий: если

4. Было бы неплохо отредактировать ваш вопрос, чтобы включить сообщение об ошибке.

Ответ №1:

Попробуйте поместить его в переменную, следующая должна работать.

 create or replace
TRIGGER CHECK_HABILITATION
BEFORE INSERT ON HABILITATION
FOR EACH ROW
DECLARE
  emp employee_TY;
  ser service_TY;
BEGIN
  select deref(:new.employee) into emp from dual;
  if (emp is of (assistant_ty)) then
    select deref(:new.service) into ser from dual;
    if ser.visit_analysis = 'v' then
      raise_application_error('-20001', 'invalid tuple');
    end if;
  end if;
END;
/
 

Ответ №2:

Согласно документации для IS OF условия, вам нужно заключить тип в круглые скобки, например:

 IF (:NEW.EMPLOYEE is of (ASSISTANT_TY) )
 

за https://docs.oracle.com/cd/B28359_01/server.111/b28286/conditions014.htm#SQLRF52157 .

Я не очень хорошо знаком с использованием типов объектов, поэтому может быть какая-то другая проблема, которую я не вижу.

Комментарии:

1. Я по-прежнему сталкиваюсь с той же проблемой, ошибки компилятора вообще не помогают, и документация oracle, похоже, избегает говорить об объектах и о том, как с ними обращаться