我有两个表:
students(student_id, first_name, last_name)
classes(classid, incharge_student_id)
我已经编写了一个包,其中将以classid
作为参数,然后为班级表的每个student_id, first_name, last_name
打印来自students表的incharge_student_id
CREATE OR REPLACE PACKAGE pack1
AS
PROCEDURE show_info(c_id classes.classid%TYPE DEFAULT 1, show_info_recordset OUT SYS_REFCURSOR);
END pack1;
/
CREATE OR REPLACE PACKAGE BODY pack1
AS
PROCEDURE show_info
(
c_id NUMBER DEFAULT 1,
show_info_recordset OUT SYS_REFCURSOR
)
IS
v_first_name students.first_name%TYPE;
v_last_name students.last_name%TYPE;
v_students students.student_id%TYPE;
BEGIN
SELECT students.first_name, students.last_name, students.student_id
INTO v_first_name, v_last_name, v_students
FROM students, classes
WHERE (classes.classid = c_id AND classes.incharge_student_id=students.student_id);
DBMS_OUTPUT.PUT_LINE('Class ID: ' || c_id);
DBMS_OUTPUT.PUT_LINE('FIRST NAME: ' || v_first_name);
DBMS_OUTPUT.PUT_LINE('LAST NAME: ' || v_last_name);
DBMS_OUTPUT.PUT_LINE('student_id: ' || v_students);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Class ID: ' || c_id || ' not found.');
END;
END pack1;
/
我收到警告消息
Package Body created with compilation errors.
我是pl / sql的新手,想知道为什么我会收到错误消息,然后还想知道如何执行具有参数的程序包。
我知道如何执行常规程序包:
variable x refcursor;
exec package_name.procedure_name ( :x );
print x;
但是我将如何使用参数执行上述程序包
答案 0 :(得分:1)
您的代码中有几个错误,请参见下文:
CREATE OR REPLACE PACKAGE pack1
AS
PROCEDURE show_info(c_id classes.classid%TYPE, show_info_recordset OUT SYS_REFCURSOR);
END pack1;
/
CREATE OR REPLACE PACKAGE BODY pack1
AS
PROCEDURE show_info
(
c_id NUMBER DEFAULT -1,
主体中c_id参数的规范与规范中的规范不匹配。将其更改为c_id classes.classid%type default 1
,然后在井上方的规范中添加default 1
限定符。
show_info_recordset OUT SYS_REFCURSOR
)
IS
v_first_name IN students.first_name%TYPE;
v_last_name IN students.last_name%TYPE;
v_students IN students.student_id%TYPE;
删除变量声明中的“ IN”关键字。它仅用于参数声明。
BEGIN
SELECT students.first_name, students.last_name, students.student_id
INTO v_first_name, v_last_name, v_students.student_id
将您中的v_students引用到子句中,而不是v_students.student_id
FROM students, classes
WHERE (classes.classid = c_id AND classes.incharge_student_id=students.student_id;);
右括号内有一个多余的分号(;
)。删除它。
DBMS_OUTPUT.PUT_LINE('Class ID: ' || c_id);
DBMS_OUTPUT.PUT_LINE('FIRST NAME: ' || v_first_name);
DBMS_OUTPUT.PUT_LINE('LAST NAME: ' || v_last_name);
DBMS_OUTPUT.PUT_LINE('student_id: ' || v_students);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Class ID: ' || c_id || ' not found.');
END;
END pack1;
/
要执行此代码,您只需要传入附加参数,或使用@Littlefoot提到的命名参数,尽管由于您没有将游标分配给out参数,所以没有任何可打印的内容。 / p>
答案 1 :(得分:0)
如果使用SQL * Plus,请执行
SQL> show err
编译软件包后;它会将您指向导致错误的行。例如:
SQL> create or replace procedure p_test is
2 begin
3 select 1 from dual;
4 end;
5 /
Warning: Procedure created with compilation errors.
SQL> show err
Errors for PROCEDURE P_TEST:
LINE/COL ERROR
-------- -----------------------------------------------------------------
3/3 PLS-00428: an INTO clause is expected in this SELECT statement
SQL>
如果使用GUI,它可能包含您可以检查的“错误”标签(并获得相同的信息)。
在调用带有参数的过程时:只需包含它们,例如
variable x refcursor;
exec package_name.procedure_name (100, :x );
print x; ^
|
this is the first procedure's parameter
答案 2 :(得分:0)
删除变量名后的IN,您需要运行PROCEDURE而不是程序包,这也是为什么要在您的情况下定义过程使其更好地起作用的原因