2013-07-11 99 views
5

Viene visualizzato un errore in una stored procedure Oracle 11g. L'errore è ...Buffer stringa di caratteri troppo piccolo errore in Oracle Stored Procedure

ORA-06502: PL/SQL: numeric or value error: character string buffer too small

sta accadendo alla riga 31, la riga che contiene out_cnt_tot := 0; io non sono davvero sicuro perché ci sia qualcosa di sbagliato in quella linea. Un altro programmatore ha creato questa procedura e non ho molta familiarità con le procedure SQL. Qualcuno può aiutarmi a capirlo?

create or replace 
PROCEDURE     "FIP_BANKREC_PREP" 
        (
    in_file_date in varchar2, 
    in_bank_code in varchar2, 
    out_cnt_apx_miss_no out integer, 
    out_cnt_prx_miss_no out integer, 
    out_cnt_apx_no_mtch out integer, 
    out_cnt_prx_no_mtch out integer, 
    out_cnt_ap_dup out integer, 
    out_cnt_pr_dup out integer, 
    out_cnt_bad out integer, 
    out_cnt_ap_load out integer, 
    out_cnt_pr_load out integer, 
    out_cnt_ap_not_load out integer, 
    out_cnt_pr_not_load out integer, 
    out_cnt_tot out integer, 
    out_message out varchar2 
    ) as 

file_date date; 
ap_acct_no varchar2(16); 
pr_acct_no varchar2(16); 

-- ------------------------------------------------------ 
-- begin logic 
-- ------------------------------------------------------ 
begin 

    file_date := to_date(in_file_date,'yyyymmdd'); 
    out_cnt_tot := 0; --- THE ERROR IS ON THIS LINE --- 
    out_message := 'Test Message'; 

    select brec_acct_code into ap_acct_no 
    from MSSU.zwkfi_bankrec_accts 
    where brec_acct_bank = in_bank_code 
     and brec_acct_type = 'AP'; 

    select brec_acct_code into pr_acct_no 
    from MSSU.zwkfi_bankrec_accts 
    where brec_acct_bank = in_bank_code 
     and brec_acct_type = 'PR';  

// The rest of the procedure... 
+0

Come fai a sapere che è la linea 31? Sei sicuro? Hai provato a guardare il file con l'editor esadecimale? Forse puoi individuare qualche carattere UTF-8 che è invisibile nel tuo editor ma causa problemi. –

+2

Sembra più probabile che sia la linea dopo quella; i numeri di riga in questi messaggi a volte non sono esattamente come ti aspetteresti. Il che significa che probabilmente è la dimensione della variabile che stai passando alla procedura come 'out_message' che è troppo piccola, piuttosto che un errore nella procedura stessa. Puoi mostrare come stai chiamando questo e come vengono dichiarate le variabili per quella chiamata? –

+0

L'unica cosa passata a out_message è quella "Test Message" letterale. Inseriremo presto dei messaggi, ma non ci siamo ancora riusciti, quindi inseriamo semplicemente un testo segnaposto. È possibile che la stringa "Test Message" sia troppo breve per quella variabile?Non ne ho mai sentito parlare prima. – grantmcconnaughey

risposta

9

semplice demo dello scenario menzionato nei commenti:

create or replace procedure p42(out_message out varchar2) as 
begin 
    out_message := 'Test message'; 
end p42; 
/

Se chiamo che con una variabile che viene dichiarata abbastanza grande, va bene. Ho una variabile di 12-char, in modo da assegnare un valore di 12 char non è un problema:

declare 
    msg varchar2(12); 
begin 
    p42(msg); 
end; 
/

anonymous block completed 

Ma se faccio un errore e fare variabile del chiamante troppo piccolo ottengo l'errore che state vedendo:

declare 
    msg varchar2(10); 
begin 
    p42(msg); 
end; 
/

Error report: 
ORA-06502: PL/SQL: numeric or value error: character string buffer too small 
ORA-06512: at "STACKOVERFLOW.P42", line 3 
ORA-06512: at line 4 
06502. 00000 - "PL/SQL: numeric or value error%s" 
*Cause:  
*Action: 

Lo stack di errori mostra sia la linea nella procedura che ha generato un errore (riga 3), sia la linea nel chiamante che l'ha attivata (riga 4). A seconda di dove lo stai chiamando, potresti non avere l'intero stack, ovviamente.

Hai detto che ci sarebbero stati vari messaggi di errore in futuro. È necessario assicurarsi che tutto ciò che viene chiamato in questo modo definisca le variabili come sufficienti per far fronte a qualsiasi messaggio. Se fossero stati archiviati in una tabella, si potrebbe eseguire la semi-automazione, altrimenti si tratterà di un controllo manuale della revisione del codice.


OK, visto il tuo C# commento dopo aver postato questo. Sembra che tu stia chiamando this constructor; che non dice che cosa dimensione di default si arriva, ma non irragionevole pensare che potrebbe essere 1. Quindi è necessario chiamare this constructor invece per specificare le dimensioni in modo esplicito:

OracleParameter (String, OracleType, Int32)
Inizializza una nuova istanza della classe OracleParameter che utilizza il nome del parametro, il tipo di dati e la lunghezza.

... qualcosa di simile:

OracleParameter prm15 = new OracleParameter("out_str_message", 
    OracleDbType.Varchar2, 80); 

A meno che non ci sia un modo per ripristinare la dimensione dopo la creazione, che non riesco a vedere. (Non qualcosa che abbia mai usato!).

+0

Si guarda come aggiungere una lunghezza di 12 al mio costruttore OracleParameter() risolve questo problema. Grazie mille per il tuo aiuto. – grantmcconnaughey

+0

Definitivamente. Grazie ancora. – grantmcconnaughey

Problemi correlati