Oracle 为什么会这样说;无效标识符(ORA-00904)“;?当我在约束检查中调用函数时

Oracle 为什么会这样说;无效标识符(ORA-00904)“;?当我在约束检查中调用函数时,oracle,sqlplus,oracle11gr2,Oracle,Sqlplus,Oracle11gr2,这是sql文件中的某种学习数据库。我使用Oracle11g并在sqlplus中处理它 我写了两个函数来检查课程号和系号,所以它取决于每个学生的主修系和辅修系 例如,我是计算机科学系(主修)和生物系(辅修)的学生,所以我不能选修数学系的课程 当我叫它检查,但我不知道为什么它告诉我 这是我创建所有表时的输出(来自sqlplus) 这是在.sql文件中 DROP TABLE department CASCADE CONSTRAINTS; CREATE TABLE department ( d

这是sql文件中的某种学习数据库。我使用Oracle11g并在sqlplus中处理它

我写了两个函数来检查课程号和系号,所以它取决于每个学生的主修系和辅修系

例如,我是计算机科学系(主修)和生物系(辅修)的学生,所以我不能选修数学系的课程

当我叫它检查,但我不知道为什么它告诉我

这是我创建所有表时的输出(来自sqlplus)


这是在.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');
删除表部门级联约束;
创建表格部门(
数据编号(4)不为空,
dname varchar(25)不为空,
主键(dnumber)
);
下拉表约束;
创建表格课程(
cno编号(4)不为空,
cname varchar(15)不为空,
信用证编号(1)不为空,
数据编号(4)不为空,
主键(cno),
外键(dnumber)参考部门(dnumber),

约束信用检查(信用>0且信用=0且等级尝试运行该函数中的每个语句,这是表不存在列或使用不存在行的情况。

不会发生。不允许在“按设计检查约束”中使用pl/sql函数:

•检查约束条件不能包含以下内容 构造:

•子查询和标量子查询表达式

•对不确定函数的调用(当前日期, 当前时间戳、DBTIMEZONE、LOCALTIMESTAMP、SESSIONTIMEZONE、, SYSDATE、SYSTIMESTAMP、UID、USER和USERENV)

对用户定义函数的调用

•REF列的取消引用(例如,使用DEREF函数)

•嵌套表列或属性

•伪列CURRVAL、NEXTVAL、LEVEL或ROWNUM

•未完全指定的日期常量


看起来很相似:()触发器可能会执行您的任务以摆脱此限制虚拟列应该会有所帮助。@Wernfried它必须是一个确定性函数/表达式,这里不是这样的情况。Oracle接受这样的函数
CREATE function deterministic\u CHEAT RETURN INTEGER deterministic is BEGIN RETURN DBMS\u RANDOM.RANDOM;END;
,没有任何错误。当然,从逻辑的角度来看,这是行不通的。
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');