2013-10-15 22 views
11

Sto usando oracle 10g e rospo 11.5. Sto cercando di chiamare una API da un blocco anonimo.ORA-06508: PL/SQL: impossibile trovare l'unità di programma che si chiama

Se i ricompilare l'api dopo l'aggiunta di dbms_output.put_line e quindi provare a eseguire il blocco anonimo, mostra errore

"ORA-06508: PL/SQL: could not find program unit being called". 

Tuttavia se finisco sessione corrente e aprire una nuova sessione, poi il blocco anonimo verrà eseguito senza l'errore.

A causa di questo problema, mi viene fatto di riconnettere la sessione ogni volta che apporto una modifica all'API. Qualcuno può aiutare se questo problema può essere risolto facendo qualsiasi configurazione in rospo o livello di database.

+2

Sei anche ottenere qualcosa come 'stato del pacchetto esistente era stato scartato '? Se è così, eseguirlo una seconda volta nella stessa sessione dovrebbe funzionare. Ma ciò suggerirebbe che il tuo pacchetto avesse qualche stato, cioè una variabile dichiarata nel pacchetto piuttosto che in una procedura (e niente a che fare con 'dbms_output'). –

risposta

21

Ho il sospetto che stai riportando solo l'ultimo errore in una pila come questo:

ORA-04068: existing state of packages has been discarded 
ORA-04061: existing state of package body "schema.package" has been invalidated 
ORA-04065: not executed, altered or dropped package body "schema.package" 
ORA-06508: PL/SQL: could not find program unit being called: "schema.package" 

Se è così, è perché your package is stateful:

I valori delle variabili, costanti, e cursori che un pacchetto dichiara (nella sua specifica o nel corpo) comprende il suo pacchetto stato. Se un pacchetto PL/SQL dichiara almeno una variabile, costante, o cursore, il pacchetto è stateful; altrimenti, è senza stato.

quando si ricompila lo stato è perduto:

Se il corpo di un pacchetto stateful istanziato viene ricompilato (sia esplicitamente, con il "ALTER istruzione package", o implicitamente), il la successiva chiamata di un sottoprogramma nel pacchetto causa Oracle Database per ignorare lo stato del pacchetto esistente e sollevare l'eccezione ORA-04068.

Dopo PL/SQL solleva l'eccezione, un riferimento al pacchetto provoca Oracle Database di ri-creare un'istanza del pacchetto, che ri-inizializza esso ...

non si può evitare questo se il tuo pacchetto ha stato. Penso che sia abbastanza raro avere davvero bisogno di un pacchetto per essere stateful, quindi dovresti rivedere tutto ciò che hai dichiarato nel pacchetto, ma al di fuori di una funzione o procedura, per vedere se è veramente necessario a quel livello. Dato che sei su 10g, ciò include costanti, non solo variabili e cursori.

Tuttavia, l'ultimo paragrafo della documentazione citata indica che la prossima volta che si fa riferimento al pacchetto nella stessa sessione, non si otterrà l'errore e funzionerà normalmente (finché non si ricompila nuovamente).

+0

Totalmente d'accordo con te. Potrei preoccuparmi dei numeri immaginari a riguardo. Gestisci il dannato proc. Ho provato ad escluderlo da un blocco anon chiamando e assolutamente deve essere eseguito fino al completamento prima che la bandiera magica si cancellerà. Irritante! –

3

Sulla base delle risposte precedenti.Ho risolto il mio problema rimuovendo la variabile globale a livello di pacchetto alla procedura, poiché non c'era alcun impatto nel mio caso.

sceneggiatura originale era

create or replace PACKAGE BODY APPLICATION_VALIDATION AS 

V_ERROR_NAME varchar2(200) := ''; 

PROCEDURE APP_ERROR_X47_VALIDATION ( PROCESS_ID IN VARCHAR2) AS BEGIN 
    ------ rules for validation... END APP_ERROR_X47_VALIDATION ; 

/* Some more code 
*/ 

END APPLICATION_VALIDATION;/

riscritto la stessa senza variabile globale V_ERROR_NAME e si trasferì a procedura sotto il livello del pacchetto come

Codice Modificato

create or replace PACKAGE BODY APPLICATION_VALIDATION AS 

PROCEDURE APP_ERROR_X47_VALIDATION ( PROCESS_ID IN VARCHAR2) AS 

**V_ERROR_NAME varchar2(200) := '';** 

BEGIN 
    ------ rules for validation... END APP_ERROR_X47_VALIDATION ; 

/* Some more code 
*/ 

END APPLICATION_VALIDATION;/