Блокът за изключение в pl/sql „Функция“ не улавя условие за грешка

Имам следната функция, която извиквам от друга процедура в рамките на същия pl/sql пакет.

Function lf_get_query(p_table in varchar2) return varchar2
Is
    v_where_clause  varchar2(500);
Begin
    Case upper(p_table)
        When 'TABLEA'   then                    
            v_where_clause := ' Where trunc(x.purchase_dtm) < ' || '''' || trunc(v_check_Date) || ''''; 
        When 'TABLEB'   then                    
            v_where_clause := ' Where trunc(x.purchase_dtm) < ' || '''' || trunc(v_check_Date) || ''''
                                || ' And product_type='ABC'
                                || ' And customer_type='XXX'
                                || ' And contract_type='YYY';   
        Else
            raise ex_unknown_table_type;                    
    End case;           
    return v_where_clause;
Exception
    When ex_unknown_table_type then
        [[Log to file that table is urecognised. ]]
        raise;
    When others then
        [[Log to file that table is urecognised and include sqlerrm ]]
        raise;
End;

Когато извикам функцията, тя генерира следната грешка:

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

Грешката се генерира, защото променливата v_where_clause не е достатъчно голяма за някои от низовете, които се опитвам да съхраня в променливата. Това, което не разбирам, е, че когато възникне грешката, тя не се улавя от нито една от двете клаузи за изключение, показани по-горе. Вместо това грешката се улавя в блока за изключения за процедурата, която извиква тази функция.

Причината, поради която знам, че не се улавя от клаузите за изключение във функцията, е, че и двете клаузи за изключение трябва да регистрират условието за грешка във файл, но не са.

Има ли причина за това? Не трябва ли изключението да бъде уловено от блока за изключения „WHEN OTHERS“?

Също така, има ли някакъв начин да декларирам променливата v_where_clause, без да посочвам размер?

Благодаря


person ziggy    schedule 08.11.2011    source източник
comment
Задайте вашата променлива VARCHAR2 на много голям размер, т.е. 32767 и Oracle автоматично ще й даде достатъчно място за съхранение, за да покрие това, което поставяте в нея. няма да задели произволно 32767 байта.   -  person Ollie    schedule 08.11.2011


Отговори (1)


Блокът за изключение на извикващата процедура издава ли връщане назад? Ако е така, това ще върне вашето регистриране заедно с всичко останало. Начинът, по който можете да заобиколите това, е да използвате процедура, която е дефинирана с PRAGMA AUTONOMOUS_TRANSACTION, което ще позволи вашето регистриране да се извършва извън текущата транзакция.

person Allan    schedule 08.11.2011
comment
О, толкова съм глупав. Записите в регистрационния файл, които бяха регистрирани в таблицата, се връщаха назад. Благодаря!!!!!!!! - person ziggy; 08.11.2011
comment
На всички ни се случва поне веднъж ;-) - person DCookie; 08.11.2011
comment
+1 Писането на регистрационни записи е единствената валидна употреба за АВТОНОМНА ТРАНЗАКЦИЯ. - person APC; 09.11.2011