Oracle procedure works only when set serveroutput on;

痴心易碎 提交于 2019-12-23 12:08:09

问题


Strange behavior trying to insert a record with a stored procedure. Only works with set serveroutput on:

Thanks.

SQL*Plus: Release 11.2.0.1.0 Production on Tue May 31 22:48:25 2016

Copyright (c) 1982, 2010, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options

SQL> exec abc_utils.abc_init(p_table_name => 'ABC_TEST', p_batch_alias => 'TST');
BEGIN abc_utils.abc_init(p_table_name => 'ABC_TEST', p_batch_alias => 'TST'); END;

*
ERROR at line 1:
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at "TESTUSR.abc_utils", line 1743
ORA-06512: at line 1


SQL> set serveroutput on;
SQL> exec abc_utils.abc_init(p_table_name => 'ABC_TEST', p_batch_alias => 'TST');

PL/SQL procedure successfully completed.


    PROCEDURE abc_init(p_table_name    IN VARCHAR2,
                           p_batch_alias   IN VARCHAR2) IS

    v_sql                VARCHAR2(32000);

    --object caller variables
    v_owner              VARCHAR2(30 CHAR);
    v_obj_name           VARCHAR2(30 CHAR);
    v_line_no            NUMBER;
    v_caller_type        VARCHAR2(30 CHAR);
    v_caller             VARCHAR2(4000 CHAR);


    BEGIN
     owa_util.who_called_me(v_owner, v_obj_name, v_line_no, v_caller_type);
       v_caller := 'Object Name: ' || $$plsql_unit || '; Caller Name: ' || v_obj_name || '; Caller Line: ' || to_char(v_line_no);

         --initialise summary table
       v_sql := 'INSERT INTO INIT_SUMMARY (BATCH_ALIAS,TABLE_NAME,START_DT,BATCH_USER,BATCH_RUN) ' ||
                'SELECT a.BATCH_NAME,:1,:2,a.BATCH_USER,:3 FROM INIT_CFG a WHERE 1 = 1 AND BATCH_NAME = :4';

       EXECUTE IMMEDIATE v_sql USING p_table_name,SYSDATE,summary_seq.nextval,p_batch_alias;
       COMMIT;

       EXCEPTION
          WHEN OTHERS THEN
             gv_err_msg := substr('Back Trace: ' ,1,4000);
             RAISE_APPLICATION_ERROR(-20001,'abc_init: ' || gv_err_msg);
    END abc_init;
    --********************************************************************

回答1:


The error is coming from the package instantiation:

When a session references a package item, Oracle Database instantiates the package for that session. Every session that references a package has its own instantiation of that package.

When Oracle Database instantiates a package, it initializes it. Initialization includes whichever of the following are applicable: ...

  • Executing the initialization part of the package body

That instatiation only happens once per session. Your first call to the procedure executes the initialisation section. The second call does not. The set serveroutput on isn't having any effect, it is just that it is the second call that works, and that is because that initialisation isn't called the second time.

So the error is coming from the initialisation part of the package body, which is right at the end - after all the procedures and functions etc. you have a begin before the final end of the package. Something like:

create or replace package body abc_utils as
  ...
  some_var number; -- package state variable
  ...
  procedure abc_init is
    ...
  begin
    ...
  end abc_init;
  ...
/* package initialisation */
begin
  select some_col into some_var from some_table;  -- line 1743
end abc_utils;
/

The code in that block will include line 1743, and that will be a select ... into which is finding more than one row. You haven't shown that code, but it is that which you need to investigate.



来源:https://stackoverflow.com/questions/37555617/oracle-procedure-works-only-when-set-serveroutput-on

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!