试图在oracle中编译该存储过程中的几个变量时,我得到了ORA-00904无效标识符,但无法弄清楚原因;所有有效的存储事件都在代码的DECLARE块中声明,并且架构中的变量也都已正确定义。 有没有人遇到此错误和/或知道如何解决?
这是正在使用的架构的DDL
CREATE TABLE history
("history_id" number(4) primary key,
"history_dt" date not null,
"history_time" timestamp not null,
"booking_cost" varchar2(50) not null,
"booking_status" varchar2(50) not null
);
CREATE TABLE attendees
("attendee_id" number(8) primary key,
"attendee_name" varchar2(50) not null,
"attendee_class" number(4) not null,
"attendee_school" varchar2(50) not null,
"attendee_status" varchar2(50) not null
);
CREATE TABLE event
("event_id" number(10) primary key,
"event_name" varchar2(100) not null,
"event_location" varchar2(100) not null,
"event_size" number(4) not null,
"start_dt" date not null,
"end_dt" date not null,
"class_restriction" number(4) not null,
"school_restriction" varchar2(100) not null
);
CREATE TABLE reservation
("reservation_id" number(3) primary key,
"event" number(10) references event("event_id"),
"attendee" number(8) references attendees("attendee_id"),
"booking" number(4) references history("history_id"),
"reservation_status" varchar2(50) not null
);
这些是我收到的错误消息
编译失败,第19行(15:38:10) PL / SQL:ORA-00904:“ END_DT”:无效的标识符编译失败,第18行(15:38:10)
PL / SQL:忽略SQL语句编译失败,第26行(15:38:10) PLS-00302:必须声明组件'EVENT_ID'编译失败,第26行(15:38:10) PL / SQL:ORA-00904:“保留”。“ EVENT_ID”:无效的标识符编译失败,第26行(15:38:10)
PL / SQL:忽略SQL语句编译失败,第36行(15:38:10) PL / SQL:ORA-00904:“ EVENT_ID”:无效的标识符编译失败,第35行(15:38:10)
PL / SQL:语句已忽略编译失败,第51行(15:38:10) PL / SQL:ORA-00947:值不足编译失败,第51行(15:38:10)
create or replace procedure Event_Planning
(arg_event_id in number, arg_student_id in number)
IS
ws_event_name varchar(100);
ws_capacity number;
ws_event_school varchar2(4);
ws_event_class number;
past_event exception;
capacity exception;
school exception;
class exception;
BEGIN
--Test for active event
select max(event_name) into ws_event_name from event
where event_id = arg_event_id and end_dt > SYSDATE;
if ws_event_name is null
then raise past_event;
end if;
--Test for capacity
select max(event_capacity) into ws_capacity from event JOIN reservation ON event.event_id = reservation.event_id
where event_id = arg_event
and event_capacity > reservation_size;
if ws_capacity is null
then raise capacity;
end if;
--Test for restricted school
select max(school_restriction) into ws_event_school from event
where event_id = arg_event_id;
if ws_event_school = arg_school
then raise school;
end if;
--Test for restricted class
select max(class_restriction) into ws_event_class from event
where event.id = arg_event;
if ws_event_class = arg_class
then raise class;
end if;
--Update reservation table
insert into reservation values
(Seq.nextval, arg_event, arg_student);
update reservation
set reservation_size = reservation_size + 1;
--Exceptions
Exception
when past_event
then raise_application_error(-20001, 'Event has passed');
when capacity
then raise_application_error(-20002, 'Event at capacity');
when school
then raise_application_error(-20003, 'Invalid school');
when class
then raise_application_error(-20004, 'Invalid class');
END;
答案 0 :(得分:2)
要使其更有可能回答您的问题,请共享所有内容。
其中包括实际的错误消息。并且,如果您真的想变得很好,请为您的EVENT和RESERVATION表添加TABLE DDL(甚至包括一些数据)。
我太懒惰了,无法猜出你的模样,只是将查询更改为虚拟表以复制问题。
您尚未声明
ws_school
arg_school
ws_class
arg_class
编译时,编译器将返回问题的行号和目标。您指的是数据库不知道的事情。
建议 不要硬编码变量的数据类型定义。因为,表可以并且将改变。
相反,使它们动态化。
所以,不用说
WS_SCHOOL VARCHAR2(4);
做类似的事情
WS_SCHOOL TABLE.COLUMN%TYPE;
然后,当表更改时,代码不一定会中断。
答案 1 :(得分:0)
因为event_id是主键,所以不需要在过滤器上使用end_date。
select "event_name" into ws_event_name
from event
where "event_id" = arg_event_id;
这看起来很困惑,以下几列来自哪里:--- = ^^^ = --- -event_capacity -Reservation_size
select max("event_size") into ws_capacity
from event
join reservation
on event."event_id" = reservation."event"
where "event_id" = arg_event_id
and "event_size" > count("reservation_id");
event.id的语法错误,必须是event_id
select "class_restriction" into ws_event_class
from event
where "event_id" = arg_event_id;
插入预订表:
select count(*) into reserve_count
from reservation
where "event" = arg_event_id
and "attendee" = arg_studen_id;
if reserve_count = 0
then
insert into reservation values
(Seq.nextval, arg_event_id, arg_student_id, null, "R");
end if;
--- note: that needs to declare reserve_count
使用count()填充与会者,然后无需更新预订表。
-- update reservation
-- set reservation_size = reservation_size + 1;
预订表:
CREATE TABLE reservation
("reservation_id" number(13) primary key,
"event" number(10) references event("event_id"),
"attendee" number(8) references attendees("attendee_id"),
"booking" number(10) references history("history_id"),
"reservation_status" varchar(1) not null
);
要合并为单个查询:
select count(*), "event_name", "class_restriction"
into event_count, ws_event_name, ws_event_class
from event
where "event_id" = arg_event_id;
-- note: that needs to declare event_count
答案 2 :(得分:0)
默认情况下,Oracle标识符(例如表名和列名)不区分大小写,因此例如,您可以
select dummy, DUMMY, Dummy
from dual;
但是,如果确实需要,也可以使用双引号来覆盖标准规则。
create table demo("123/Wow!" number);
SQL> desc demo
Name Null? Type
----------------------------------------- -------- ----------------------------
123/Wow! NUMBER
由于双引号,您的表history
,attendees
,event
等具有区分大小写的小写列名,因此在使用它们时必须遵循相同的约定:
SQL> select count(event_id) from event;
select count(event_id) from event
*
ERROR at line 1:
ORA-00904: "EVENT_ID": invalid identifier
SQL> select count("event_id") from event;
COUNT("EVENT_ID")
-----------------
0
1 row selected.
除非有一些重要的原因,否则重新创建没有双引号的列名的表将是最简单的。
(此外,reservation
有一个"event"
列,而不是"event_id"
。可能还有其他错别字-我没有检查整个内容。)