【问题标题】:ORA-24344: success with compilation error in Oracle Apex when compiling a packageORA-24344: 编译包时在 Oracle Apex 中编译错误成功
【发布时间】:2018-01-06 02:33:25
【问题描述】:

我正在 Oracle Apex 中处理我的大学数据库项目,并在尝试使用以下代码编译正文包时收到 ORA-24344: success with compilation error

CREATE OR REPLACE PACKAGE BODY band_price_package AS 
-- Function that checks if a band has a manager 
FUNCTION agent_present(band_id BAND.Band_id%TYPE)
RETURN BOOLEAN
IS
BEGIN
 IF BAND.Agent_firstname IS NULL
    AND BAND.Agent_lastname IS NULL
    AND BAND.Agent_phone IS NULL
    AND BAND.Agent_email IS NULL
 THEN
  RETURN FALSE;
 ELSE
  RETURN TRUE;
 END IF;
END agent_present;
-- Procedure that gets the band hire price including agent fee 
PROCEDURE get_band_cost(band_id IN BAND.Band_id%TYPE, 
                        band_cost OUT BOOKING.Agreed_band_price%TYPE) 
IS 
BEGIN 
 IF agent_present(band_id) 
 THEN
  band_cost := BOOKING.Agreed_band_price * 1.25;
 ELSE
  band_cost := BOOKING.Agreed_band_price;
 END IF;
END get_band_cost;

END band_price_package; 
/

以下规范已编译,没有任何错误:

CREATE OR REPLACE PACKAGE band_price_package AS 
-- Function that checks if a band has a manager 
FUNCTION agent_present(band_id   BAND.Band_id%TYPE)
RETURN BOOLEAN;
-- Procedure that gets the band hire price including agent fee 
PROCEDURE get_band_cost(band_id IN BAND.Band_id%TYPE, 
                        band_cost OUT BOOKING.Agreed_band_price%TYPE); 

END band_price_package; 
/

【问题讨论】:

  • agent_present 函数指的是诸如band.agent_firstname 之类的东西,它们没有在任何地方声明。您需要查看编译错误。

标签: oracle plsql


【解决方案1】:

您不能直接在 PL/SQL 中访问表;所以

 IF BAND.Agent_firstname IS NULL
    AND BAND.Agent_lastname IS NULL
    AND BAND.Agent_phone IS NULL
    AND BAND.Agent_email IS NULL

是无效的语法。您需要像这样在 PL/SQL 块中使用 SQL 语句:

SQL Fiddle

Oracle 11g R2 架构设置

CREATE TABLE BAND(
  band_id INTEGER PRIMARY KEY,
  Agent_firstname VARCHAR2(200),
  Agent_lastname  VARCHAR2(200),
  Agent_phone     VARCHAR2(20),
  Agent_email     VARCHAR2(100)
)
/

CREATE TABLE BOOKING(
  Agreed_band_price NUMBER(10,2)
)
/

CREATE OR REPLACE PACKAGE band_price_package AS 
  -- Function that checks if a band has a manager 
  FUNCTION agent_present(
    i_band_id   BAND.Band_id%TYPE
  )
  RETURN BOOLEAN;

  -- Procedure that gets the band hire price including agent fee 
  PROCEDURE get_band_cost(
    i_band_id   IN  BAND.Band_id%TYPE, 
    o_band_cost OUT BOOKING.Agreed_band_price%TYPE
  );
END band_price_package; 
/

那么你可以这样做:

CREATE OR REPLACE PACKAGE BODY band_price_package AS 
  -- Function that checks if a band has a manager 
  FUNCTION agent_present(
    i_band_id BAND.Band_id%TYPE
  )
  RETURN BOOLEAN
  IS
    agent_exists NUMBER(1,0);
  BEGIN
    -- Check if an agent exists in the table.
    SELECT 1
    INTO   agent_exists
    FROM   band
    WHERE  band_id = i_band_id
    AND    (   Agent_firstname IS NOT NULL
           OR  Agent_lastname  IS NOT NULL
           OR  Agent_phone     IS NOT NULL
           OR  Agent_email     IS NOT NULL );

    RETURN TRUE;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      RETURN FALSE;
  END agent_present;

-- Procedure that gets the band hire price including agent fee 
  PROCEDURE get_band_cost(
    i_band_id   IN  BAND.Band_id%TYPE, 
    o_band_cost OUT BOOKING.Agreed_band_price%TYPE
  )
  IS
  BEGIN
    -- Not completed; since it is your homework.
    NULL;
  END get_band_cost;
END band_price_package; 
/

【讨论】:

  • 感谢您的建议,我没有意识到这需要 SQL 语句才能工作。
【解决方案2】:

您使用什么工具来访问数据库?在 SQLPlus 中,您应该运行SHOW ERR,它会告诉您代码有什么问题。例如:

SQL> create or replace function f_test return boolean is
  2  begin
  3    return 1 = 2   --> missing semi-colon
  4  end;
  5  /

Warning: Function created with compilation errors.

SQL> show err
Errors for FUNCTION F_TEST:

LINE/COL ERROR
-------- -----------------------------------------------------------------
4/1      PLS-00103: Encountered the symbol "END" when expecting one of the
         following:
         * & - + ; / at mod remainder rem <an exponent (**)> and or ||
         multiset
         The symbol ";" was substituted for "END" to continue.

SQL>

GUI 工具通常在 Object Navigator 中具有“错误”选项卡,显示相同。

对于您的代码,一些盲目的猜测(因为我们没有您的表格,也无法自己测试):

  • 函数 AGENT_PRESENT 接受 BAND_ID 作为参数,该参数声明为 BAND.BAND_ID 列数据类型。您不能以您的方式引用其他 BAND 表列 - 您应该将这些列选择到变量中(或者,如果需要,声明一个行类型变量并使用它)然后检测它们是否存在。
  • 过程 GET_BAND_COST 调用未知的 BOOKING.AGREED_BAND_PRICE(至少,它没有在该包中声明)。那么,它是什么?是表格列吗?如果是这样,您不能那样修改它 - 请改用 UPDATE。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-01
    • 2020-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多