如何使用参数执行包

时间:2018-11-27 20:24:40

标签: oracle stored-procedures plsql package

我有两个表:

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;

但是我将如何使用参数执行上述程序包

3 个答案:

答案 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而不是程序包,这也是为什么要在您的情况下定义过程使其更好地起作用的原因