Тестирование обработки исключений в Oracle 11g - PullRequest
0 голосов
/ 03 февраля 2011

У меня есть этот код оракула

 FUNCTION get_enc_val(p_in                          IN VARCHAR2,
                        p_key                         IN VARCHAR2
                       )
   RETURN raw
   IS
      p_title_procedure_name        VARCHAR2(100) := 'get_enc_val';
      l_enc_val                     RAW(2000);
      l_mod                         PLS_INTEGER := DBMS_CRYPTO.ENCRYPT_AES128 + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_PKCS5;
      v_key                         VARCHAR2(16);

      encryption_ex Exception;
   BEGIN



      v_key                 := RPAD(SUBSTR(TRIM(p_key), 1, 16), 16, '0');
      l_enc_val             := DBMS_CRYPTO.encrypt(UTL_RAW.cast_to_raw(p_in), l_mod, UTL_RAW.cast_to_raw(v_key));


      RAISE encryption_ex;

      RETURN l_enc_val;

   EXCEPTION
      WHEN OTHERS THEN
         service_func.log_error(p_title_package_name || '.' || p_title_procedure_name, 'Proc', NULL, SYSDATE, SQLERRM, p_in || '~' || p_key);
         RETURN 'Encryption_ERROR';
   END;

Когда я запускаю это, я получаю ORA-06510 Необработанное пользовательское исключение, в то время как оно действительно должно вернуть строку 'Encryption_ERROR'. Что дает?Это идет в блок Exception, потому что я вижу результат функции log_error.Вопрос в том, не должен ли блок Exception обрабатывать ЛЮБОЕ исключение?

Я немного растерялся.

Ответы [ 2 ]

4 голосов
/ 03 февраля 2011

Проблема в том, что ваш второй оператор RETURN возвращает VARCHAR2, а ваша функция объявлена ​​для возврата RAW. Это можно исправить, вызвав UTL_RAW.CAST_TO_RAW, т.е.

   EXCEPTION
      WHEN OTHERS THEN
         service_func.log_error(p_title_package_name || '.' || 
                                   p_title_procedure_name, 
                                'Proc', 
                                NULL, 
                                SYSDATE, 
                                SQLERRM, 
                                p_in || '~' || p_key);
         RETURN utl_raw.cast_to_raw( 'Encryption_ERROR' );
   END;

Если я объявлю две функции, одну из которых возвращает жестко запрограммированную строку, а другую - RAW, вы увидите разницу (я удаляю вызовы DBMS_CRYPTO и вызов LOG_ERROR). Если я объявлю функцию, которая возвращает RAW, вы получите результат обратно (хотя человеку придется преобразовать необработанный текст обратно в строку, чтобы иметь смысл результата)

SQL> ed
Wrote file afiedt.buf

  1  create or replace function throw_exception
  2    return raw
  3  is
  4    my_exception exception;
  5  begin
  6    raise my_exception;
  7  exception
  8    when others then
  9      return utl_raw.cast_to_raw( 'Foo' );
 10* end;
SQL> /

Function created.

SQL> select throw_exception
  2    from dual;

THROW_EXCEPTION
-----------------------------------------------------------------------------

466F6F

Если я просто верну строку, я получу то же исключение, что и вы

SQL> ed
Wrote file afiedt.buf

  1  create or replace function throw_exception2
  2    return raw
  3  is
  4    my_exception exception;
  5  begin
  6    raise my_exception;
  7  exception
  8    when others then
  9      return 'Foo';
 10* end;
SQL> /

Function created.

SQL> select throw_exception2
  2    from dual;
select throw_exception2
       *
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: hex to raw conversion error
ORA-06512: at "SCOTT.THROW_EXCEPTION2", line 9
ORA-06510: PL/SQL: unhandled user-defined exception

Конечно, другой вариант - объявить, что функция возвращает VARCHAR2. Но я бы предпочел иметь хэши и зашифрованные данные в формате RAW, а не в VARCHAR2, чтобы вам никогда не приходилось беспокоиться о таких вещах, как проблемы преобразования набора символов при манипулировании данными.

0 голосов
/ 03 февраля 2011

Поскольку вы уверены, что service_func.log_error(...); не вызывает ошибку, она должна быть вызвана вызывающей процедурой / функцией.

И вот что вызывает ту же ошибку.

create or replace function abc return raw is
begin
    return 'Encryption_ERROR';
end;
/

declare
     r raw(50);
begin
     r := abc;
end;
/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...