2013-07-11 16 views
5

Otrzymuję błąd w procedurze składowanej Oracle 11g. Błąd znajduje się ...Bufor znaków za mały błąd w procedurze przechowywanej Oracle

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

To się dzieje na linii 31, wiersz, który zawiera out_cnt_tot := 0; ja naprawdę nie wiem, dlaczego nie ma nic złego w tym wierszu. Inny programista stworzył tę procedurę i naprawdę nie jestem zaznajomiony z procedurami SQL. Czy ktoś może mi pomóc to rozgryźć?

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

Skąd wiesz, że to linia 31? Jesteś pewny? Czy próbowałeś spojrzeć na plik za pomocą edytora szesnastkowego? Być może zauważysz pewną postać UTF-8, która jest niewidoczna w twoim edytorze, ale powoduje problemy. –

+2

Wygląda raczej na to, że linia będzie później; numery linii w tych wiadomościach czasami nie są takie, jakich byś oczekiwał. Co oznacza, że ​​prawdopodobnie jest to wielkość zmiennej, którą przekazujesz do procedury jako "out_message", która jest zbyt mała, a nie błąd w samej procedurze. Czy możesz pokazać, jak to nazywasz i jak deklarowane są zmienne dla tego połączenia? –

+0

Jedyną rzeczą przekazaną do out_message jest to, że "Test Message" jest dosłowny. Wkrótce dodamy wiadomości, ale jeszcze się do tego nie dostaliśmy, dlatego właśnie wstawiliśmy tam tekst zastępczy. Czy jest możliwe, że ciąg "Test Message" jest zbyt krótki dla tej zmiennej?Nigdy wcześniej nie słyszałem o tym. – grantmcconnaughey

Odpowiedz

9

Proste demo scenariusza wymienionego w komentarzach:

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

jeśli zadzwonię, że przy zmiennej, która jest zadeklarowana wystarczająco duży, to w porządku. Mam zmiennej 12-char, więc przypisanie wartości 12-char nie jest problemem:

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

anonymous block completed 

Ale jeśli się pomylę i uczynić zmienna rozmówcy zbyt mała pojawia się błąd jesteś zobaczyć:

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: 

Stos błędów pokazuje zarówno linię w procedurze, która została skasowana (linia 3), jak i linię wywołującego, która ją wywołała (linia 4). W zależności od tego, gdzie dzwonisz, możesz oczywiście nie mieć całego stosu.

Wspomniał Pan, że w przyszłości pojawią się różne komunikaty o błędach. Musisz się upewnić, że wszystko, co kiedykolwiek wywołasz, określa zmienne, które są wystarczająco duże, aby poradzić sobie z każdą wiadomością. Jeśli były przechowywane w tabeli, można je zautomatyzować, w przeciwnym razie będzie to ręczna kontrola weryfikacji kodu.


OK, zobaczyłem twój komentarz C# po opublikowaniu tego. Wygląda na to, że dzwonisz pod numer this constructor; że nie mówi, co robi domyślny rozmiar, ale nie nierozsądne, że może to być 1. Więc trzeba zadzwonić this constructor zamiast określić rozmiar extenso:

OracleParameter (String, OracleType, Int32)
Inicjuje nowe wystąpienie klasy OracleParameter, która używa nazwy parametru, typ danych i długość.

... coś jak:

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

Chyba że istnieje sposób, aby zresetować rozmiary po stworzeniu, którego nie widzę. (Nie coś, z czego kiedykolwiek korzystałem!).

+0

to wygląda jak dodanie długości 12 do mojego konstruktora OracleParameter() rozwiązuje ten problem. Dzięki za twoją pomoc milion. – grantmcconnaughey

+0

Zdecydowanie. Dzięki jeszcze raz. – grantmcconnaughey

Powiązane problemy