从过程PLSQL中检索用户定义的记录

时间:2016-04-14 06:28:02

标签: oracle stored-procedures plsql user-defined-types

我终于破解了。这是我们的学校作业:

  

在名为 get_class_infor college_package 中添加其他程序。   get_class_infor过程用于获取并返回类   id,教师姓名,课程名称和特定部门   类。将CLASS_ID作为IN参数传递。定义用户定义的记录   TYPE用于过程中的记录变量。

     

创建一个匿名块以调用 get_class_infor 过程并显示   关于课程的信息。以下示例使用类ID 01。

** Class id:     1
** Instructor:   Gunther Haas
** Course Title: Algebra I
** Department:   Mathematics

我创建了这个匿名块,以确保我了解如何发送参数并检索用户定义的记录。这完全没问题。

ANONYMOUS BLOCK:

DECLARE
   TYPE class_type IS RECORD (
     class_id  classes.class_id%TYPE,
     i_first   instructors.first_name%TYPE,
     i_last    instructors.last_name%TYPE,
     course    courses.title%TYPE,
     dept      sections.title%TYPE
   );
   p_rec class_type;
   PROCEDURE get_class_infor(
      p_id IN NUMBER,
      p_rec OUT class_type
   ) IS
   BEGIN
      SELECT cl.class_id, i.first_name, i.last_name, cr.title, s.title 
      INTO p_rec 
      FROM classes cl 
         JOIN instructors i ON cl.instr_id = i.instructor_id
         JOIN courses cr    ON cl.course_id = cr.course_id
         JOIN sections s    ON cr.section_code = s.section_code
         WHERE class_id = p_id;
   END get_class_infor;
BEGIN
   get_class_infor(:class_id, p_rec);
   DBMS_OUTPUT.PUT_LINE('** Class id:     ' || p_rec.class_id);
   DBMS_OUTPUT.PUT_LINE('** Instructor:   ' || p_rec.i_first || ' ' || p_rec.i_last);
   DBMS_OUTPUT.PUT_LINE('** Course Title: ' || p_rec.course);
   DBMS_OUTPUT.PUT_LINE('** Department:   ' || p_rec.dept);
END;

我被困在哪里正确地创建包规格/身体,或者我假设。我不知道我错过了什么。这就是我得到的。

包装规范:

-- Example 4_2A
CREATE OR REPLACE PACKAGE college_package IS
  TYPE class_type IS RECORD (
    class_id  classes.class_id%TYPE,
    i_first   instructors.first_name%TYPE,
    i_last    instructors.last_name%TYPE,
    course    courses.title%TYPE,
    dept      sections.title%TYPE
  );
  PROCEDURE get_class_infor (
     p_id IN NUMBER, 
     p_rec OUT class_type
  );
END college_package;

PACKAGE BODY:

-- Example 4_2B
CREATE OR REPLACE PACKAGE BODY college_package IS
  PROCEDURE get_class_infor (
    p_id IN NUMBER,
    p_rec OUT class_type
  ) IS
  BEGIN
    SELECT cl.class_id, i.first_name, i.last_name, cr.title, s.title
    INTO p_rec 
    FROM classes cl 
      JOIN instructors i  ON cl.instr_id = i.instructor_id
      JOIN courses cr     ON cl.course_id = cr.course_id
      JOIN sections s     ON cr.section_code = s.section_code
      WHERE class_id = p_id;
  END;
END college_package;

ANONYMOUS BLOCK:

-- Example 4_2C
DECLARE
  TYPE class_type IS RECORD  (
    class_id  classes.class_id%TYPE,
    i_first   instructors.first_name%TYPE,
    i_last    instructors.last_name%TYPE,
    course    courses.title%TYPE,
    dept      sections.title%TYPE
  ); 
  v_rec class_type;
BEGIN
   college_package.get_class_infor(:class_id, v_rec);
   DBMS_OUTPUT.PUT_LINE('** Class id:     ' || v_rec.class_id);
   DBMS_OUTPUT.PUT_LINE('** Instructor:   ' || v_rec.i_first || ' ' || v_rec.i_last);
   DBMS_OUTPUT.PUT_LINE('** Course Title: ' || v_rec.course);
   DBMS_OUTPUT.PUT_LINE('** Department:   ' || v_rec.dept);
END;

我得到的错误信息是:

  

ORA-06550:第12行,第4栏:
  PLS-00306:调用'GET_CLASS_INFOR'时参数的数量或类型错误   ORA-06550:第12行,第4栏:
  PL / SQL:忽略语句

我是如何创建包规范/正文的?我想自己找到答案,以便对正确方向的暗示表示赞赏。

1 个答案:

答案 0 :(得分:3)

您已在包规范中定义了记录类型。这意味着您可以在其他程序中使用它,就像您可以调用该过程一样。

但是你所做的是在你的匿名块中声明第二个记录类型。它们看起来和你一样,因为它们有相同的名称和结构。但是对于编译器来说它们是不同的,因为它们是不同的东西。该过程需要包中定义的记录类型。

所以修复非常简单:

DECLARE
  v_rec college_package.class_type;
BEGIN
   college_package.get_class_infor(:class_id, v_rec);
   DBMS_OUTPUT.PUT_LINE('** Class id:     ' || v_rec.class_id);
   DBMS_OUTPUT.PUT_LINE('** Instructor:   ' || v_rec.i_first || ' ' || v_rec.i_last);
   DBMS_OUTPUT.PUT_LINE('** Course Title: ' || v_rec.course);
   DBMS_OUTPUT.PUT_LINE('** Department:   ' || v_rec.dept);
END;