SQL Неверный идентификатор хранимой процедуры - PullRequest
1 голос
/ 15 апреля 2020

Я получаю неверный идентификатор ORA-00904 для нескольких переменных в этой хранимой процедуре, когда пытаюсь скомпилировать его в oracle, но не могу понять, почему; Все события рабочего хранилища объявляются в блоке 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 Оператор ignoredCompilation не выполнен, строка 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 Оператор ignoredCompilation не выполнен, строка 36 (15:38:10) PL / SQL: ORA-00904: «EVENT_ID»: неверный идентификаторCompilation не удалось, строка 35 (15:38:10)

PL / SQL: оператор ignoredCompilation не удалось, строка 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;

Ответы [ 3 ]

2 голосов
/ 15 апреля 2020

Чтобы получить больше ответов на ваши вопросы, поделитесь всем.

Включает фактические сообщения об ошибках. И если вы ДЕЙСТВИТЕЛЬНО хотите быть милым, включите TABLE DDL (и даже некоторые данные) для своих таблиц EVENT и RESERVATION.

Я был слишком «ленив», чтобы догадаться, как выглядит ваш, и просто изменил ваши запросы на фиктивные таблицы, чтобы повторить проблему.

Вы не объявили

ws_school
arg_school
ws_class
arg_class

Когда вы компилируете, компилятор вернет номер строки и курс вашей проблемы. Вы имеете в виду то, о чем БД не знает.

enter image description here

Рекомендации Не задавайте жестко код типа данных определения для ваших переменных. Потому что таблицы МОГУТ и БУДУТ изменяться.

Вместо этого сделайте их динамичными c.

Поэтому вместо того, чтобы

WS_SCHOOL        VARCHAR2(4);

сделать что-то вроде

WS_SCHOOL        TABLE.COLUMN%TYPE;

Тогда, когда ваши таблицы изменятся, ваш код не обязательно сломается.

0 голосов
/ 16 апреля 2020

По умолчанию, идентификаторы 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 et c имеют регистрозависимые имена столбцов в нижнем регистре из-за двойных кавычек, поэтому у вас есть придерживайтесь того же соглашения всякий раз, когда вы их используете:

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". Могут быть и другие опечатки, подобные этой - я не все проверил.)

0 голосов
/ 16 апреля 2020

Это не должно использовать end_date для фильтров, потому что event_id является первичным ключом.

select "event_name" into ws_event_name
from event
where "event_id" = arg_event_id;

Это выглядит настолько запутанным, чтобы знать, откуда берутся следующие столбцы: --- = ^^ ^ = --- - event_capacity --servation_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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...