4 Oracle Database Provider for DRDAのSQL翻訳および例
SQL翻訳は、Oracle Database 12cリリース2 (12.2)の新機能です。以前のリリースのOracle Databaseでは、SQL翻訳なしでOracle Provider for DRDAを使用できます。
SQL翻訳の詳細は、Oracle® Database移行ガイドを参照してください
ノート:
SQL翻訳はオプションの機能であり、アプリケーション内で使用されるSQLがDB2中心の構文である場合にお薦めします。4.1 SQL翻訳プロセスの概要
SQL翻訳の概念は、Oracle Databaseリリース12cで導入されました。この機能により、DB2などの外部のSQL文を、Oracle Databaseが正しく使用できるSQL構文に翻訳できるようになります。SQL翻訳自体は、主にサードパーティから翻訳用に提供されるSQLトランスレータにより実装されます。SQLトランスレータは、入力SQLを検査し、場合によってはOracle SQLの構文に準拠するように入力SQLを変更します。SQL翻訳プロファイルは、SQL Translator Interface Packageで指定されます。このプロファイルにより、使用するSQLトランスレータが指定されます。
SQL翻訳プロファイルは、SQL TRANSLATION PROFILE
型のスキーマ・レベルのオブジェクトです。ATTR_TRANSLATOR
属性を介してPL/SQLパッケージを参照します。このパッケージはSQL Translator Interface Packageと呼ばれます。このパッケージは、SQL翻訳プロファイルがアクティブなときにSQL翻訳を実行するサードパーティのSQLトランスレータを指定します。一度に1つのSQL翻訳プロファイルだけを有効にできます。
SQL翻訳プロファイルは、ユーザー間で共有できます。一般には、すべてのユーザーが1つのSQL翻訳プロファイルを一連のパッケージで共有しますが、これは必須ではありません。
各DB2パッケージは、そのパッケージで保持されている属性によってSQL翻訳プロファイルに関連付けられます。DB2パッケージに対して指定されたSQL翻訳プロファイルに関連付けられているSQLトランスレータは、そのDB2パッケージ内のSQL文を準備する際に使用されます。
4.1.2 SQL翻訳の要件
SQL翻訳は、次の状況に該当する場合にのみ正常に完了します。
-
次のコマンドを使用してSQL翻訳プロファイルがセッションに対して有効になっている必要があります。
ALTER SESSION SET SQL_TRANSLATION_PROFILE
-
受信するSQL文が外部の構文またはOracle以外のSQL言語で記述されていることを、プロセスが指定している必要があります。この項で説明するすべてのケースでは、SQL言語はDB2 SQLのバリエーションです。
Oracle Database Provider for DRDA製品の場合、前述の2つの条件が結合されます。つまり、DB2パッケージにSQL翻訳プロファイルが関連付けられている場合、SQL文は外部構文で記述されていると想定されます。また、そのパッケージでSQLを翻訳するときにはSQL翻訳プロファイルに関連付けられているSQLトランスレータがコールされます。
4.2 DB2固有のSQL構文の翻訳に関する詳細
クライアント・アプリケーションがOracle Database Provider for DRDAに送信するSQLコンストラクトのほとんどは直接実行されますが、一部のDB2 SQLコンストラクトはOracleによって認識されません。Oracle Databaseインスタンスを使用するように再構成されたアプリケーションによって発行されたDB2 SQL文を翻訳する際に発生する既知の問題について検討してください。
SQL翻訳プロファイルが存在する場合、そのプロファイルに関連付けられているSQLトランスレータは、これらのSQL文を変更するように設計されています。これにより、アプリケーションが同等または類似の操作をOracle SQLで実行し、予期されている結果を戻すことができます。
4.2.1 DB2の特殊レジスタ
Oracle Databaseでは、現在の時刻を取得するCURRENT TIME
特殊レジスタ・コンストラクトはサポートされていません。次の例に示すように、このコンストラクトを呼び出すとORA-00936
エラーが発生します。
SELECT CURRENT TIME FROM SYSIBM.SYSDUMMY1
4.2.2 DB2 SQLファンクションおよびプロシージャ
Oracleでは、DB2で定義されているファンクションの一部がサポートされていません。たとえば、CEILING
ファンクションはOracleには存在しませんが、Oracle SQL構文にはこのファンクションと互換性のあるCEIL
ファンクションがあります。
4.2.3 DB2名前付きデータ型
Oracleでは、BIGINT
などのいくつかの基本的なSQLデータ型が定義されていません。アプリケーションがOracleに対して実行される場合、列値または定数をBIGINT
としてキャストすると、エラーが発生します。次の例では、BIGINT
が有効なOracleデータ型として認識されていないためため、ORA-00902
エラーが発生します。
SELECT CAST(12345678912 AS BIGINT) from SYSIBM.SYSDUMMY1
4.3 SQL Translator Interface Package
SQL翻訳プロファイルは、DBMS_SQL_TRANSLATOR.CREATE_PROFILE()
プロシージャを使用して作成されたSQL TRANSLATION PROFILE
型のスキーマ・レベルのオブジェクトです。SQL Translator Interface Packageは、特定の形式のPL/SQLパッケージであり、サードパーティ提供のトランスレータ・オブジェクトを参照する一方で、それ自身がSQL翻訳プロファイルから参照されます。SQL Translator Interface Packageは、SQL翻訳プロファイルおよびサードパーティ提供のSQLトランスレータ・オブジェクトに接続します。
4.3.1 SQL Translator Interface Packageについて
SQL翻訳プロファイルは、固定形式のPL/SQLラッパー・パッケージであるSQL Translator Interface Packageを参照します。セッションでSQL TRANSLATION PROFILE
が設定されると、すべてのSQLがSQL Translator Interface Packageに関連付けられているサードパーティのSQLトランスレータによって翻訳されることが指定されます。SQL Translator Interface Packageのプロシージャtranslate_sql()
により翻訳が実行されます。
OracleからはSQLトランスレータは提供されないことに注意してください。かわりに、サードパーティ・ベンダーからSQLトランスレータを取得するか、または内部で開発する必要があります。Oracleでは、SQL翻訳プロファイルを作成および管理するための様々な管理スクリプトが用意されています。
4.3.2 SQL Translator Interface Packageの作成
例4-1に、SQL翻訳プロファイルとともに使用される単純なSQL Translation Interface Packageを示します。言語と名前の指定は、サードパーティのSQLトランスレータの言語タイプおよびコール可能な名前に関連しています。SYSDBA
権限でOracle Databaseにログインした後に、次のパッケージ宣言を行う必要があります。パッケージ名は、SQL翻訳プロファイルのTRANSLATOR_ATTR
属性の値です。
例4-1 SQL Translator Interface Packageの作成
create or replace package SYSIBM.DBTooSQLTranslator as procedure translate_sql( sql_text in CLOB, translated_text out CLOB); procedure translate_error( error_code in BINARY_INTEGER, translated_code out BINARY_INTEGER, translated_sqlstate out VARCHAR2); end; / create or replace package body SYSIBM.DBTooSQLTranslator as procedure translate_sql( sql_text in CLOB, translated_text out CLOB ) as language JAVA name /* actually the "signature" of the third-party callable */ /* procedure associated with translate_sql */ 'DBTooSQLApiInterface.translateSQL(oracle.sql.CLOB, oracle.sql.CLOB[])'; procedure translate_error(error_code in BINARY_INTEGER, translated_code out BINARY_INTEGER, translated_sqlstate out VARCHAR2) as language JAVA name /* actually the "signature" of the third-party callable */ /* procedure associated with translate_error */ 'DBTooSQLApiInterface.translateError(oracle.sql.CLOB, oracle.sql.CLOB[])'; end; /
4.3.3 SQL Translator Interface PackageへのEXECUTE権限の付与
SQL Translator Interface Packageは実行時にコールされるため、EXECUTE
権限が有効になっている必要があります。例4-2に、このアクセス権限を付与する方法を示します。
例4-2 SQL Translator Interface PackageへのEXECUTE権限の付与
GRANT EXECUTE ON SYSIBM.DBTooSQLTranslator TO DRDAAS_USER_ROLE
4.3.4 SQL翻訳プロファイルの作成
SQL翻訳プロファイルは、CREATE SQL TRANSLATION PROFILE
権限およびTRANSLATE ANY SQL
権限を持つユーザーが作成および管理できます。「DRDAAS_TRANS_ADMIN
ロールを持つユーザーへの必要な権限の付与」の項に、これら2つの権限をDRDAAS_TRANS_ADMIN
に付与する方法を示しています。これらの権限は、既存のSYSDBA
権限を持つユーザーが付与できます。
ADMIN OPTION
句により、DRDAAS_TRANS_ADMIN
が他のOracleユーザーに対しTRANSLATE ANY SQL
権限をGRANT
(付与)できるようになります。このようにして、「DRDAAS_USER_ROLE
ロールを持つユーザーへの必要な権限の付与」に示すように、DRDAAS_TRANS_ADMIN
により、DRDAAS_USER_ROLE
を持つ複数のユーザーが翻訳機能を使用できるようになります。
実際のSQL翻訳プロファイルは、「SQL翻訳プロファイルの作成および管理」に示すスクリプトを使用して管理できます。管理IDには、CREATE SQL TRANSLATION PROFILE
を実行するために必要な権限がすでに付与されている必要があることに注意してください。
4.3.4.1 管理者ロールを使用した翻訳権限の付与
例4-3 DRDAAS_TRANS_ADMINロールを持つユーザーへの必要な権限の付与
GRANT CREATE SQL TRANSLATION PROFILE TO DRDAAS_TRANS_ADMIN; GRANT TRANSLATE ANY SQL TO DRDAAS_TRANS_ADMIN WITH ADMIN OPTION;
4.3.4.2 ユーザー・ロールを使用した翻訳権限の付与
例4-4 DRDAAS_USER_ROLEを持つユーザーへの翻訳権限の付与
GRANT TRANSLATE ANY SQL TO DRDAAS_USER_ROLE;
4.3.4.3 SQL翻訳プロファイルの作成および管理
例4-5 SQL翻訳プロファイルの作成および管理
declare PROFILE_DOES_NOT_EXIST exception; pragma EXCEPTION_INIT(PROFILE_DOES_NOT_EXIST, -24252); /* profile_name is the nsme of the SQL Translation Profile */ /* created here. */ profile_name VARCHAR2(32) := 'DRDAAS_TRANS_ADMIN.MY_PROFILE'; /* SYSIBM is the schema in which the SQL Translator Interface */ /* package (viz., SYSIBM.DBTooSQLTranslator) is found. */ sql_trnsltr_intfc_schema VARCHAR2(32) := 'SYSIBM'; /* DBTooTranslator is the unqualified package name of the SQL */ /* Translator Interface Package */ sql_trnsltr_intfc_pkgnm VARCHAR2(32) := 'DBTooSQLTranslator'; sql_trnsltr_intfc_pkg VARCHAR2(128); grant_cmd VARCHAR2(256); cursor_id NUMBER; begin sql_trnsltr_intfc_pkg := sql_trnsltr_intfc_schema || '.' || sql_trnsltr_intfc_pkgnm; begin DBMS_SQL_TRANSLATOR.DROP_PROFILE(profile_name); exception WHEN PROFILE_DOES_NOT_EXIST THEN NULL; /* ignore if non-existant */ end; /* Create SQL Translation Profile */ DBMS_SQL_TRANSLATOR.CREATE_PROFILE(profile_name); /* Associate the SQL Translator Interface Package denoted by */ /* sql_trnsltr_intfc_pkg with this profile */ DBMS_SQL_TRANSLATOR.SET_ATTRIBUTE(profile_name, DBMS_SQL_TRANSLATOR.ATTR_TRANSLATOR, sql_trnsltr_intfc_pkg); /* Mark this SQL Translation Profile as "registered" */ DBMS_SQL_TRANSLATOR.SET_ATTRIBUTE(profile_name, DBMS_SQL_TRANSLATOR.ATTR_TRANSLATION_REGISTRATION, DBMS_SQL_TRANSLATOR.ATTR_VALUE_TRUE); /* The owner of the SQL Translator Interface Package must have */ /* full authority for the SQL TRANSLATION PROFILE */ grant_cmd := 'GRANT ALL ON SQL TRANSLATION PROFILE ' || profile_name || ' TO ' || sql_trnsltr_intfc_schema; cursor_id := DBMS_SQL.OPEN_CURSOR(); DBMS_SQL.PARSE(cursor_id, grant_cmd, DBMS_SQL.NATIVE); DBMS_SQL.CLOSE_CURSOR(cursor_id); /* Let all with DRDAAS_USER_ROLE have access to the SQL Translation profile. */ grant_cmd := 'GRANT USE ON SQL TRANSLATION PROFILE ' || profile_name || ' TO DRDAAS_USER_ROLE'; cursor_id := DBMS_SQL.OPEN_CURSOR(); DBMS_SQL.PARSE(cursor_id, grant_cmd, DBMS_SQL.NATIVE); DBMS_SQL.CLOSE_CURSOR(cursor_id); end; /
4.4 サードパーティのSQLトランスレータの使用
サードパーティのトランスレータを使用しするには、トランスレータのファイルとオブジェクトがディレクトリ$ORACLE_HOME/rdbms/drdaas/jlib
にインストールされている必要があります。
問題が発生した場合は、DBMS_JAVA.SET_OUTPUT()
プロシージャを使用して、サーバー側のエラー・メッセージをDBMS_OUTPUT
にリダイレクトします。
4.4.1 単一オブジェクトとしてロードされたサードパーティSQLトランスレータの使用
サードパーティのSQLトランスレータがJavaで作成されている場合、例4-6はSYSDBA
ユーザーによってSQL*Plus環境で実行されます。例4-6では、DBMS_JAVA.LOADJAVA()
プロシージャを使用してSYSIBM
スキーマにオブジェクトをロードしています。この例では1つのサードパーティ・オブジェクトDBTooSQLAPI.jar
がロードされます。
例4-6 サードパーティのSQLトランスレータのロード(単一オブジェクト)
begin DBMS_JAVA.LOADJAVA('-definer -genmissing -schema SYSIBM ' || ' ' rdbms/drdaas/jlib/DBTooSQLAPI.jar', '((* SYSIBM)(* PUBLIC)(* -))'); end; /
4.4.2 複数オブジェクトとしてロードされたサードパーティSQLトランスレータの使用
サードパーティのトランスレータが複数オブジェクトで構成されている場合、各コンポーネントをLOADJAVA
コールに指定する必要があります。例4-7では、2つのトランスレータ・オブジェクト、DBTooSQLAPI.jar
およびDBTooMainClass.class
が指定されています。
例4-7 サードパーティのSQLトランスレータのロード(複数オブジェクト)
begin DBMS_JAVA.LOADJAVA('-definer -genmissing -schema SYSIBM ' || ' rdbms/drdaas/jlib/DBTooMainClass.class' || ' rdbms/drdaas/jlib/DBTooSQLAPI.jar', '((* SYSIBM)(* PUBLIC)(* -))'); end; /
4.5 トランスレータ管理スクリプトの使用
Oracle Databaseには、翻訳プロファイルを管理するdrdasqtt_translator_setup.sql
スクリプトが付属しています。このスクリプトは、SYSDBA
権限を持つユーザーがSQL*Plusで起動する必要があります。次の情報の入力が求められます。
4.6 SQLトランスレータ・プロファイルの検証
次のステップでは、SQL翻訳プロファイルが正しくインストールされ、適切に有効化されていることを確認します。
SQLトランスレータ・プロファイルの構成を検証するには、次のようにします。
4.7 SQL翻訳プロファイルの変更
場合によっては、SQL翻訳プロファイルを変更して、DB2パッケージのSQL TRANSLATION PROFILE
属性が新しいSQL翻訳プロファイルを参照するようにする必要があります。
DB2パッケージは通常セットで提供され、DB2パッケージの名前はクライアントによって決定されます。ただし、クライアントがODBCを使用してOracle Database Provider for DRDAにアクセスする場合、パッケージ名はODBCドライバによって決定します。
パッケージ・セットのSQL翻訳プロファイル属性を設定するための2つのスクリプトがOracleから提供されています。
-
DataDirect ODBCドライバがOracle Database Provider for DRDAにアクセスする場合、
drdaas/admin
ディレクトリにあるdrdasqt_set_profile_dd.sql
スクリプトを使用します。 -
IBM ODBCドライバがOracle Database Provider for DRDAにアクセスする場合、
drdaas/admin
ディレクトリにあるdrdasqt_set_profile_ibm.sql
スクリプトを使用します。ネイティブ・クライアント・アプリケーションもこのスクリプトを使用することがありますが、この場合は拡張する必要があります。
これらのスクリプトをコピーし、他のDB2パッケージ・セットで使用できるように変更できます。
また、各スクリプトはDRDAAS_ADMIN_ROLE
権限を持つユーザーがSQL*Plusで実行する必要があります。スクリプトでは、様々なパッケージが参照するプロファイル(DRDAAS_TRANS_ADMIN.MY_PROFILE
など)の修飾名の入力が求められます。また、デフォルトのパッケージ・コレクション・スキーマ(通常はNULLID
)の入力が求められます。