2014-10-15 4 views
0

У меня есть следующие тела из моего пакета, используемого, чтобы сделать некоторые операции CRUD в HR схеме:Ошибки создания тела пакета Oracle

CREATE SEQUENCE emp_sequence; 

CREATE OR REPLACE PACKAGE BODY employee_crud AS 

    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 
    SELECT emp_sequence.NEXTVAL INTO id FROM dual; 
    INSERT INTO employees(last_name, first_name, email, hire_date, job_id) 
    VALUES (emp_seq.nextval, p_last_name, p_first_name, p_email, p_hire_date, p_job_id); 
    EXCEPTION 
    WHEN DUP_VAL_ON_INDEX THEN 
    dbms_output.put_line('error'); 
    END create_emp; 


    PROCEDURE erase_emp(p_employee_id IN employees.employee_id%type) AS 
    BEGIN 
    DELETE FROM employees 
    WHERE employee_id = p_employee_id; 
    EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
    dbms_output.put_line('Error'); 
    END erase_emp; 


    PROCEDURE upd_emp(p_employee_id IN employees.employee_id%type, p_salary IN employees.salary%type, 
            p_email IN employees.email%type, p_department_id IN employees.department_id%type) AS 
    BEGIN 
    UPDATE employees 
    SET employee_id = p_employee_id, 
      salary = p_salary, 
      email = p_email, 
      department_id = p_department_id 
    WHERE employee_id = p_employee_id; 
    EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
    dbms_output.put_line('error'); 
    END upd_emp; 


    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 employee_id, 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; 
    EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
    dbms_output.put_line('Error'); 
    END read_emp; 

END employee_crud; 
/

После создания спецификации (что правильно), я создаю последовательность, чтобы помочь добавление сотрудников. Но, компилируя корпус пакета, он показывает следующие ошибки:

LINE/COL ERROR 
-------- ---------------------------------------------------- 
10/5  PL/SQL: SQL Statement ignored 
10/38 PLS-00201: 'ID' must be declared 
10/41 PL/SQL: ORA-00904: : identifier is not valid 
11/5  PL/SQL: SQL Statement ignored 
11/17 PL/SQL: ORA-00913: too many values 
49/5  PL/SQL: SQL Statement ignored 
51/5  PL/SQL: ORA-00947: insufficient values 

Что мне делать, чтобы исправить эти ошибки? Я изменил некоторые имена из своего кода, потому что это назначение, и у меня проблемы с попытками сделать это без ошибок.

+1

Вы не указали локальную переменную с именем 'ID'? Ошибки «слишком много значений» и «недостаточных значений» кажутся достаточно ясными - просто подсчитайте количество столбцов/значений в каждой части этих операторов. –

+0

'Что мне делать, чтобы исправить эти ошибки? «Лучший ответ - это изучение основ. Есть так много ошибок. И большинство из них даст вам ключ к чтению самого сообщения. Всего наилучшего! –

+0

@MaheswaranRavisankar, AlexPoole, я знаю, что у меня были некоторые небольшие ошибки, которые я раньше не видел (я новичок><).И хорошо, я не нашел причину своих ошибок, пока я не попросил здесь о помощи. Большое спасибо за ваши ответы. – KPavezC

ответ

3
10/38 PLS-00201: 'ID' must be declared 

Вы выбора данных в локальной переменной ID, которая не была объявлена. Если вы хотите, чтобы объявить локальную переменную, вы могли бы сделать это в разделе декларации между AS и 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; 

Если вы собираетесь сделать это, вы хотели бы использовать локальную переменную id в вашем заявлении INSERT, а не напрямую звонить emp_sequence.nextval. Лично, однако, я бы избавился от локальной переменной, избавлюсь от начального SELECT и просто сделаю вызов emp_sequence.nextval в вашем заявлении INSERT.

11/17 PL/SQL: ORA-00913: too many values 

Независимо от того, как вы это делаете, хотя, вы должны были бы количество столбцов в INSERT, чтобы соответствовать количеству VALUES вы укажете.

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; 

Или, если вы хотите, чтобы вызвать последовательность непосредственно

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; 

Аналогично для следующей ошибки, количество переменных, которые вы запрашиваете в должно соответствовать числу столбцов, которые вы выбираете

51/5  PL/SQL: ORA-00947: insufficient values 

В вашем read_emp вы выбираете 7 вещей и пытаетесь поместить их в 6 переменных. Предполагая, что вы не хотите возвращать employee_id, не утруждайте его выбором.

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; 

В то время как вы можете написать read_emp процедуру, как это, как правило, больше смысла, чтобы создать функцию, которая возвращает employees%rowtype запись вместо.

Ваши исключения должны быть удалены. В лучшем случае они отбрасывают стек ошибок, который расскажет человеку, что не удалось и где. В худшем случае они скрывают ошибки (вы никогда не должны предполагать, что кто-нибудь увидит что-нибудь, что вы напишете, до dbms_output) и заставляя вызывающий код полагать, что некоторая операция удалась, когда она этого не сделала.

+0

Эй, у меня было слишком много небольших ошибок, мне очень стыдно! Большое вам спасибо за помощь и за ваши советы. Я делаю исключения, потому что я учусь использовать это :) – KPavezC

Смежные вопросы