2016-05-31 5 views
4

Seltsames Verhalten, das versucht, einen Datensatz mit einer gespeicherten Prozedur einzufügen. Funktioniert nur mit set serveroutput on:Oracle-Prozedur funktioniert nur, wenn der Serveroutput eingeschaltet ist;

Danke.

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

Ich erwarte, dass Zeile 1743 ist in der Paket Initialisierung Abschnitt - der Anfang/Ende Block im Paketkörper nach all den Verfahren und Funktionen. Dies wird nur einmal pro Sitzung ausgeführt, so dass der zweite Aufruf es nicht trifft - nichts mit Serveroutput zu tun. Und dieser Block führt eine Auswahl durch. Fügen Sie diesen Codeabschnitt zur Frage hinzu. –

+1

Nebenbei, warum verwenden Sie hier dynamisches SQL, wenn statisches SQL mehr als ausreichend wäre? –

Antwort

3

Der Fehler kommt aus dem package instantiation:

Wenn eine Sitzung ein Paket Artikel verweist, instanziiert Oracle Database das Paket für diese Sitzung. Jede Sitzung, die auf ein Paket verweist, hat eine eigene Instanz dieses Pakets.

Wenn die Oracle-Datenbank ein Paket instanziiert, wird es initialisiert. Die Initialisierung beinhaltet je nachdem, welche der folgenden Optionen gelten: ...

  • Ausführen der Initialisierung Teil des Gehäusekörpers

dass nur instatiation geschieht einmal pro Sitzung. Ihr erster Aufruf der Prozedur führt den Initialisierungsabschnitt aus. Der zweite Anruf nicht. Die set serveroutput on hat keine Wirkung, es ist nur, dass es der zweite Aufruf ist, der funktioniert, und das ist, weil diese Initialisierung nicht das zweite Mal aufgerufen wird.

So kommt der Fehler von der Initialisierung Teil des Gehäuses der Packung, die am Ende ist - nach allen Verfahren und Funktionen usw. Sie haben eine begin vor der endgültigen end des Pakets. Etwas wie:

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; 
/

Der Code in diesem Block gehört Linie 1743, und das wird ein select ... into sein, die mehr als eine Zeile findet. Sie haben diesen Code nicht angezeigt, aber Sie müssen ihn untersuchen.

+0

In der Tat gab es am Ende des Pakets eine Auswahl, die mehr als eine Zeile zurückgab. Danke vielmals. –

Verwandte Themen