创建Oracle包体时出错

创建Oracle包体时出错,oracle,stored-procedures,plsql,Oracle,Stored Procedures,Plsql,我的包中有以下主体,用于在HR模式中执行一些CRUD操作: 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,

我的包中有以下主体,用于在HR模式中执行一些CRUD操作:

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
我应该如何纠正这些错误?我更改了代码中的一些名称,因为这是一项任务,我在尝试无误地完成它时遇到了困难

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;
如果要这样做,您应该在
INSERT
语句中使用局部变量
id
,而不是直接调用
emp_sequence.nextval
。但就我个人而言,我会去掉局部变量,去掉初始的
SELECT
,然后在
INSERT
语句中调用
emp\u序列

11/17    PL/SQL: ORA-00913: too many 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个变量中。假设您不想返回
员工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\u emp
过程,但创建一个返回
employees%rowtype
记录的函数通常更有意义

你的例外条款应该删除。充其量,他们正在丢弃错误堆栈,该堆栈将告诉一个人什么失败了,在哪里失败了。最坏的情况是,它们隐藏了错误(您永远不应该假设任何人都会看到您写入到
dbms\u output
)的任何内容,并使调用代码相信某些操作在没有成功的情况下成功了

您正在将数据选择到尚未声明的局部变量
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;
如果要这样做,您应该在
INSERT
语句中使用局部变量
id
,而不是直接调用
emp_sequence.nextval
。但就我个人而言,我会去掉局部变量,去掉初始的
SELECT
,然后在
INSERT
语句中调用
emp\u序列

11/17    PL/SQL: ORA-00913: too many 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个变量中。假设您不想返回
员工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\u emp
过程,但创建一个返回
employees%rowtype
记录的函数通常更有意义

你的例外条款应该删除。充其量,他们正在丢弃错误堆栈,该堆栈将告诉一个人什么失败了,在哪里失败了。最坏的情况是,它们隐藏了错误(您永远不应该假设任何人都会看到您写入到
dbms\u output
)的任何内容,并使调用代码相信某些操作在没有成功的情况下成功了

您正在将数据选择到尚未声明的局部变量
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;
如果要这样做,您应该在
INSERT
语句中使用局部变量
id
,而不是直接调用
emp_sequence.nextval
。但就我个人而言,我会去掉局部变量,去掉初始的
SELECT
,然后在
INSERT
语句中调用
emp\u序列

11/17    PL/SQL: ORA-00913: too many 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个变量中。假设您不想返回
员工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\u emp
过程,但创建一个返回
employees%rowtype
记录的函数通常更有意义

你的例外条款应该删除。充其量,他们正在丢弃错误堆栈,该堆栈将告诉一个人什么失败了,在哪里失败了。最坏的情况是,它们隐藏了错误(您永远不应该假设任何人都会看到您写入到
dbms\u output
)的任何内容,并使调用代码相信某些操作在没有成功的情况下成功了

您正在将数据选择到尚未声明的局部变量
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;
如果要这样做,您应该在
INSERT
语句中使用局部变量
id
,而不是