2015-02-17 4 views
-1

Это какая-то база данных исследования в sql-файле. Я использую oracle 11g и обрабатываю его в sqlplus.Почему он говорит «недопустимый идентификатор (ORA-00904)»? когда я вызываю функцию в CONSTRAINT CHECK

Я написал две функции для проверки номера курса и номера отдела, поэтому он зависит от основного и младшего отдела каждого учащегося.

Например, я участвую в отделе CS (майор) и отделе BIO (младший), поэтому я не могу зачислить курс, посвященный математическому факультету.

Когда я называю это в CHECK, но я не знаю, почему он это сказал.

Это вывод, когда я создаю все таблицы (из SQLPLUS)

 .... 
    .... 
    .... 
table created. 
ALTER TABLE sections ADD CONSTRAINT CK_course_depart CHECK (FindMYDeparture(stuid,find_dno_from_cno(cno)) = 'true'); 
ERROR at line 1: 
ORA-0094: "FIND_DNO_FROM_CNO":invalid identifier 

Это в файле .sql

DROP TABLE department CASCADE CONSTRAINTS; 
CREATE TABLE department (
    dnumber  number(4) not null, 
    dname  varchar(25) not null, 
    primary key (dnumber) 
); 

DROP TABLE courses CASCADE CONSTRAINTS; 
CREATE TABLE courses (
    cno  number(4) not null, 
    cname varchar(15) not null, 
    credit number(1) not null, 
    dnumber number(4) not null, 
    primary key (cno), 
    foreign key (dnumber) references department(dnumber), 
    CONSTRAINT credits CHECK (credit > 0 AND credit <= 5) 
); 

DROP TABLE student CASCADE CONSTRAINTS; 
CREATE TABLE student (
    stuid char(9) not null, 
    fname varchar(15) not null, 
    lname varchar(15) not null, 
    dMjno  number(4) not null, 
    dMnno  number(4), 
    primary key (stuid), 
    CONSTRAINT depart_M_n CHECK (dMjno <> dMnno), 
    CONSTRAINT dMinor_check CHECK (dMnno = 1 OR dMnno = 2 OR dMnno = 3) 
); 

DROP TABLE sections CASCADE CONSTRAINTS; 
CREATE TABLE sections (
    sno  number(4) not null, 
    cno  number(4) not null, 
    stuid char(9) not null, 
    semester varchar(6) not null, 
    year varchar(4) not null, 
    instructor varchar(15) not null, 
    CONSTRAINT combine_pk primary key (sno,stuid), 
    foreign key (cno) references courses(cno), 
    foreign key (stuid) references student(stuid), 
    CONSTRAINT cant_enroll CHECK (semester <> 'Spring' AND year <> 2007) 
); 

DROP TABLE grading CASCADE CONSTRAINTS; 
CREATE TABLE grading (
    sno  number(4) not null, 
    stuid char(9) not null, 
    grade numeric(1,2), 
    foreign key (sno,stuid) references sections(sno,stuid), 
    foreign key (stuid) references student(stuid), 
    CONSTRAINT grading_check CHECK (grade >= 0 AND grade <= 4) 

); 

DROP FUNCTION FindMYDeparture; 
CREATE OR REPLACE FUNCTION FindMYDeparture(stuid_in IN char,depart_course IN NUMBER) 
RETURN NUMBER AS 
departMa_no NUMBER; 
departMi_no NUMBER; 
report varchar(10); 
CURSOR cdno is 
SELECT dMjno,dMnno FROM student WHERE stuid = stuid_in; 

BEGIN 
OPEN cdno; 
LOOP 
FETCH cdno INTO departMa_no,departMi_no; 
IF (departMa_no = depart_course OR departMi_no = depart_course) 
THEN 
report := 'true'; 
EXIT; 
ELSE 
report := 'flase'; 
END IF; 
EXIT WHEN cdno%NOTFOUND; 
END LOOP; 
CLOSE cdno; 
RETURN report; 
END; 
/

DROP FUNCTION find_dno_from_cno; 
CREATE OR REPLACE FUNCTION find_dno_from_cno(cno_in IN NUMBER) 
RETURN NUMBER AS 
depart_no NUMBER; 
CURSOR cdno is 
SELECT dnumber FROM courses WHERE cno = cno_in; 
BEGIN 
OPEN cdno; 
FETCH cdno INTO depart_no; 
CLOSE cdno; 
RETURN depart_no; 
END; 
/

ALTER TABLE sections ADD CONSTRAINT CK_course_depart CHECK (FindMYDeparture(stuid,find_dno_from_cno(cno)) = 'true'); 
+0

Похож: (http://stackoverflow.com/questions/16778948/check-constraint-calling-a-function-oracle-sql-developer) –

+0

триггер может сделать вашу задачу – psaraj12

ответ

-3

Попробуйте выполнить каждое утверждение в этой функции, это случай несуществующего столбца для таблицы или использование не существующей строки.

2

Не получится. Вы не можете использовать свои функции PL/SQL в проверочном ограничении по дизайну:

• Условие проверка ограничения не может содержать следующие конструкции:

• подзапросов и выражений подзапросов скалярных

• вызовы функций, которые не являются детерминированными (CURRENT_DATE, CURRENT_TIMESTAMP, DBTIMEZONE, LOCALTIMESTAMP, SESSIONTIMEZONE, SYSDATE, SYSTIMESTAMP, UID, USER и USERENV)

• Вызовы функций, определяемого пользователь

• Разыменование REF столбцов (например, с помощью функции DEREF)

• вложенных столбцов таблицы или атрибутов

• The псевдостолбцев CURRVAL, NEXTVAL , уровень, или RowNum

• Дата константы, которые не в полной мере определены

http://docs.oracle.com/cd/B19306_01/server.102/b14200/clauses002.htm

+0

Чтобы избавиться этого ограничения должен помочь виртуальный столбец. –

+0

@Wernfried это должна быть детерминированная функция/выражение, что здесь не так –

+0

Ну, Oracle принимает функцию, подобную этой 'CREATE FUNCTION DETERMINISTIC_CHEAT RETURN INTEGER DETERMINISTIC НАЧАТЬ ВОЗВРАТ DBMS_RANDOM.RANDOM; END; 'без ошибок. Конечно, это не с логической точки зрения. –