2016-09-28 73 views
0

我有以下表格:复合触发无效的标识符

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')); 

我在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或replace type'单独定义它 - 但如果你这样做,使用全局临时表可能会更简单。 –

+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; 
/

不要忘记在触发器主体评论的类型声明。