28 сент. 2014 г.

The same code for Oracle 11g and 12c

В настоящий момент некоторые компании-разработчики объявили о поддержке Oracle Database 12c в своих приложениях.
Мне довелось принять участие в конференции, посвященной этой грядущей поддержке в решениях компании ЦФТ: Миграция банковских комплексов ЦФТ на СУБД Oracle 12с.

В ходе последующего общения с разработчиками ЦФТ возник вопрос о сложности сопровождения кода в промежуточный период: когда будет необходимо поддерживать одновременно и Oracle 11g и Oracle 12c.

В решении этой задачи, на мой взгляд, может помочь условная компиляция PL/SQL. C помощью определенных в стандартном встроенном PL/SQL-пакете DBMS_DB_VERSION символов условной компиляции (логических констант), мы можем указывать части кода которые будут работоспособны только в Oracle 12c.
В этом пакете есть логическая константа VER_LE_11_2, истинное значение которой указывает на то, что компиляция кода производится в версии не более чем Oracle 11g Release 2.

Рассмотрим в качестве примера одну из новых технологий Oracle 12c - возможность определять UDF-функции, и тем самым значительно снижать затраты на переключение контекста в SQL-запросах.
Идея очень проста: директиву компиляции UDF мы обрамляем в символ условной компиляции.
CREATE OR REPLACE FUNCTION inc_amount(v_pValue in number) RETURN number is
  $if not dbms_db_version.ver_le_11_2 $then
PRAGMA UDF;
  $end
  v_xValue number(9);
BEGIN
  v_xValue := v_pValue;
  
  return v_xValue+10;
END;
Далее, в момент компиляции этого кода, исходный текст будет препроцессирован. Если текущая версия БД - Oracle 12c, в код, который в итоге будет скомпилирован, попадет UDF-прагма PL/SQL-компилятора. Если БД имеет версии ниже, чем Oracle 12c - перед компиляцией, из исходного текста будет удалена строка с определением прагмы.

Важно отметить, что нам не нужно обрабатывать версию СУБД на уровне патчера нашего приложения и проводить собственный препроцессинг: компиляция этого кода на обеих версиях БД проходит без ошибок.
Компилируем код в Oracle 11.2:
-bash-4.1$ sqlplus scott/tiger

SQL*Plus: Release 11.2.0.4.0 Production on Sun Sep 28 20:06:36 2014

Copyright (c) 1982, 2013, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning and Real Application Testing options

SQL> CREATE OR REPLACE FUNCTION inc_amount(v_pValue in number) RETURN number is
  $if not dbms_db_version.ver_le_11_2 $then
    PRAGMA UDF;
  $end
  v_xValue number(9);
BEGIN
  v_xValue := v_pValue;
  
  return v_xValue+10;
END;
/

Function created.

SQL> 
Теперь тот же самый код компилируем в Oracle 12c R1:
[oracle@localhost Desktop]$ sqlplus scott/tiger

SQL*Plus: Release 12.1.0.2.0 Production on Sun Sep 28 20:10:13 2014

Copyright (c) 1982, 2014, Oracle.  All rights reserved.

Last Successful login time: Sun Sep 28 2014 19:35:23 +04:00

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options

SQL> CREATE OR REPLACE FUNCTION inc_amount(v_pValue in number) RETURN number is
  $if not dbms_db_version.ver_le_11_2 $then
    PRAGMA UDF;
  $end
  v_xValue number(9);
BEGIN
  v_xValue := v_pValue;
  
  return v_xValue+10;
END;
/

Function created.

SQL> 
Таким образом, мы имеем единую версию исходных текстов нашего приложения, который работоспособен сразу в нескольких версиях СУБД, получая преимущества от использования новых версий!

Комментариев нет:

Отправить комментарий