2016-09-28 3 views
0

я в следующей таблице:триггер Compound неверный идентификатор

create table lessons(
id number, 
name_teacher varchar2(9), 
name_student varchar2(40), 
start_lesson date, 
end_lesson date 
); 

Я добавил эти данные:

insert into lessons values (001,'Peter','Thomas',to_date('2015-12-15','YYYY-MMDD'),to_date('2015-12-22','YYYY-MM-DD')); 
insert into lessons values (002,'Eli','Alice',to_date('2015-06-16','YYYY-MMDD'),to_date('2015-06-23','YYYY-MM-DD')); 
insert into lessons values (003,'Daniel','Thomas',to_date('2015-08-15','YYYY-MMDD'),to_date('2015-08-20','YYYY-MM-DD')); 
insert into lessons values (001,'Peter','Alice',to_date('2015-12-16','YYYY-MM-DD'),to_date('2015-12-25','YYYY-MM-DD')); 
insert into lessons values (002,'Eli','Thomas',to_date('2015-06-13','YYYY-MM-DD'),to_date('2015-06-20','YYYY-MM-DD')); 

Данные, которые вы не можете добавить триггер:

insert into lessons values (001,'Peter','Alice',to_date('2015-12-16','YYYY-MM-DD'),to_date('2015-12-25','YYYY-MM-DD')); 
insert into lessons values (002,'Eli','Thomas',to_date('2015-06-13','YYYY-MM-DD'),to_date('2015-06-20','YYYY-MM-DD')); 

I иметь этот код в Oracle, с которым я пытаюсь сделать триггер, который не позволяет мне добавлять учеников, у которых есть учителя, которые накладываются во времени , как «Питер» или «Эли».

CREATE OR REPLACE TRIGGER lessons_trg 
FOR INSERT OR UPDATE ON lessons 
REFERENCING NEW AS New OLD AS Old 
COMPOUND TRIGGER 

TYPE tbl_t IS RECORD(
name_teacher VARCHAR2(9), 
start_lesson date, 
end_lesson date 
); 
TYPE tbl_typ IS TABLE OF tbl_t; 
tbl tbl_typ; 

    BEFORE STATEMENT IS 
    BEGIN 
    SELECT tbl_t(name_teacher, start_lesson, end_lesson) 
    BULK COLLECT INTO tbl 
    FROM lessons; 
    END BEFORE STATEMENT; 

    BEFORE EACH ROW IS 
    v_count number; 
    BEGIN 
    SELECT COUNT(1) 
    INTO v_count 
    FROM TABLE(tbl) t 
    WHERE t.name_teacher = :NEW.name_teacher 
    AND :NEW.start_lesson BETWEEN t.start_lesson AND t.end_lesson 
    AND :NEW.end_lesson BETWEEN t.start_lesson AND t.end_lesson; 

    IF v_count > 0 THEN 
     RAISE_APPLICATION_ERROR(-20000, 'Error'); 
    END IF; 
    END BEFORE EACH ROW; 
END; 
/

Проблема заключается в том, что оракул дал мне следующую процедуру ошибки:

Error(13,11): PL/SQL: ORA-00904: "TBL_T": invalid identifier 
Error(23,10): PL/SQL: ORA-22905: cannot access rows from a non-nested table item 
Error(23,16): PLS-00642: local collection types not allowed in SQL statements 

Спасибо за помощь и хороший день :)

+0

Как сказано в сообщении об ошибке, локальные типы коллекций не допускается в операторах SQL. Вам нужно будет определить его отдельно с помощью 'create or replace type' - хотя, если вы это делаете, может быть проще использовать глобальную таблицу temp. –

+0

btw, когда вы пройдете эту синтаксическую ошибку, у вас все еще будет проблема триггера, позволяющая двум сеансам добавлять строки, которые перекрывают друг друга. –

ответ

1
create or replace 
TYPE tbl_t as object(
name_teacher VARCHAR2(9), 
start_lesson date, 
end_lesson date 
); 
/
create TYPE tbl_typ IS TABLE OF tbl_t; 
/
create or replace 
trigger lessons_trg 
FOR INSERT OR UPDATE ON lessons 
REFERENCING NEW AS New OLD AS Old 
COMPOUND TRIGGER 


tbl tbl_typ; 

    BEFORE STATEMENT IS 
    BEGIN 
    SELECT tbl_t(name_teacher, start_lesson, end_lesson) 
    BULK COLLECT INTO tbl 
    FROM lessons; 
    END BEFORE STATEMENT; 

    BEFORE EACH ROW IS 
    v_count number; 
    BEGIN 
    SELECT COUNT(1) 
    INTO v_count 
    FROM TABLE(tbl) t 
    WHERE t.name_teacher = :NEW.name_teacher 
    AND :NEW.start_lesson BETWEEN t.start_lesson AND t.end_lesson 
    AND :NEW.end_lesson BETWEEN t.start_lesson AND t.end_lesson; 

    IF v_count > 0 THEN 
     RAISE_APPLICATION_ERROR(-20000, 'Error'); 
    END IF; 
    END BEFORE EACH ROW; 
END; 
/
insert into lessons values (001,'Peter','Thomas',to_date('2015-12-15','YYYY-MM-DD'),to_date('2015-12-22','YYYY-MM-DD')); 
insert into lessons values (002,'Eli','Alice',to_date('2015-06-16','YYYY-MM-DD'),to_date('2015-06-23','YYYY-MM-DD')); 
insert into lessons values (003,'Daniel','Thomas',to_date('2015-08-15','YYYY-MM-DD'),to_date('2015-08-20','YYYY-MM-DD')); 
insert into lessons values (001,'Peter','Alice',to_date('2015-12-16','YYYY-MM-DD'),to_date('2015-12-25','YYYY-MM-DD')); 
insert into lessons values (002,'Eli','Thomas',to_date('2015-06-13','YYYY-MM-DD'),to_date('2015-06-20','YYYY-MM-DD')); 

Это должно работать

1

Вы должны объявлять типы в явном виде объектов базы данных, не как компоненты в триггере.
Попробуйте что-то вроде этого:

create or replace TYPE tbl_t IS object(
    name_teacher VARCHAR2(9), 
    start_lesson date, 
    end_lesson date 
    ); 
/
create or replace TYPE tbl_typ IS TABLE OF tbl_t; 
/

Не забудьте прокомментировать заявления типа в теле триггера.

Смежные вопросы