Условная компиляция PL/SQL позволяет избирательно компилировать участки исходного кода в зависимости от условия, как правило связанного со значением пакетной константы. Часто это используется для обеспечения совместимости приложений с разными версиями СУБД.
В декабре 2017 года такая возможность появилась и в Tibero, что позволило обеспечить ещё большую совместимость приложений между Tibero и Oracle.
В качестве примера, возьмем пакет для объявления и связывания исключений с кодами системных ошибок. В Tibero коды системных ошибок отличаются от Oracle.
В первую очередь, надо использовать стандартные исключения из пакета SYS.STANDARD, как например NO_DATA_FOUND. С ними проблем совместимости не возникнет. Для остальных, используемых в вашем приложении исключений рекомендуется создать отдельный пакет.
В этом пакете у пользовательских исключений с кодами ошибок от -20999 до -20000 тоже все в порядке — как в Tibero, так и в Oracle. В остальных случаях, если планируется использовать это приложение для работы как с Oracle, так и с Tibero, можно воспользоваться условной компиляцией.
Для начала, нам понадобится пакет с константой для определения с какой СУБД мы работаем:
create or replace package tmax_ConstPkg is
c_isTibero constant boolean := false;
end tmax_ConstPkg;
Теперь можно писать связывание исключений в зависимости от СУБД:
create or replace package tmax_ErrPkg is
e_object_not_exists exception;
pragma exception_init(e_object_not_exists,
$if tmax_Constpkg.c_isTibero $THEN
-7071
$ELSE
-4043
$END
);
--
e_compilation_error exception;
pragma exception_init(e_compilation_error,
$IF tmax_Constpkg.c_isTibero $THEN
-15163
$ELSE
-06550
$END
);
end tmax_ErrPkg;
Если пакет для объявления и связывания исключений в вашем приложении для Oracle уже используется, то вам остается получить (опытным путем) соответствующий код ошибки в Tibero и добавить его с помощью условной компиляции.
В случае, если объявление и связывание исключений рассыпано бисером по всему коду вашего приложения, то это не повод для паники.
Мы решили воспользоваться замечательной возможностью для анализа PL/SQL кода с помощью PL/Scope. Приводить весь код утилиты здесь нецелесообразно, он доступен на Oracle2Tibero_Tools. Утилита представляет собой несколько PL/SQL пакетов, два из которых уже были рассмотрены выше. Проще всего будет ими пользоваться, если вы установите эти пакеты в схему вашего приложения вместе с анализируемыми PL/SQL объектами.
Т.к. для анализа кода используется PL/Scope, то необходимо скомпилировать ваши PL/SQL объекты в режиме поиска идентификаторов, например:
SQL> ALTER SESSION SET plscope_settings='IDENTIFIERS:ALL';
SQL> alter procedure p1 compile;
Для перекомиляции всех PL/SQL объектов в режиме поиска идентификаторов, достаточно выполнить:
SQL> exec tmax_check4migrate.recompile4plscope
Теперь можно запустить утилиту следующим образом:
SQL> set serveroutput on
SQL> exec tmax_check4migrate.run
Будут выведены сообщения о всех проблемных исключениях с предложениями использования либо стандартных исключений, либо заготовок объявления и связывания исключений с кодами ошибок в Oracle для пакета Tmax_ErrPkg:
1. Exception LONG_TEXT(PACKAGE BODY HR.TEST line 2528) init with error code -6502(line 2529)
...replace it to VALUE_ERROR Reference list
1) PACKAGE BODY HR.TEST line(s) 2570,2615
3. Exception E_MONTH_ERR(PACKAGE BODY HR.TEST line 6128) init with error code -1843(line 6129) Reference list
1) PACKAGE BODY HR.TEST line(s) 6198
...
...You need to use conditional compilation to define different system error codes for Tibero and Oracle Following error codes did not find in Tmax_ErrPkg package, need to add:
/* ORA-01843: not a valid month */
------------------------------
e_not_a_valid_month exception;
pragma exception_init(e_not_a_valid_month,
$if tmax_Constpkg.c_isTibero $THEN
-?????
$ELSE
-1843
$END
);
Кстати это будет полезно хотя бы для консолидации всех исключений в один пакет. Сразу предупрежу, что кроме проверки исключений, утилита решает ряд других вопросов совместимости, о которых мы поговорим в следующих частях. Поэтому на этом этапе, в основной процедуре Run, вы можете закомментировать вызовы других проверок — процедур с префиксом Chk_ .
После того, как вы добавите все заготовки исключений в пакет Tmax_ErrPkg, можно запустить утилиту в режиме исправлений:
SQL> set serveroutput on
SQL> exec tmax_check4migrate.run(p_modify => true)
Старые объявления и связывания будут закомментированы и вместо них в коде будут использоваться либо стандартные исключения, либо исключения из пакета Tmax_ErrPkg.
Теперь, что касается Tibero. На момент написания статьи условная компиляция еще не вошла в стандартную сборку, доступную на сайте technet.tmaxsoft.com. Проверить поддержку условной компиляции на вашем экземпляре Tibero можно либо попробовав установить требуемые параметры инициализации:
_PSM_PREPROCESS=Y
_PSM_PREPROCESS_SELECTION=Y
Либо можно проверить SQL запросом, что такие скрытые параметры есть:
SQL> select NAME,VALUE from sys._vt_parameter where name like '_PSM_PREPROCESS%';
Версию Tibero, поддерживающую условную компиляцию вы можете запросить в российском представительстве компании TmaxSoft.
В следующих публикациях мы рассмотрим некоторые отличия синтаксиса Tibero и Oracle, с которыми вы можете встретиться, а также как избежать связанных с этим исправлений вручную.