AnalyticDB for PostgreSQLは、Oracle構文と互換性があります。 このトピックでは、OracleアプリケーションからAnalyticDB for PostgreSQLインスタンスにデータを移行する方法について説明します。
Ora2Pgを使用した構文変換
Ora2Pgはオープンソースツールです。 このツールを使用して、Oracleのテーブル、ビュー、およびパッケージのDDLステートメントを、PostgreSQL構文と互換性のあるステートメントに変換できます。 詳細については、Ora2Pgのドキュメントを参照してください。
スクリプト変換後のPostgreSQL構文バージョンはAnalyticDB for PostgreSQLインスタンスのマイナーエンジンバージョンよりも後であり、Ora2Pgがスクリプトを変換するルールが欠落しているか正しくない可能性があるため、変換されたSQLスクリプトを手動で修正する必要があります。
Oracleとの互換性
互换モードパラメータ
同じ関数の動作は異なり、データベースによって互換性がありません。 互換モードパラメーターを設定する必要があります。 PostgreSQL互換モードとOracle互換モードが利用可能です。
次の表に、互換モードを指定するためにAnalyticDB for PostgreSQLによって提供されるパラメーターを示します。
パラメーター | 説明 |
adb_compatibility_mode | 互換モード。 有効な値:
このパラメーターを設定する前に、 インスタンスレベルのパラメーターを変更する場合は、 チケットを起票して、サービスセンターにお問い合わせください。 |
文字列連結演算子の互換モード
文字列連結式 'abc' | | NULL
では、'abc'
とNULL
は定数、または実表や計算結果のデータです。
PostgreSQL互換モードでは、式の戻り値は
NULL
です。 PostgreSQLでは、NULL
を使用した文字列の連結によってNULL
が生成されます。Oracle互換モードでは、式の戻り値は
'abc'
です。 Oracleでは、NULL
は単一引用符 ('
) で囲まれた空の文字列と同じです。重要Oracle互換モードで文字列連結機能を使用する前に、
Laser. enable = off
を使用してレーザーエンジンを無効にする必要があります。
データ型のサポート
AnalyticDB for PostgreSQLは、互換性モードパラメーターを設定することなく、定数文字列のデータ型をサポートします。
CREATE TABLE as SELECT
などのステートメントを実行すると、定数文字列がUNKNOWN型ではなくTEXT型として自動的に認識されます。
Orafce拡張機能を使用する
AnalyticDB for PostgreSQLは、Orafce拡張機能を提供します。 この拡張機能は、Oracleと互換性のある機能をサポートします。 これらの関数は、AnalyticDB for PostgreSQLで変更または変換することなく使用できます。
Orafceを使用する前に、次のステートメントを実行してOrafceをインストールします。
CREATE EXTENSION orafce;
次の表に、Orafceが提供するOracle互換関数を示します。
表 1 Orafceが提供するOracle互換関数
関数 | 説明 | 例 |
|
説明 2つの引数のデータ型は同じでなければなりません。 |
|
| この関数は、最初の引数で指定された日付に、2番目の引数で指定された月数を追加して日付を返します。 |
次の情報が返されます。
|
| この関数は、指定された日付の月の最終日を返します。 戻り値は日付です。 |
次の情報が返されます。
|
|
この関数は、開始日から2週目の日を表す日付を返します。 例: 第2金曜日を表す日付。 |
次の情報が返されます。
|
|
この関数は、開始日より特定の日数後の日付を返します。 |
|
| この関数は、date1とdate2の間の月数を返します。
|
|
|
|
|
| この関数はタイムスタンプを切り捨てます。 指定されたタイムスタンプの時、分、秒の値はデフォルトで切り捨てられます。 |
次の情報が返されます。
|
| この関数は日付を切り捨てます。 |
次の情報が返されます。
|
| この関数は、週や日などの単位に基づいて最も近い値にタイムスタンプを丸めます。 |
次の情報が返されます。
|
| この関数は、単位日に基づいて最も近い値にタイムスタンプを丸めます。 |
次の情報が返されます。
|
| この関数は丸められた日付を返します。 |
|
| この関数は丸められた日付を返します。 |
次の情報が返されます。
|
| この関数は、文字列の部分文字列を検索します。 部分文字列が取得された場合、関数は部分文字列の位置を返します。 それ以外の場合、関数は0を返します。
|
|
| n番目の引数は指定されていません。 この関数は、部分文字列の最初の出現の位置を返します。 |
次の情報が返されます。
|
| start引数が指定されていません。 この関数は、文字列の先頭から部分文字列を検索します。 |
次の情報が返されます。
|
| この関数は、指定した文字列の文字の順序を逆にします。 str引数は文字列を指定し、start引数とend引数は順序を逆にする文字の開始位置と終了位置を指定します。 |
次の情報が返されます。
|
| この関数は、start引数で指定された文字から文字列の末尾まで文字の順序を逆にします。 |
次の情報が返されます。
|
| この関数は、文字列全体の順序を逆にします。 |
次の情報が返されます。
|
| この関数は2つの文字列を結合します。 |
次の情報が返されます。
|
| この関数は、同じまたは異なるデータ型のデータを結合します。 |
|
| 最初の引数がNUMERICデータ型の場合、この関数は最初の引数の値を返します。 それ以外の場合、この関数は2番目の引数の値を返します。 |
|
| この関数は、INTEGERデータ型の2つの2進数に対してAND演算を実行します。 1行のみが返されます。 |
|
| この関数は、テキストのクラスタ化文字列を返します。 |
次の情報が返されます。
|
| この関数は、テキストのクラスタ化文字列を返します。 2番目の引数の値が区切り文字として使用されます。 |
次の情報が返されます。
|
| 最初の引数の値がnullの場合、この関数は3番目の引数の値を返します。 それ以外の場合、この関数は2番目の引数の値を返します。 |
|
| 引数の値がnullまたはfalseの場合、この関数はtrueを返します。 引数の値がtrueの場合、この関数はfalseを返します。 |
|
| この関数は、データ型コード、バイト単位の長さ、および引数の内部表現を含むテキストを返します。 |
次の情報が返されます。
|
| 2番目の引数は、戻り値の形式を指定します。 形式は、10進数表記 (10で指定) または16進数表記 (16で指定) にすることができます。 |
|
| この関数は、特定の順序でデータをソートします。 | 次のステートメントを実行して、テーブルを作成し、データを挿入します。
|
| この関数は、最初の引数で指定された文字列から部分文字列を取得します。 2番目の引数は、部分文字列の開始位置を指定します。 |
|
| 3番目の引数は、部分文字列の終了位置を指定します。 この引数の値は、 |
次の情報が返されます。
|
| この関数は、VARCHAR2データ型の文字列から部分文字列を返します。 2番目の引数は部分文字列の開始位置を指定し、3番目の引数は部分文字列の終了位置を指定します。 |
次の情報が返されます。
|
| この関数は、VARCHAR2データ型の文字列から部分文字列を返します。 部分文字列は、2番目の引数で指定された文字から始まり、文字列の最後まで続きます。 |
次の情報が返されます。
|
| この関数は、VARCHAR2データ型の文字列のバイト数を返します。 nullを指定した場合、関数はnullを返します。 空の文字列が指定されている場合、関数は0を返します。 |
|
| この関数は、文字列のシーケンスで指定された長さに左側の文字列をパディングします。
説明 CHAR型の文字列の場合、PostgreSQLは末尾のスペースを削除しますが、Oracleは削除しません。 |
次の情報が返されます。
|
| この関数は、左側の文字列を指定した長さにスペースでパディングします。 |
次の情報が返されます。
|
| この関数は、開始位置からソース文字列でパターンが発生する回数を返します。 戻り値は整数でなければなりません。 パターンが見つからない場合、関数は0を返します。
|
|
| この関数は、文字列の開始位置からソース文字列内でパターンが発生する回数を返します。 戻り値は整数でなければなりません。 パターンが見つからない場合、関数は0を返します。 |
次の情報が返されます。
|
| この関数は、文字列の先頭からソース文字列でパターンが発生する回数を返します。 戻り値は整数でなければなりません。 パターンが見つからない場合、関数は0を返します。 |
次の情報が返されます。
|
| この関数は、ソース文字列内のパターンの開始位置または終了位置を返します。 戻り値は整数でなければなりません。
|
次の情報が返されます。
|
| この関数は、文字列の開始位置からソース文字列内のパターンの指定されたオカレンスの開始位置または終了位置を返します。 戻り値は整数でなければなりません。
|
次の情報が返されます。
|
| この関数は、文字列の開始位置からソース文字列内のパターンの指定されたオカレンスの開始位置または終了位置を返します。 戻り値は整数でなければなりません。 return_optは、ソース文字列内のパターンの開始位置または終了位置を指定します。 有効な値:
|
次の情報が返されます。
|
| この関数は、文字列の開始位置からソース文字列内のパターンの指定されたオカレンスの位置を返します。 戻り値は整数でなければなりません。 |
次の情報が返されます。
|
| この関数は、文字列の開始位置からソース文字列内のパターンの位置を返します。 戻り値は整数でなければなりません。 |
次の情報が返されます。
|
| この関数は、文字列の先頭からのソース文字列内のパターンの位置を返します。 戻り値は整数でなければなりません。 |
次の情報が返されます。
|
| ソース文字列の部分文字列がパターンと一致する場合、この関数はtrueを返します。 それ以外の場合、この関数はfalseを返します。
|
次の情報が返されます。
|
| ソース文字列の部分文字列がパターンと一致する場合、この関数はtrueを返します。 それ以外の場合、この関数はfalseを返します。 |
次の情報が返されます。
|
| この関数は、パターンに一致するソース文字列の部分文字列を返します。
|
次の情報が返されます。
|
| この関数は、文字列の開始位置から指定されたオカレンスのパターンと一致するソース文字列の部分文字列を返します。 |
次の情報が返されます。
|
| この関数は、文字列の開始位置からパターンに一致するソース文字列の部分文字列を返します。 |
次の情報が返されます。
|
| この関数は、文字列の先頭からのパターンと一致するソース文字列の部分文字列を返します。 |
次の情報が返されます。
|
上記の機能に加えて、OrafceはOracleのVARCHAR2データ型と互換性があります。
次の表に、OrafceをインストールせずにAnalyticDB for PostgreSQLでサポートできるOracle関数を示します。
関数 | 説明 | 例 |
| この関数は、双曲正弦値を返します。 |
次の情報が返されます。
|
| この関数は、双曲正接値を返します。 |
次の情報が返されます。
|
| この関数は、双曲線余弦値を返します。 |
次の情報が返されます。
|
| この関数は、式の値を検索します。 値が見つかった場合、関数は値を返します。 それ以外の場合、関数はデフォルト値を返します。 | 次のステートメントを実行して、テーブルを作成し、データを挿入します。
|
Oracleデータ型とAnalyticDB for PostgreSQLデータ型のマッピング
オラクル | AnalyticDB for PostgreSQL |
VARCHAR2 | varcharまたはテキスト |
日付 | timestamp |
LONG | text |
LONG RAW | bytea |
CLOB | text |
NCLOB | text |
BLOB | bytea |
RAW | bytea |
ROWID | oid |
FLOAT | ダブル精度 |
DEC | decimal |
DECIMAL | decimal |
DOUBLE PRECISION | ダブル精度 |
INT | int |
INTEGER | integer |
REAL | real |
SMALLINT | smallint |
NUMBER | numeric |
BINARY_FLOAT | ダブル精度 |
BINARY_DOUBLE | ダブル精度 |
TIMESTAMP | timestamp |
XMLTYPE | xml |
BINARY_INTEGER | integer |
PLS_INTEGER | integer |
TIMESTAMP WITH TIME ZONE | タイムゾーンのタイムスタンプ |
ローカルタイムゾーン付きタイムスタンプ | タイムゾーンのタイムスタンプ |
Oracle関数とAnalyticDB for PostgreSQL関数間のマッピング
オラクル | AnalyticDB for PostgreSQL |
sysdate | 現在のタイムスタンプ |
trunc | truncまたは日付trunc |
dbms_output.put_line | RAISEステートメント |
デコード | またはデコード |
NVL | 合体 |
PL/SQLでのデータの変換
手続き型言語 /SQL (PL/SQL) は、Oracleによって提供されるSQLの手続き型言語拡張です。 PL/SQLは、SQLの一般的なプログラミング言語の機能をサポートしており、複雑なビジネスロジックを実装するために使用できます。 PL/SQLは、AnalyticDB for PostgreSQLのPL/pgSQLをマップします。
パッケージ
PL/pgSQLはパッケージをサポートしていません。 パッケージをスキーマに変換する必要があります。 パッケージ内のすべてのプロシージャと関数は、AnalyticDB for PostgreSQLでサポートされている関数に変換する必要があります。
例:
CREATE OR REPLACE PACKAGE pkg IS
...
END;
変換結果:
CREATE SCHEMA pkg;
パッケージで定義されている変数
プロシージャと関数のローカル変数は変更されず、グローバル変数はAnalyticDB for PostgreSQLの一時テーブルに格納できます。
パッケージ初期化ブロック
パッケージ初期化ブロックを削除する必要があります。 ブロックを削除できない場合は、それらを関数にカプセル化し、必要に応じて関数を呼び出します。
パッケージで定義されているプロシージャと関数
パッケージで定義されているプロシージャと関数を、AnalyticDB for PostgreSQLでサポートされている関数に変換します。 各関数は、使用されているパッケージに対応するスキーマで定義する必要があります。
たとえば、pkgという名前のパッケージには次の関数が含まれます。
FUNCTION test_func (args int) RETURN int is var number := 10; BEGIN ... END;
上記の関数は、AnalyticDB for PostgreSQLでサポートされている次の関数に変換する必要があります。
CREATE OR REPLACE FUNCTION pkg. test_func(args int) RETURNS int AS $$ ... $$ LANGUAGE plpgsql;
プロシージャ /関数
Oracleのパッケージ固有およびグローバルプロシージャと関数を、AnalyticDB for PostgreSQLでサポートされている関数に変換します。
例:
CREATE OR REPLACE FUNCTION test_func (v_name varchar2, v_version varchar2)
RETURN varchar2 IS
ret varchar(32);
BEGIN
IF v_version IS NULL THEN
ret := v_name;
ELSE
ret := v_name || '/' || v_version;
END IF;
RETURN ret;
END;
変換結果:
CREATE OR REPLACE FUNCTION test_func (v_name varchar, v_version varchar)
RETURNS varchar AS
$$
DECLARE
ret varchar(32);
BEGIN
IF v_version IS NULL THEN
ret := v_name;
ELSE
ret := v_name || '/' || v_version;
END IF;
RETURN ret;
END;
$$
LANGUAGE plpgsql;
プロシージャまたは関数を変換する前に、次の情報に注意してください。
RETURNキーワードをRETURNSに変換します。
お使い&dollar ;\$... &dollar ;\$ 関数本体をカプセル化します。
関数言語の宣言に注意してください。
サブプロシージャをAnalyticDB for PostgreSQLでサポートされている関数に変換します。
PLステートメント
ステートメントのため
PL/SQLとPL/pgSQLでは、REVERSEを使用した整数FOR LOOPステートメントの動作が異なります。
PL/SQLは、2番目の数から1番目の数にカウントダウンします。
PL/pgSQLは、最初の数から2番目の数までカウントダウンします。
したがって、変換中にループ境界を交換する必要があります。 例:
逆のiのための
FOR i IN REVERSE 1..3 LOOP DBMS_OUTPUT.PUT_LINE (TO_CHAR(i)); END LOOP;
変換結果:
逆のiのための
FOR i IN REVERSE 3..1 LOOP RAISE '%' ,i; END LOOP;
PRAGMAステートメント
AnalyticDB for PostgreSQLはPRAGMAステートメントをサポートしていません。 PRAGMAステートメントを削除する必要があります。
トランザクション処理
AnalyticDB for PostgreSQLの関数は、BEGIN、COMMIT、ROLLBACKなどのトランザクション制御ステートメントをサポートしていません。
これらのステートメントは、次のルールに基づいて処理する必要があります。
関数本体のトランザクション制御ステートメントを削除し、関数本体の外部に含めます。
COMMITおよびROLLBACKステートメントに基づいて関数を分割します。
EXECUTE 文
AnalyticDB for PostgreSQLは、Oracleで提供されているものと同様の動的SQLステートメントをサポートします。 次の違いに注意してください。
AnalyticDB for PostgreSQLの動的SQL文は、USING構文をサポートしていません。 パラメーターをSQL文字列に結合する必要があります。
データベース識別子はquote_identを使用してパッケージ化され、数値はquote_literalを使用してパッケージ化されます。
例:
EXECUTE 'UPDATE employees_temp SET commission_pct = :x' USING a_null;
変換結果:
EXECUTE 'UPDATE employees_temp SET commission_pct = ' || quote_literal(a_null);
パイプROW関数
AnalyticDB for PostgreSQLのテーブル関数を使用して、PIPE ROW関数を置き換えます。
例:
TYPE pair IS RECORD(a int, b int); TYPE numset_t IS TABLE OF pair; FUNCTION f1(x int) RETURN numset_t PIPELINED IS DECLARE v_p pair; BEGIN FOR i IN 1..x LOOP v_p.a := i; v_p.b := i+10; PIPE ROW(v_p); END LOOP; RETURN; END; select * from f1(10);
変換結果:
CREATE TYPE pair AS (a int, b int); CREATE OR REPLACE FUNCTION f1(x int) RETURNS SETOF PAIR AS $$ DECLARE REC PAIR; BEGIN FOR i IN 1..x loop REC := row(i, i+10); RETURN NEXT REC; END LOOP; RETURN ; END $$ language 'plpgsql'; SELECT * FROM f1(10);
例外処理
RAISEステートメントを使用して、例外をスローします。
例外がキャッチされた後、対応するトランザクションはロールバックできません。 ロールバックは、ユーザー定義関数の外部でのみ許可されます。
AnalyticDB For PostgreSQLでサポートされているエラーコードの詳細については、PostgreSQL公式Webサイトをご覧ください。
return引数とout引数を含む関数
AnalyticDB for PostgreSQLでは、関数にreturn引数とout引数を同時に含めることはできません。 return引数をout引数に変換する必要があります。
例:
CREATE OR REPLACE FUNCTION test_func(id int, name varchar(10), out_id out int) returns varchar(10) AS $body$ BEGIN out_id := id + 1; return name; end $body$ LANGUAGE PLPGSQL;
変換結果:
CREATE OR REPLACE FUNCTION test_func(id int, name varchar(10), out_id out int, out_name out varchar(10)) AS $body$ BEGIN out_id := id + 1; out_name := name; end $body$ LANGUAGE PLPGSQL;
次に、
SELECT * FROM test_func(1,'1') INTO rec;
ステートメントを実行して、recから対応するフィールドの戻り値を取得します。文字列接続の変数に含まれる引用符 (')
次の例では、変数param2はSTRINGデータ型です。 たとえば、この変数の値は
adb-'pg
です。 AnalyticDB for PostgreSQLでsql_strを直接使用すると、ハイフン (-
) が演算子として識別され、エラーが発生します。 変数を変換するには、quote_literal関数を使用する必要があります。例:
sql_str := 'SELECT * FROM test1 WHERE col1 = ' || param1 || ' AND col2 = '''|| param2 || '''AND col3 = 3';
変換結果:
sql_str := 'SELECT * FROM test1 WHERE col1 = ' || param1 || ' AND col2 = '|| quote_literal(param2) || 'AND col3 = 3';
2つのタイムスタンプ間の日数を取得する
例:
SELECT to_date('2019-06-30 16:16:16') - to_date('2019-06-29 15:15:15') + 1 INTO v_days FROM dual;
変換結果:
SELECT extract('days' from '2019-06-30 16:16:16'::timestamp - '2019-06-29 15:15:15'::timestamp + '1 days'::interval)::int INTO v_days;
PLデータ型
レコード
AnalyticDB for PostgreSQLでRECORDデータ型を複合データ型に変換します。
例:
TYPE rec IS RECORD (a int, b int);
変換結果:
CREATE TYPE rec AS (a int, b int);
ネストテーブル
PLの変数として、NESTED TABLEデータ型はAnalyticDB for PostgreSQLのARRAYデータ型に変換できます。
例:
DECLARE TYPE Roster IS TABLE OF VARCHAR2(15); names Roster := Roster('D Caruso', 'J Hamil', 'D Piro', 'R Singh'); BEGIN FOR i IN names.FIRST .. names.LAST LOOP IF names(i) = 'J Hamil' THEN DBMS_OUTPUT.PUT_LINE(names(i)); END IF; END LOOP; END;
変換結果:
CREATE OR REPLACE FUNCTION f1() RETURNS VOID AS $$ DECLARE names varchar(15)[] := '{"D Caruso", "J Hamil", "D Piro", "R Singh"}'; len int := array_length(names, 1); BEGIN for i in 1..len loop if names[i] = 'J Hamil' then raise notice '%', names[i]; end if; end loop; return ; END $$ language 'plpgsql'; SELECT f();
ネストされたテーブルが関数の戻り値として使用されている場合、テーブル関数を使用してネストされたテーブルを置き換えることができます。
連想配列
このデータ型の置き換えはできません。
可変サイズ配列
VARIABLE-SIZE ARRAYデータ型は、NESTED TABLEデータ型と同様に、ARRAYデータ型に変換できます。
グローバル変数
AnalyticDB for PostgreSQLはグローバル変数をサポートしていません。 パッケージのすべてのグローバル変数を一時テーブルに格納し、グローバル変数の取得に使用する関数を定義できます。
例:
CREATE TEMPORARY TABLE global_variables ( id int, g_count int, g_set_id varchar(50), g_err_code varchar(100) ); INSERT INTO global_variables VALUES(0, 1, null, null); CREATE OR REPLACE FUNCTION get_variable() returns setof global_variables AS $$ DECLARE rec global_variables%rowtype; BEGIN execute 'select * from global_variables' into rec; return next rec; END; $$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION set_variable(in param varchar(50), in value anyelement) returns void AS $$ BEGIN execute 'update global_variables set ' || quote_ident(param) || ' = ' || quote_literal(value); END; $$ LANGUAGE plpgsql;
global_variables一时テーブルでは、IDフィールドはテーブルの配布キーです。 AnalyticDB for PostgreSQLでは、配布キーを変更することはできません。 テーブルに
tmp_rec record;
フィールドを追加する必要があります。グローバル変数を変更するには、
select * from set_variable('g_error_code ', 'error'::varchar) into tmp_rec;
ステートメントを実行します。グローバル変数を取得するには、
select * from get_variable() into tmp_rec; error_code := tmp_rec.g_error_code;
ステートメントを実行します。
SQL
CONNECT BY
CONNECT BY句は、Oracleの階層クエリに使用できます。 AnalyticDB for PostgreSQLのSQL文を同じ方法で使用してCONNECT BY句を置き換えることはできません。 階層による循環トラバーサルを使用して、CONNECT by句を変換できます。
例:
CREATE TABLE employee( emp_id numeric(18), lead_id numeric(18), emp_name varchar(200), salary numeric(10,2), dept_no varchar(8) ); INSERT INTO employee values('1',0,'king','1000000.00','001'); INSERT INTO employee values('2',1,'jack','50500.00','002'); INSERT INTO employee values('3',1,'arise','60000.00','003'); INSERT INTO employee values('4',2,'scott','30000.00','002'); INSERT INTO employee values('5',2,'tiger','25000.00','002'); INSERT INTO employee values('6',3,'wudde','23000.00','003'); INSERT INTO employee values('7',3,'joker','21000.00','003'); INSERT INTO employee values('3',7,'joker','21000.00','003');
SELECT emp_id,lead_id,emp_name,prior emp_name as lead_name,salary FROM employee START WITH lead_id=0 CONNECT BY prior emp_id = lead_id
変換結果:
CREATE OR REPLACE FUNCTION f1(tablename text, lead_id int, nocycle boolean) RETURNS setof employee AS $$ DECLARE idx int := 0; res_tbl varchar(265) := 'result_table'; prev_tbl varchar(265) := 'tmp_prev'; curr_tbl varchar(256) := 'tmp_curr'; current_result_sql varchar(4000); tbl_count int; rec record; BEGIN execute 'truncate ' || prev_tbl; execute 'truncate ' || curr_tbl; execute 'truncate ' || res_tbl; loop -- Query the current hierarchical result and insert the result into the tmp_curr table. current_result_sql := 'insert into ' || curr_tbl || ' select t1.* from ' || tablename || ' t1'; if idx > 0 then current_result_sql := current_result_sql || ', ' || prev_tbl || ' t2 where t1.lead_id = t2.emp_id'; else current_result_sql := current_result_sql || ' where t1.lead_id = ' || lead_id; end if; execute current_result_sql; -- If a loop exists, delete the data that is traversed. if nocycle is false then execute 'delete from ' || curr_tbl || ' where (lead_id, emp_id) in (select lead_id, emp_id from ' || res_tbl || ') '; end if; -- Exit if no data exists. execute 'select count(*) from ' || curr_tbl into tbl_count; exit when tbl_count = 0; -- Save data from the tmp_curr table to the result table. execute 'insert into ' || res_tbl || ' select * from ' || curr_tbl; execute 'truncate ' || prev_tbl; execute 'insert into ' || prev_tbl || ' select * from ' || curr_tbl; execute 'truncate ' || curr_tbl; idx := idx + 1; end loop; -- The following information is returned: current_result_sql := 'select * from ' || res_tbl; for rec in execute current_result_sql loop return next rec; end loop; return; END $$ language plpgsql;
ROWNUM
ROWNUMを使用して、結果セットのサイズを制限できます。 ROWNUMを置き換えるには、LIMIT句を使用できます。
例:
SELECT * FROM t WHERE rownum < 10;
変換結果:
SELECT * FROM t LIMIT 10;
row_number() over()
を使用してROWNUMを生成します。例:
SELECT rownum, * FROM t;
変換結果:
SELECT row_number() over() AS rownum, * FROM t;
DUALテーブル
DUALテーブルを削除します。
例:
SELECT sysdate FROM dual;
変換結果:
SELECT current_timestamp;
dualという名前のテーブルを作成します。
SELECTステートメントのユーザー定義関数
AnalyticDB for PostgreSQLでは、SELECTステートメントでユーザー定義関数を呼び出すことができます。 これらの関数にSQL文を含めることはできません。 ユーザー定義関数にSQL文が含まれている場合、次のエラーメッセージが表示されます。
ERROR: function cannot execute on segment because it accesses relation "public.t2" (functions.c:155) (seg1 slice1 127.0.0.1:25433 pid=52153) (cdbdisp.c:1326) DETAIL: SQL statement "select b from t2 where a = $1 "
このエラーを防ぐには、SELECTステートメントのユーザー定義関数をSQL式またはサブクエリに変換します。
例:
CREATE OR REPLACE FUNCTION f1(arg int) RETURN int IS v int; BEGIN SELECT b INTO v FROM t2 WHERE a = arg; RETURN v; END; SELECT a, f1(b) FROM t1;
変換結果:
SELECT t1.a, t2.b FROM t1, t2 WHERE t1.b = t2.a;
複数のテーブルのOUTER JOIN (+)
AnalyticDB for PostgreSQLは (+) 構文をサポートしていません。 (+) 構文を標準のOUTER JOIN構文に変換する必要があります。
例:
SELECT * FROM a,b WHERE a.id=b.id(+)
変換結果:
SELECT * FROM a LEFT JOIN b ON a.id=b.id
(+) 構文で3つのテーブルに対してJOIN操作を実行する必要がある場合は、WTEを使用して2つのテーブルを結合し、WTEテーブルと (+) で接続されているテーブルに対してOUTER join操作を実行します。
例:
SELECT * FROM test1 t1, test2 t2, test3 t3 WHERE t1.col1(+) BETWEEN NVL(t2.col1, t3.col1) ADN NVL(t3.col1, t2.col1);
変換結果:
WITH cte AS (SELECT t2.col1 AS low, t2.col2, t3.col1 AS high, t3.col2 AS c2 FROM t2, t3) SELECT * FROM t1 RIGHT OUTER JOIN cte ON t1.col1 BETWEEN coalesce(cte.low, cte.high) AND coalesce(cte.high,cte.low);
MERGE INTO
ほとんどの場合、MERGE INTO構文はINSERT ON CONFLICTによって実装できます。 ただし、MERGE INTOの一部の機能は、ストアドプロシージャによってのみ実装できます。
INSERT ON CONFLICTの詳細については、「INSERT ON CONFLICTを使用したデータの上書き」をご参照ください。
ストアドプロシージャの詳細については、「ストアドプロシージャ」をご参照ください。
シーケンス
例:
CREATE SEQUENCE seq1; SELECT seq1.nextval FROM dual;
変換結果:
CREATE SEQUENCE seq1; SELECT nextval('seq1');
カーソル
次のステートメントを使用して、Oracleのカーソルをトラバースできます。
例:
FUNCTION test_func() IS Cursor data_cursor IS SELECT * from test1; BEGIN FOR I IN data_cursor LOOP Do something with I; END LOOP; END;
変換結果:
CREATE OR REPLACE FUNCTION test_func() AS $body$ DECLARE data_cursor cursor for select * from test1; I record; BEGIN Open data_cursor; LOOP Fetch data_cursor INTO I; If not found then Exit; End if; Do something with I; END LOOP; Close data_cursor; END; $body$ LANGUAGE PLPGSQL;
同じ名前のカーソルは、再帰関数で開くことができます。 これはAnalyticDB for PostgreSQLではサポートされていません。 FOR I INクエリを使用する必要があります。
例:
FUNCTION test_func(level IN numer) IS Cursor data_cursor IS SELECT * from test1; BEGIN If level > 5 then return; End if; FOR I IN data_cursor LOOP Do something with I; test_func(level + 1); END LOOP; END;
変換結果:
CREATE OR REPLACE FUNCTION test_func(level int) returns void AS $body$ DECLARE data_cursor cursor for select * from test1; I record; BEGIN If level > 5 then return; End if; For I in select * from test1 LOOP Do something with I; PERFORM test_func(level+1); END LOOP; END; $body$ LANGUAGE PLPGSQL;