我的包中有以下主体,用于在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_sequence.nextval
。
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
的任何东西),并导致调用代码相信某个操作成功了,但它没有成功。