【问题标题】:Oracle Package or function in invalid stateOracle 包或函数处于无效状态
【发布时间】:2013-05-06 15:37:22
【问题描述】:

尝试创建一个基于 pl/sql 游标的函数以从 oracle 数据库返回详细信息。

相关表MEETING 具有列 MEETING_ID: number(10), TIME: timestamp(4), TITLE: varchar(20)

CREATE OR REPLACE FUNCTION GetMeeting
                    (meetingnumber MEETING.MEETING_ID%TYPE)
RETURN VARCHAR
IS
    CURSOR current_meeting(meetingnumber MEETING.MEETING_ID%TYPE)
    IS
        SELECT TITLE, TIME
        FROM MEETING
        WHERE MEETING_ID = meetingnumber;

    r_meeting current_meeting%ROWTYPE;
BEGIN
    OPEN current_meeting(meetingnumber);

    FETCH current_meeting INTO r_meeting;

    IF current_meeting%NOTFOUND THEN
        r_meeting.TITLE := 'UNKNOWN APPOINTMENT';
        END IF;

        CLOSE current_meeting;

        RETURN r_meeting.TITLE;
    END;


SELECT GetMeeting (27) name
FROM MEETING;

该函数似乎可以编译 - 但调用时会抛出

ORA-06575: 包或函数 GETMEETING 处于无效状态

【问题讨论】:

  • 该函数是说编译成功,还是编译成功并出现警告?如果是后者,您可以在之后立即执行show errors。你也可以稍后再做show errors function getmeeting 看看为什么无效。但是当您可能得到%notfound 时,您正在从r_meeting 返回一个值,这可能是运行时的问题?也许更重要的是,将返回声明为 varchar 而不是 varchar2 可能是一个问题,但我不会这么认为。
  • 这似乎没有什么问题。使用您的表定义,该函数可以编译并运行正常。你怎么称呼它没有意义,但我认为这是一个测试。更新 r_meeting 值可能不寻常,但似乎可以正常工作。
  • 它只是说:“函数已创建”。尝试启用显示错误;导致编译器发疯“遇到符号“SHOW””
  • 好的,据我所知,show errors 仅适用于 SQL*Plus 和 SQL Developer;您可以改为查看user_errors 表,但如果它表示编译成功,则不应显示任何内容。您使用的是哪个“编译器”? (你在endselect 之间有一个/ 你用来测试它吗?我从你的措辞中假设是这样,但它没有显示......)
  • 我实际上是单独运行了选择语句。使用 / 终止 plsql 会导致编译失败。编译器是 Application Express

标签: sql oracle plsql cursor


【解决方案1】:

也许这对你会更好:

create or replace function
  getmeeting(
    meeting_id number)
return
  varchar
is
  meeting_title meeting.title%Type;
begin
  select title
  into   meeting_title
  from   meeting
  where  meeting_id = getmeeting.meeting_id;

  return meeting_title;
exception
  when NO_DATA_FOUND then
     return 'UNKNOWN APPOINTMENT';
end;
/

未检查语法。

【讨论】:

    【解决方案2】:

    由作为 SQL 关键字的列标识符“TIME”生成的错误;执行时触发运行时错误。

    不幸的是,删除 'TIME' 时代码返回 NULL

    【讨论】:

    • 这个值并没有被使用,所以你最好删除它。然而,这似乎不是问题的答案。
    • 问题是关于 oracle 生成的特定错误,通过删除该特定列来修复该错误。不幸的是,您的代码(令人惊讶)引发了相同的错误。请注意,该函数仍然没有做任何有用的事情,因为某种原因它返回 NULL,除非触发了 UNKNOWN APPOINTMENT 异常。
    【解决方案3】:

    没有足够的事实要知道,但我会研究某种形式的循环依赖。

    select * 
      from user_dependencies 
     where referenced_name = 'GETMEETING' 
       and referenced_type = 'FUNCTION';
    

    避免循环依赖的最佳方法是使用仅在主体中引用其他包的包。避免使用独立的函数和过程对象。

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-17
      相关资源
      最近更新 更多