この章は次の項で構成されています。
アプリケーションをOracle Databaseに移行する前に、『Oracle Database概要』に記載されたいくつかの重要な点に注意する必要があります。
データベース中心のエンタープライズの移行について話し合う場合、データベースのスキーマとデータの実際の移行は、プロセスの一環にすぎないことを念頭に置いておくと役立ちます。コア・ビジネス・ソリューションの移行には多くの場合、組織の収益をもたらす製品やサービスを提供するために連携している複数のデータベースやアプリケーションが関係します。移行計画の準備の詳細は、『Oracle SQL Developerユーザーズ・ガイド』を参照してください。
Oracle Database 12cリリース1で導入された次の機能はすべて、Oracle以外のデータベース・アプリケーションのOracle Databaseへの移行プロセスを向上させるものです。
Oracle以外のデータベースからOracle Databaseへの移行の中心としては、Oracle以外のSQL文をOracle Databaseで使用可能なSQL文に変更することなどがあります。アプリケーションのOracle以外のSQL文の変換は、手動で単調なプロセスです。労力を最小限にしたり、文を変換する必要がなくなるように、Oracle Databaseリリース12cにSQL翻訳フレームワークと呼ばれる新機能が導入されました。これを使用すると、クライアント・アプリケーションからSQL文が受け入れられ、実行時に翻訳されてから実行されます。
Oracle以外のクライアント・アプリケーション用の翻訳を処理するために、データベース内でSQL文はSQLトランスレータによって翻訳され、SQL翻訳プロファイルに登録されます。SQL文の実行時にエラーが発生すると、SQLトランスレータは、Oracleエラー・コードおよびANSI SQLSTATEを、アプリケーションで想定されているベンダー固有の値に翻訳することも行います。翻訳された文はSQL翻訳プロファイルに保存され、必要に応じて確認したり、編集できます。
SQL翻訳フレームワークの利点は次のとおりです。
SQL文、Oracleエラー・コードおよびANSI SQLSTATEの翻訳は自動です。
翻訳は一元化され、検証可能です。
後で翻訳を抽出したり、アプリケーションに挿入したりできます。
MySQL用Oracle Databaseドライバにより、MySQLデータベースと連携するために当初開発されたアプリケーションの移行が容易になります。この機能には、主に次の2つの利点があります。
エンタープライズは、同じアプリケーションを再利用して、MySQLデータベースとOracle Databaseの両方に格納されるデータを使用できます。
MySQLアプリケーションをOracle Databaseに移行する場合のコストと複雑さを軽減します。
Oracle Databaseではクライアント・インタフェース内のすべてのMySQL関数が同じセマンティックでサポートされます。SQL文は翻訳されますが、次の制限があります。
次のSQLコンストラクトは無視されます。
表に対するENGINE指定。Oracleが唯一のストレージ・エンジンであるためです。
ENUMおよびSET型はVARCHAR2として使用されます。したがって、これらの値が数値コンテキストで取得される場合は索引値に変換されません。
次のSQLコンストラクトはエラーになるため、アプリケーションをコーディングしなおす必要があります。
GEOMETRY、POINT、LINESTRING、POLYGON、GEOMETRYCOLLECTION、MULTILINESTRING、MULTIPOINT、MULTIPOLYGONなどの空間データ型を含む表の作成
MySQL固有のNLSコマンド
次のSQLコマンドでは、Oracle固有の出力またはOracle固有の効果が得られます。
SHOW DATABASESは1つのデータベース(つまりoracle)のみ表示します
SHOW ENGINESはOracleエンジンのみ表示します
CREATE PROCEDUREはOracle Database 12cリリース1のOracle PL/SQL仕様に従う必要があります。
次のデータ型では動作が異なります。
ENUMデータ型の列はVARCHAR2(4000)として作成されます。挿入に対して検証は実行されません。
SETデータ型の列はVARCHAR2(64)として作成されます。挿入に対して検証は実行されません。
詳細は、第6章『Oracle用MySQLクライアント・ライブラリ・ドライバ』および第7章「Oracle MySQLクライアント・ライブラリ・ドライバのAPIリファレンス」を参照してください。
Oracle Database 12cリリース1は、ANSI準拠のIDENTITY列を実装しています。アイデンティティ列を使用するデータベース・システムからの移行は簡略化され、この新しい機能を活用できます。
この機能は、SEQUENCE.NEXTVALおよびSYS_GUIDで使用するDEFAULTまたはDEFAULT ON NULLセマンティックを強化することで自動増分を実装し、組込み関数やデフォルト値の暗黙的な戻りをサポートします。
例1-1では、デフォルトで生成される、アイデンティティ列を含む表を作成します。明示的なnullがアイデンティティ列に挿入されるときのデフォルトの動作は順序ジェネレータを使用することです。詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
Oracle Database 12cリリース1以降、Oracleでは、ストアド・プロシージャで実行されたSQL文の結果がサポートされます。明示的にREF CURSORを使用する必要がなく、結果は暗黙的にクライアント・アプリケーションに戻されます。この機能によって、クライアント側のコードを記述しなおすオーバーヘッドがなくなります。
暗黙的な文の結果を使用すると、対象の各問合せ(FORキーワードの後の文)がOPENカーソル変数の一部であるストアド・プロシージャを作成できます。他のベンダー環境からOracle Databaseにコードが移行された場合、PL/SQL層によって同等の機能が追加され、SELECT文でクライアントに結果を渡すことが可能になります。ストアド・プロシージャはDBMS_SQL.RETURN_RESULTプロシージャを使用して結果をクライアントに直接返すことができます。SQL*PlusのFORMATコマンドとそのバリエーションを呼び出すと、出力をカスタマイズできます。
DBMS_SQLパッケージの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。フォーマット出力の使用方法の詳細は、『SQL*Plusユーザーズ・ガイドおよびリファレンス』を参照してください。
Oracle Database 12cリリース1より、JDBCアプリケーションで次の新しい関数を使用した暗黙的結果のサポートが提供されます。
getMoreResults
getMoreResults(int)
getResultSet
例1-2に示すように、これらのメソッドを使用して、PL/SQLプロシージャまたはブロックによって返された暗黙的結果を取得したり、処理できます。
例1-2 PL/SQLブロックからの暗黙的結果の取得および処理
プロシージャでfooをコールするとします。
create procedure foo as c1 sys_refcursor; c2 sys_refcursor; begin open c1 for select * from hr.employees; dbms_sql.return_result(c1); --return to client -- open 1 more cursor open c2 for select * from hr.departments; dbms_sql.return_result (c2); --return to client end;
次のコードに、JDBC getMoreResultsメソッドを使用して、PL/SQLプロシージャによって返された暗黙的結果を取得する方法を示します。
String sql = "begin foo; end;";
...
Connection conn = DriverManager.getConnection(jdbcURL, user, password);
try {
Statement stmt = conn.createStatement ();
stmt.executeQuery (sql);
while (stmt.getMoreResults())
{
ResultSet rs = stmt.getResultSet();
System.out.println("ResultSet");
while (rs.next())
{
/* get results */
}
}
}
詳細は、『Oracle Database JDBC開発者ガイド』を参照してください
Oracle Database 12cリリース1より、Oracle Call Interface (OCI)で新しい関数OCIStmtGetNextResult()を使用した暗黙的結果のサポートが提供されます。これは、Cアプリケーションによって繰り返し呼び出され、ストアド・プロシージャや匿名ブロックの各暗黙的結果を取得します。暗黙的結果は、RefCursorを経由せずにストアド・プロシージャの行を直接使用します。
例1-3に、OCIStmtGetNextResult()関数を使用して、PL/SQLプロシージャまたは無名ブロックによって返された暗黙的結果を取得したり、処理する方法を示します。
例1-3 暗黙的結果の処理のためのOCIStmtGetNextResult()の使用
OCIStmt *stmthp;
ub4 rsetcnt;
void *result;
ub4 rtype;
char *sql = "begin foo; end;";
OCIHandleAlloc((void *)envhp, (void **)&stmthp,
OCI_HTYPE_STMT, 0, (void **)0);
/* Prepare and execute the PL/SQL procedure. */
OCIStmtPrepare(stmthp, errhp, (oratext *)sql, strlen(sql),
OCI_NTV_SYNTAX, OCI_DEFAULT);
OCIStmtExecute(svchp, stmthp, errhp, 1, 0,
(const OCISnapshot *)0,
(OCISnapshot *)0, OCI_DEFAULT);
/* Now check if any implicit results are available. */
OCIAttrGet((void *)stmthp, OCI_HTYPE_STMT, &rsetcnt, 0,
OCI_ATTR_IMPLICIT_RESULT_COUNT, errhp);
/* Loop and retrieve the implicit result-sets.
* ResultSets are returned in the same order as in the PL/SQL
* procedure/block.
*/
while (OCIStmtGetNextResult(stmthp, errhp, &result, &rtype,
OCI_DEFAULT) == OCI_SUCCESS)
{ /* Check the type of implicit ResultSet, currently
* only supported type is OCI_RESULT_TYPE_SELECT
*/ if (rtype == OCI_RESULT_TYPE_SELECT)
{ OCIStmt *rsethp = (OCIStmt *)result;
/* Perform normal OCI actions to define and fetch rows. */
} else
printf("unknown result type %d\n", rtype);
/* The result set handle should not be freed by the user. */
} OCIHandleFree(stmthp, OCI_HTYPE_STMT); /* All implicit result-sets are also freed. */
|
関連項目: 『Oracle Call Interfaceプログラマーズ・ガイド』 |
Oracle Database 12cリリース1より、ODBCアプリケーションで新しい関数SQLMoreResults()を使用した暗黙的結果のサポートが提供されます。ODBCドライバは、移行プロセスを向上させる次の新しいOCI APIを使用できるよう機能拡張されています。
OCIStmtGetNextResult()関数
OCI_ATTR_IMPLICIT_RESULT_COUNT属性
OCI_RESULT_TYPE_SELECT属性
暗黙的結果のODBCサポートにより、ストアド・プロシージャにバンドルされた複数の結果セットを使用するSybaseおよびSQL Serverアプリケーションの移行が可能になります。Oracleでは、文またはプロシージャをサーバーに送信し、サーバーでOracle以外のSQLをOracle構文に変換することでこれを実現します。例1-4および例1-5に、ODBCの暗黙的結果の取得方法を示します。このトピックの詳細は、『Oracle Call Interfaceプログラマーズ・ガイド』を参照してください。
例1-4 DBMS_SQL.RETURN_RESULTによる暗黙的結果を返すためのODBCの使用
create or replace procedure foo is c1 sys_refcursor; c2 sys_refcursor; begin open c1 for select employee_id, first_name from employees where employee_id=7369; dbms_sql.return_result(c1); open c2 for select department_id, department_name from departments where rownum <=2; dbms_sql.return_result(c2); end; /
例1-5 SQLMoreResultsによる暗黙的結果を返すためのODBCの使用
SQLLEN enind,jind;
SQLUINTEGER eno = 0;
SQLCHAR empname[STR_LEN] = "";
//Allocate HENV, HDBC, HSTMT handles
rc = SQLPrepare(hstmt, "begin foo(); end;", SQL_NTS);
rc = SQLExecute(hstmt);
//Bind columns for the first SELECT query in the procedure foo( )
rc = SQLBindCol (hstmt, 1, SQL_C_ULONG, &eno, 0, &jind);
rc = SQLBindCol (hstmt, 2, SQL_C_CHAR, empname, sizeof (empname),
&enind);
…
//so on for all the columns that needs to be fetched as per the SELECT
//query in the procedure.
//Fetch all results for first SELECT query
while ((rc = SQLFetch (hstmt)) != SQL_NO_DATA)
{
//do something
}
//Again check if there are any results available by calling
//SQLMoreResults. SQLMoreResults will return SQL_SUCCESS if any
//results are available else returns errors appropriately as explained
//in MSDN ODBC spec.
rc = SQLMoreResults ( hstmt );
if( rc == SQL_SUCCESS)
{
//If the columns for the second SELECT query are different the rebind
//the columns for the second SELECT SQL statement.
rc = SQLBindCol (hstmt, 1,…);
rc = SQLBindCol (hstmt, 2,…);
…
//Fetch the second result set
while ((rc = SQLFetch (hstmt)) != SQL_NO_DATA)
//do something
}
SQLFreeStmt(hstmt,SQL_DROP);
SQLDisconnect (hdbc);
SQLFreeConnect (hdbc);
SQLFreeEnv (henv);
以前のリリースのOracle Databaseでは、SQL式で、SQLデータ型でない仮引数または戻り型を使用したPL/SQL関数を起動できませんでした。
Oracle Databaseリリース12cより、PL/SQL無名ブロック、SQL CALL文またはSQL問合せにより、次の型のパラメータを持つPL/SQL関数を起動できます。
Boolean
パッケージ仕様部で宣言されたレコード
パッケージ仕様部で宣言されたコレクション
また、SQL TABLE演算子の機能が強化され、TABLE演算子の引数としてローカル・スコープ型のPL/SQLコレクションに問い合せることもできます。ここで、コレクションは、ネストした表、VARRAYまたはPLS_INTEGERで索引付けされたPL/SQL索引表です。
この機能(特に、TABLE演算子の柔軟性の拡張)によって、Oracle以外のストアド・プロシージャ・コードのPL/SQLへの移行が容易になります。
例1-6に、ネストした表仮パラメータを持つサブプログラムの動的起動方法を示します。このトピックの詳細は、 『Oracle Database PL/SQL言語リファレンス』を参照してください。
例1-6 ネストした表仮パラメータを持つサブプログラムの起動
CREATE OR REPLACE PACKAGE pkg AUTHID CURRENT_USER AS
TYPE names IS TABLE OF VARCHAR2(10);
PROCEDURE print_names (x names);
END pkg;
/
CREATE OR REPLACE PACKAGE BODY pkg AS
PROCEDURE print_names (x names) IS
BEGIN
FOR i IN x.FIRST .. x.LAST LOOP
DBMS_OUTPUT.PUT_LINE(x(i));
END LOOP;
END;
END pkg;
/
DECLARE
fruits pkg.names;
dyn_stmt VARCHAR2(3000);
BEGIN
fruits := pkg.names('apple', 'banana', 'cherry');
dyn_stmt := 'BEGIN print_names(:x); END;';
EXECUTE IMMEDIATE dyn_stmt USING fruits;
END;
このリリースより、Oracle Databaseに問合せの行制限と行のオフセットのネイティブSQLでのサポートを可能にする行制限句が用意されています。アプリケーションに、返される行数の制限または結果の開始行のオフセットを行う問合せがある場合、この機能によってそのような問合せのSQLの複雑性が大幅に軽減されます。
例1-7に、FETCH FIRST句を使用したバルク選択を制限する方法を示します。このトピックの詳細は、 『Oracle Database PL/SQL言語リファレンス』を参照してください。
例1-7 バルク選択の制限方法
DECLARE
TYPE SalList IS TABLE OF employees.salary%TYPE;
sals SalList;
BEGIN
SELECT salary BULK COLLECT INTO sals FROM employees
WHERE ROWNUM <= 50;
SELECT salary BULK COLLECT INTO sals FROM employees
SAMPLE (10);
SELECT salary BULK COLLECT INTO sals FROM employees
FETCH FIRST 50 ROWS ONLY;
END;
/
他のデータベースからOracle Databaseに移行するアプリケーションの多くは、JDBCを使用してデータベースに接続するJavaアプリケーションを所有しています。SQL翻訳を円滑に行うために、Oracle Database 12cリリース1に、SQL翻訳に特化した新しいJDBC APIのセットが導入されました。
ODBCドライバは、SQL翻訳フレームワークを使用したOracle Databasesへのサード・パーティ・アプリケーションの移行をサポートします。これによって、Oracle以外のデータベースのSQL文をOracle Databaseに対して実行できます。サード・パーティODBCアプリケーションをOracle Databaseに移行する前に「SQL翻訳フレームワークの使用方法」を参照してください。
この機能をODBCアプリケーションに対して使用するには、SQL翻訳フレームワーク設定の一環で作成されたサービス名をServerName=エントリとして.odbc.iniファイルに指定する必要があります。
アプリケーションがOracle Databaseに対する実行を開始した後、Oracleエラー(ORAエラー)のネイティブ・データベースへの翻訳に対するサポートが必要な場合、.odbc.iniファイルでSQLTranslateErrors=Tエントリを有効にする必要があります。このトピックの詳細は、「ODBCアプリケーションのSQL翻訳」を参照してください。
移行戦略全体の一環として、次の製品の使用をお薦めします。
どのタイプの移行でも、アプリケーションで使用されるSQL文の一部を変更し、一部の索引を再構築する必要があります。Oracle SQL TuningおよびPerformance Packsでは、アプリケーション移行の最適化手順のガイダンスが提供されます。
Oracle GoldenGateは、異種データ環境でのデータのレプリケーションを可能にする包括的なソフトウェア・パッケージです。製品セットにより、運用および分析用エンタープライズ・システム間での高可用性ソリューション、リアルタイム・データ統合、トランザクション変更データの取得、データ・レプリケーション、変換および検証が可能になります。
Oracle GoldenGateは、エンタープライズ全体で複数の異種プラットフォーム間でのトランザクション・レベルのデータの交換および操作を可能にします。そのモジュール方式のアーキテクチャによって、様々なトポロジ間で選択したデータ・レコード、トランザクション変更およびDDL(データ定義言語)の変更を抽出したり、レプリケートする柔軟性が提供されます。
非常に大規模なデータベースを移行する場合、あるデータベースから別のデータベースへデータをコピーする実際のプロセスはかなり時間がかかります。この間、エンタープライズは、古いソリューションを使用してサービスの配信を続ける必要がありますが、この場合、データの一部が変更されます。このような実行時の変更は、取得されてOracle Databaseに伝播される必要があります。Oracle GoldenGateで、このような変更を取得し、比較テストによって新しいソリューションが計画どおり機能することを確認できます。
Oracle Database Gatewayは、異種データ・アクセスのニーズに対応します。異種分散環境で、GatewayはOracleアプリケーションからの多数のOracle以外のシステムとの統合を可能にします。IBM DB2、Microsoft SQL Server、Excelなどのデータ・ストア、IBM CICSなどのトランザクション・マネージャおよびIBM WebSphere MQなどのメッセージ・キューイング・システムの統合が可能になります。
Oracle Database Gatewaysの詳細は、http://www.oracle.com/technetwork/database/gateways/index.htmlを参照してください
Oracleでは、各種データベースで実行するアプリケーションの移行サポートを用意しています。表1-1に、Oracle SQL Developerを使用した移行がサポートされるデータベース・バージョンをリストします。これは包括的なリストです。SQL翻訳は、すべてのデータベースに対して適切に機能するわけではありません。
表1-1 Oracle SQL Developerを使用した移行がサポートされるデータベース・バージョン
| RDBMS | サポート対象のバージョン |
|---|---|
|
SQL Server |
7.0, 2000, 2005,2008 |
|
Sybase Adaptive Server(ASE) |
12, 15 |
|
Access |
97、2000、2002および2003 |
|
MySQL |
3,4,5 |
|
DB2 |
AS400 V4R3、V4R5 |
|
DB2 LUW |
8, 9 |
|
Teradata |
12 |
|
Informix |
7.3, 9.1, 9.2, 9.3, 9.4 |
表1-2に、一部のサードパーティ・データベースでサポートされるアプリケーションの情報を示します。翻訳フレームワークは、DB2 LUWの場合に利用できますが、DB2のトランスレータは使用できません。