【问题标题】:PLS-00103 Oracle stored procedure errorPLS-00103 Oracle 存储过程错误
【发布时间】:2012-11-24 17:50:17
【问题描述】:

我是存储过程的新手。 我正在尝试运行存储过程并收到以下错误: 我收到 PLS-00103:在预期以下情况之一时遇到符号“SELECT”:开始函数杂注过程... PLS-00103:在期待以下情况之一时遇到符号“RETURN”:* & = - + at in is mod remaining not rem then... 我尝试搜索导致这些错误的原因以及与此类似的示例,但结果还不够。关于为什么会发生这些错误的任何线索? 这是代码:

CREATE OR REPLACE PROCEDURE LIST_ACTIONS_CHECK_ADD 
(
  LISTNAME IN VARCHAR2  
) AS 
BEGIN
 DECLARE CNT NUMBER;
 SELECT COUNT(LIST_NAME) INTO CNT FROM LISTS_MASTER WHERE LIST_NAME = LISTNAME;
IF (CNT > 0)
 RETURN 1
ELSE
 RETURN 0
END IF;
END LIST_ACTIONS_CHECK_ADD;

新代码:

CREATE OR REPLACE PROCEDURE LIST_ACTIONS_CHECK_ADD 
(
  P_LISTNAME IN VARCHAR2  
) 
AS 
 L_CNT NUMBER;
BEGIN
 SELECT COUNT(LIST_NAME) 
   INTO L_CNT 
   FROM LISTS_MASTER 
  WHERE LIST_NAME = P_LISTNAME;
 IF (L_CNT > 0)
   RETURN 1;
 ELSE
   RETURN 0;
  END IF;
END LIST_ACTIONS_CHECK_ADD;

【问题讨论】:

    标签: sql oracle stored-procedures plsql


    【解决方案1】:
    • (更正 #1)不能在过程中返回值;应删除 LIST_ACTIONS_CHECK_ADD 并将其声明为函数以返回 NUMBER
    • (更正 #2)您需要按如下方式移动 CNT 的声明(见下文)
    • (更正 #3)您需要在 return 语句中使用分号:
    • (更正 #4)在 IF (CNT > 0) 之后需要一个 THEN(见下文):


    DROP PROCEDURE LIST_ACTIONS_CHECK_ADD;
    CREATE OR REPLACE FUNCTION LIST_ACTIONS_CHECK_ADD
    (
       LISTNAME IN VARCHAR2  
    ) 
    
    RETURN NUMBER AS 
    
      CNT NUMBER;
    BEGIN
        SELECT COUNT(LIST_NAME) INTO CNT FROM LISTS_MASTER WHERE LIST_NAME = LISTNAME;
        IF (CNT > 0) THEN
           RETURN 1;
        ELSE
           RETURN 0;
        END IF;
    END LIST_ACTIONS_CHECK_ADD;
    

    这可以从 SQLPLUS 执行为:

    SET SERVEROUTPUT ON SIZE 100000;
    DECLARE
        V_RESULT NUMBER;
    BEGIN
    
        V_RESULT := LIST_ACTIONS_CHECK_ADD('X');
        DBMS_OUTPUT.PUT_LINE('RESULT: ' || V_RESULT);
    
    END;    
    

    【讨论】:

    • 谢谢!我正在尝试调用此函数。我试过打电话 LIST_ACTIONS_CHECK_ADD('NAME');我用执行尝试了同样的事情
    • 这行得通:从 dual 中选择 LISTS_ACTIONS_CHECK_ADD('BLACKLIST');
    • SQLPLUS 不会使用 LIST_ACTIONS_CHECK_ADD('NAME');如果 LIST_ACTIONS_CHECK_ADD 是一个函数 - 你需要一个匿名 PLSQL 块 - 我会编辑上面的帖子,好吗?
    • 是的。非常感谢您的建议
    【解决方案2】:

    存储过程声明的骨架是

    CREATE OR REPLACE PROCEDURE procedure_name( <<parameters>> ) 
    AS
      <<variable declarations>>
    BEGIN
      <<code>>
    END procedure_name;
    

    在您发布的代码中,

    1. 您将BEGIN 放在变量声明之前
    2. 您有一个无关的 DECLARE-- 只有在声明不涉及 CREATE 的 PL/SQL 块时才使用它。
    3. RETURN 语句后缺少分号。
    4. 过程不能返回值。如果你想返回 1 或 0,你可能需要一个函数,而不是一个过程。如果需要过程,可以声明OUT参数。
    5. 您在IF 之后缺少THEN

    听起来你想要类似的东西

    CREATE OR REPLACE FUNCTION LIST_ACTIONS_CHECK_ADD 
    (
      LISTNAME IN VARCHAR2  
    ) 
      RETURN NUMBER
    AS 
     CNT NUMBER;
    BEGIN
     SELECT COUNT(LIST_NAME) 
       INTO CNT 
       FROM LISTS_MASTER 
      WHERE LIST_NAME = LISTNAME;
     IF (CNT > 0)
     THEN
       RETURN 1;
     ELSE
       RETURN 0;
      END IF;
    END LIST_ACTIONS_CHECK_ADD;
    

    请注意,一般来说,您最好使用某种命名约定来确保参数和局部变量不共享列名。试图弄清楚LISTNAME 是参数还是列名以及LIST_NAME 和LISTNAME 之间的区别是什么,通常会让未来的程序员感到困惑。就个人而言,我对参数使用p_ 前缀,对局部变量使用l_ 前缀。我还建议使用锚定类型——lists_master.list_name%type 如果这是传入的内容

    CREATE OR REPLACE FUNCTION LIST_ACTIONS_CHECK_ADD 
    (
      P_LIST_NAME IN lists_master.list_name%type
    ) 
      RETURN NUMBER
    AS 
     L_CNT NUMBER;
    BEGIN
     SELECT COUNT(LIST_NAME) 
       INTO L_CNT 
       FROM LISTS_MASTER 
      WHERE LIST_NAME = P_LIST_NAME;
     IF (L_CNT > 0)
     THEN
       RETURN 1;
     ELSE
       RETURN 0;
      END IF;
    END LIST_ACTIONS_CHECK_ADD;
    

    【讨论】:

    • 非常感谢您的帮助。除了使用锚定类型外,我已经使用了您的所有建议。根据我在查看锚定类型后的理解,您的 in 参数是从 list_name 列的 lists_master 表中获取的?实际上我只是希望它是一个我希望输入的参数:CALL LIST_ACTIONS_CHECK_ADD('BLACKLIST');
    • 现在,当我按照您的建议编译代码时,我得到 Error(13,4): PLS-00103: Encountered the symbol "RETURN" when expecting 以下之一:* & = - + >...知道为什么吗?我编辑了原始问题以包含新代码
    • @jon - 锚定类型只是指定您传入的参数是 lists_master.list_name 当前定义的任何类型。即使该字符串不在表中,这也不会阻止您传入硬编码字符串。这确实意味着如果list_name 列的数据类型发生变化,参数的数据类型也会发生变化,并为下一个开发人员提供有关预期数据类型的文档。
    • @jon - 请注意,我更新了我的答案。我错过了 A B 在他的回答中指出的几个问题。
    • 看到了。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多