问题
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