【问题标题】:How to output the a record that is the result of a procedure?如何输出作为程序结果的记录?
【发布时间】:2016-12-18 15:08:44
【问题描述】:

所以,假设我有一张这样的桌子:

CREATE TABLE MEETINGS(
    MEETING_DAY DATE,
    MEETING_ROOM NVARCHAR2(10),
    MEETING_DURATION NUMBER(2)
);

还有一个像这样的程序,它接收日期和会议室,并返回一个记录,其中包含在给定日期将在会议室中发生的会议持续时间:

CREATE OR REPLACE PROCEDURE meetings_for_today(
    v_room IN NVARCHAR2, v_day IN DATE, result_meetings OUT SYS_REFCURSOR)
    IS BEGIN
        OPEN result_meetings FOR
            SELECT  MEETING_DAY, MEETING_DURATION
            FROM MEETINGS
            WHERE MEETING_DAY = v_day AND MEETING_ROOM = v_room;
END;
/

但我想检查该程序是否真的有效,我在这个主题上搜索了很多,但我发现很难找到解决方案。

所以我尝试过这样做:

DECLARE
  meeting_res MEETINGS%ROWTYPE; 
  v_refcur sys_refcursor;

BEGIN
    meetings_for_today('1A', to_date('12/12/2016', 'dd/mm/yyyy'), v_refcur);
    LOOP
    fetch v_refcur into meeting_res;
    exit when v_refcur%notfound;
    dbms_output.put_line(meeting_res.MEETING_DAY || ' ' || meeting_res.MEETING_DAY);
end loop;
End;
/

这给了我以下错误:

第 1 行的错误: ORA-06504: PL/SQL: 结果集变量或查询的返回类型不匹配 ORA-06512: 在第 8 行

我做错了什么?

PS:请不要给我有效的代码;向我解释我的推理出了什么问题以及我应该如何更好地使用 Oracle 的资源:)

【问题讨论】:

    标签: oracle stored-procedures plsql


    【解决方案1】:

    PS:请不要给我有效的代码,请解释我有什么问题 我的推理以及我应该如何更好地使用 oracle 的资源:)

    这个变量:

    meeting_res MEETINGS%ROWTYPE; 
    

    类型:MEETINGS%ROWTYPE;
    这意味着,这是由 MEETINGS 表的所有 3 列 组成的行(记录):

    CREATE TABLE MEETINGS(
        MEETING_DAY DATE,
        MEETING_ROOM NVARCHAR2(10),
        MEETING_DURATION NUMBER(2)
    );
    

    但是光标返回只有2列,看这里的SELECT子句,那里只有2列:MEETING_DAY + MEETING_DURATION

     OPEN result_meetings FOR
                SELECT  MEETING_DAY, MEETING_DURATION
                FROM MEETINGS .....
    

    因此,您正试图从包含 2 列的游标中获取记录,并将其放入由 3 列组成的变量中。
    它们肯定不匹配(3 cols vs 2 cols),你会得到 ORA-06504 错误。


    您可以声明由 2 列组成的自己的记录类型

      type my_type is record(
         MEETING_DAY date , MEETING_DURATION number(2)
      );
    

    并以这种方式在您的代码中使用它:

    DECLARE
      type my_type is record(
         MEETING_DAY date , MEETING_DURATION number(2)
      );
      meeting_res my_type; 
      v_refcur sys_refcursor;
    
    BEGIN
        meetings_for_today('1A', to_date('12/12/2016', 'dd/mm/yyyy'), v_refcur);
        LOOP
        fetch v_refcur into meeting_res;
        exit when v_refcur%notfound;
        dbms_output.put_line(meeting_res.MEETING_DAY || ' ' || meeting_res.MEETING_DAY);
    end loop;
    End;
    /
    

    注意 - 列的数量以及对应列的类型必须匹配,或者至少它们的数据类型必须是“兼容的” - 如果 Oracle 能够将一个值转换为另一个值(例如 NUMBER 可以是转换为 VARCHAR2),否则如果 Oracle 无法将某些值转换为另一种数据类型,您将得到 ORA-06504(例如 NUMBER 到 DATE)。

    【讨论】:

    • 天哪,非常感谢!您的回答非常详尽,这正是我试图理解的。我很高兴我接近正确答案!
    猜你喜欢
    • 1970-01-01
    • 2016-07-16
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 2012-01-29
    • 2019-10-13
    • 1970-01-01
    相关资源
    最近更新 更多