【问题标题】:How to return output from stored procedure - Oracle如何从存储过程返回输出 - Oracle
【发布时间】:2022-08-07 18:10:39
【问题描述】:

我创建了一个 PL/SQL 存储过程,我想从中返回输出并显示它。

我想将成功或失败消息的输出返回到变量中:MSG

我怎么需要这样做任何想法

PL/SQL 代码:

CREATE OR REPLACE PROCEDURE CHECKFILED
(
    MY_NAME EMP.FIRSTNAME%TYPE,
    MY_ID   EMP.ID%TYPE

) RETURN VARCHAR2

IS 
     V_MSG VARCHAR(4000 CHAR);  

BEGIN
       
     SELECT FIRSTNAME INTO MY_NAME FROM EMP WHERE ID=MY_ID;

     IF MY_NAME IS NOT NULL THEN 
          INSERT INTO CUSTOMER VALUES (UID,FIRSTNAME);  
          V_MSG=\'FIELD IS NOT EMPTY\';
     ELSE
          RAISE_APPLICATION_ERROR(-20000,\'FIELD IS EMPTY\'); 
     END IF; 
     


     EXCEPTION 
            WHEN OTHERS THEN
                V_MSG := SQLCODE || \'-\' || SQLERRM;  
                RETURN(V_MSG);

     RETURN(V_MSG);  

END; 

调用存储过程:

DECLARE 
     MSG VARCHAR2(4000 CHAR);
BEGIN  
     SELECT CHECKFILED(\'10A\') AS MSG FROM DUAL; 
END;
  • 为什么需要这样做而不是使用 PL/SQL 中内置的错误处理?程序成功与否无需返回信息;相反,如果出现错误,您就知道它失败了,否则它就成功了。
  • 只是为了评论代码,SQLCODE || \'-\' || SQLERRM 是多余的,因为sqlerrm 已经包含sqlcode。例如,如果 sqlerrm 是ORA-12345 这里有一些错误消息, 那么 sqlcode 是 -12345 你会返回-12345-ORA-12345 这里有一些错误信息.为什么要这样做?

标签: oracle plsql


【解决方案1】:

如果它是一个过程,它应该有一个出去参数,然后将用于返回一些值。

像这样的东西;请注意,检查select 是否返回null(员工确实有姓名;select 将返回没有行因此引发no_data_found 异常)。

CREATE OR REPLACE PROCEDURE checkfiled (my_id  IN     emp.id%TYPE,
                                        v_msg     OUT VARCHAR2)
IS
   my_name  emp.firstname%TYPE;
BEGIN
   SELECT firstname
     INTO my_name
     FROM emp
    WHERE id = my_id;

   INSERT INTO customer
        VALUES (UID, firstname);

   v_msg := 'FIELD IS NOT EMPTY';
EXCEPTION
   WHEN OTHERS
   THEN
      v_msg := SQLCODE || '-' || SQLERRM;
END;

然后,您将其称为

DECLARE
   msg  VARCHAR2 (4000 CHAR);
BEGIN
   checkfiled ('10A', msg);

   DBMS_OUTPUT.put_line ('Procedure returned ' || msg);
END;
/

【讨论】:

    【解决方案2】:

    PROCEDUREs 没有任何返回值。如果你想返回一个值,它需要是一个FUNCTION。试试下面的代码。

    CREATE OR REPLACE FUNCTION CHECKFILED (MY_NAME EMP.FIRSTNAME%TYPE, MY_ID EMP.ID%TYPE)
        RETURN VARCHAR2
    IS
        V_MSG   VARCHAR (4000 CHAR);
    BEGIN
        SELECT FIRSTNAME
          INTO MY_NAME
          FROM EMP
         WHERE ID = MY_ID;
    
        IF MY_NAME IS NOT NULL
        THEN
            INSERT INTO CUSTOMER
                 VALUES (UID, FIRSTNAME);
    
            V_MSG := 'FIELD IS NOT EMPTY';
        ELSE
            RAISE_APPLICATION_ERROR (-20000, 'FIELD IS EMPTY');
        END IF;
    
        RETURN (V_MSG);
    EXCEPTION
        WHEN OTHERS
        THEN
            V_MSG := SQLCODE || '-' || SQLERRM;
            RETURN (V_MSG);
    END;
    

    【讨论】:

    • 这是值得怀疑的。如果这是一个函数,它就不能执行 DDL,因为 - 如果你使用 SELECT 语句调用它 - 你会得到“ORA-14551: cannot perform a DML operation inside a query”,除非它是一个自治事务。但是,如果在赋值语句中使用它会起作用,但是 - 通常,DDL 应该在过程中使用,而不是在函数中使用。
    • 作为补充:具有副作用的功能不是消费者通常所期望的(可能除了日志记录)。
    猜你喜欢
    • 1970-01-01
    • 2012-12-24
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 2015-08-18
    • 2020-08-03
    • 1970-01-01
    • 2018-07-28
    相关资源
    最近更新 更多