10/38 PLS-00201: 'ID' must be declared
Wybierasz dane do zmiennej lokalnej ID
to nie zostało ogłoszone. Jeśli chcesz zadeklarować zmienną lokalną, zrób to w sekcji deklaracji między AS
i BEGIN
PROCEDURE create_emp(p_last_name IN employees.last_name%type,
p_first_name IN employees.first_name%type,
p_email IN employees.email%type,
p_hire_date IN employees.hire_date%type,
p_job_id IN employees.job_id%type)
AS
id integer;
BEGIN
SELECT emp_sequence.NEXTVAL INTO id FROM dual;
Jeśli masz zamiar to zrobić, użyj lokalnej zmiennej id
w swoim INSERT
zamiast wywoływania emp_sequence.nextval
bezpośrednio. Osobiście jednak pozbyłbym się zmiennej lokalnej, pozbyłbym się początkowego SELECT
i po prostu utwórz emp_sequence.nextval
zadzwoń w swoim INSERT
oświadczenie.
11/17 PL/SQL: ORA-00913: too many values
Niezależnie od tego, jak to zrobisz, będziesz potrzebować liczby kolumn w INSERT
aby dopasować liczbę VALUES
określisz.
PROCEDURE create_emp(p_last_name IN employees.last_name%type,
p_first_name IN employees.first_name%type,
p_email IN employees.email%type,
p_hire_date IN employees.hire_date%type,
p_job_id IN employees.job_id%type)
AS
id integer;
BEGIN
SELECT emp_sequence.NEXTVAL INTO id FROM dual;
INSERT INTO employees(employee_id, last_name, first_name, email, hire_date, job_id)
VALUES (id, p_last_name, p_first_name, p_email, p_hire_date, p_job_id);
END create_emp;
Lub jeśli chcesz wywołać sekwencję bezpośrednio
PROCEDURE create_emp(p_last_name IN employees.last_name%type,
p_first_name IN employees.first_name%type,
p_email IN employees.email%type,
p_hire_date IN employees.hire_date%type,
p_job_id IN employees.job_id%type)
AS
BEGIN
INSERT INTO employees(employee_id, last_name, first_name, email, hire_date, job_id)
VALUES ( emp_sequence.NEXTVAL, p_last_name, p_first_name, p_email, p_hire_date, p_job_id);
END create_emp;
Podobnie w przypadku następnego błędu liczba pobieranych zmiennych powinna odpowiadać liczbie wybranych kolumn
51/5 PL/SQL: ORA-00947: insufficient values
W swoim read_emp wybierasz 7 rzeczy i próbujesz umieścić je w 6 zmiennych. Zakładając, że nie chcesz zwracać employee_id
, nie przejmuj się jego zaznaczaniem.
PROCEDURE read_emp(p_employee_id IN employees.employee_id%type,
p_last_name OUT employees.last_name%type,
p_first_name OUT employees.first_name%type,
p_email OUT employees.email%type,
p_hire_date OUT employees.hire_date%type,
p_job_id OUT employees.job_id%type,
p_salary OUT employees.salary%type)
AS
BEGIN
SELECT last_name, first_name, email, hire_date, job_id, salary
INTO p_last_name, p_first_name, p_email, p_hire_date, p_job_id, p_salary
FROM EMPLOYEES
WHERE employee_id = p_employee_id;
END read_emp;
Chociaż możesz napisać read_emp
procedury takiej jak ta, ogólnie bardziej sensowne byłoby utworzenie funkcji, która zwraca employees%rowtype
zamiast tego nagrywaj.
Twoje klauzule wyjątków powinny zostać usunięte. W najlepszym razie odrzucają stos błędów, który powiedziałby osobie, co się nie udało i gdzie. W najgorszym przypadku ukrywają błędy (nigdy nie należy zakładać, że ktoś kiedykolwiek zobaczy coś, co napiszesz do dbms_output
) i spowodowanie, że kod wywołujący uwierzy, że jakaś operacja powiodła się, gdy się nie powiodła.