このドキュメントは、Oracle® 11g/12c データベースから Cloud SQL for PostgreSQL バージョン 12 への移行を計画し、実施する際に必要な情報とガイダンスを提供するシリーズの一つです。このシリーズには、最初の設定のパートに加えて、次のパートが含まれています。
- Oracle から Cloud SQL for PostgreSQL への移行: 用語と機能
- Oracle から Cloud SQL for PostgreSQL への移行: データ型、ユーザー、テーブル
- Oracle から Cloud SQL for PostgreSQL への移行: クエリ、ストアド プロシージャ、関数、トリガー(このドキュメント)
- Oracle から Cloud SQL for PostgreSQL への移行: セキュリティ、オペレーション、モニタリング、ロギング
- Oracle Database のユーザーとスキーマを Cloud SQL for PostgreSQL に移行する
クエリ
Oracle と Cloud SQL for PostgreSQL は ANSI SQL 標準に対応しています。そのため、一般的に SQL ステートメントの移行は難しくありません、基本的な構文要素を使用するだけで移行できます。スカラー関数やその他の Oracle 拡張機能を指定する必要はありません。以下では、一般的な Oracle クエリ要素とそれに対応する Cloud SQL for PostgreSQL の同等機能について説明します。
基本的な SELECT 構文と FROM 構文
| Oracle の機能名または構文名 | Oracle の概要または実装 | Cloud SQL for PostgreSQL のサポート | Cloud SQL for PostgreSQL の対応ソリューションまたは代替ソリューション | 
|---|---|---|---|
| データ取得用の SQL 基本構文 | SELECT | ○ | SELECT | 
| SELECT(出力用) | SELECT 1 FROM DUAL | ○ | SELECT 1 | 
| 列のエイリアス | SELECT COL1 AS C1 | ○ | SELECT COL1 AS C1 | 
| テーブル名での大文字と小文字の区別 | 大文字と小文字は区別しない (例: テーブル名として ordersとORDERSのどちらも使用可能) | ○ | 引用符で囲まない限り、名前は大文字と小文字が区別されません(たとえば、 ordersとORDERSは同じ、"orders" と"ORDERS"は異なるものと扱われます)。 | 
Cloud SQL for PostgreSQL の SELECT 構文の詳細については、ドキュメントをご覧ください。
インライン ビュー
- インライン ビュー(別名、派生テーブル)は FROM句に指定されるSELECTステートメントで、サブクエリとして使用されます。
- インライン ビューを利用して複合計算を削除したり、結合オペレーションを排除したりすると、複雑なクエリをシンプルにできます。また、複数の個別クエリを 1 つの簡素化されたクエリに要約することもできます。
- 変換に関する注記: Oracle ではインライン ビューにエイリアスを使用する必要はありませんが、Cloud SQL for PostgreSQL ではインライン ビューごとに固有のエイリアスが必要です。
次の表に、Oracle から Cloud SQL for PostgreSQL へのインライン ビューの変換例を示します。
| Oracle 11g / 12c | Cloud SQL for PostgreSQL 12 | 
|---|---|
| SQL> SELECT FIRST_NAME,出力は次のようになります。 
FIRST_NAME           DEPARTMENT_ID     SALARY DATE_COL | インライン ビューにエイリアスがない場合: postgres=> SELECT FIRST_NAME,インライン ビューにエイリアスを追加した場合: postgres=> SELECT FIRST_NAME,出力は次のようになります。 
 first_name  | department_id |  salary  |            date_col | 
JOIN ステートメント
Oracle の JOIN ステートメントは、Cloud SQL for PostgreSQL の JOIN ステートメントでサポートされています。ただし、Oracle の結合演算子 (+) の使用は Cloud SQL for PostgreSQL でサポートされていません。同じ結果を得るには、外部結合用の標準 SQL 構文に変換する必要があります。
次の表に、JOIN の変換例を示します。
| Oracle の JOIN の種類 | Cloud SQL for PostgreSQL でのサポート | Cloud SQL for PostgreSQL JOIN の構文 | 
|---|---|---|
| INNER JOIN | ○ | SELECT E.FIRST_NAME, D.DEPARTMENT_NAME | 
| CROSS JOIN | はい | SELECT E.FIRST_NAME, D.DEPARTMENT_NAME | 
| FULL JOIN
[ OUTER ] | はい | SELECT E.FIRST_NAME, D.DEPARTMENT_NAME | 
| LEFT JOIN [ OUTER ] | はい | SELECT E.FIRST_NAME, D.DEPARTMENT_NAME | 
| RIGHT JOIN
[ OUTER ] | はい | SELECT E.FIRST_NAME, D.DEPARTMENT_NAME | 
| SUBQUERY | ○ | SELECT E.FIRST_NAME, D.DEPARTMENT_NAME | 
UNION、UNION ALL、INTERSECT、MINUS
Cloud SQL for PostgreSQL は、Oracle UNION、UNION ALL、および INTERSECT 演算子をサポートしています。MINUS 演算子はサポートされていません。ただし、Cloud SQL for PostgreSQL は EXCEPT 演算子を実装しています。この演算子は Oracle の MINUS 演算子と同等です。また、Cloud SQL for PostgreSQL は、Oracle ではサポートされていない INTERSECT ALL 演算子と EXCEPT ALL 演算子をサポートしています。
- UNION: 2 つ以上の- SELECTステートメントの結果セットを結合しますが、重複するレコードは除外します。
- UNION ALL: 重複レコードを除外せずに、複数の- SELECTステートメントの結果セットを結合します。
- INTERSECT: レコードが両方のデータセットに存在する場合にのみ、2 つ以上の- SELECTステートメントの結果で共通する部分を返します。重複するレコードは除外されません。
- INTERSECT ALL(Cloud SQL for PostgreSQL のみ): レコードが両方のデータセットに存在する場合にのみ、2 つ以上の- SELECTステートメントの結果で共通する部分を返します。
- MINUS (EXCEPTCloud SQL for PostgreSQL): 2 つ以上の- SELECTステートメントを比較し、最初のクエリで他のステートメントから返されない個別の行のみを返します。
- EXCEPT ALL(Cloud SQL for PostgreSQL のみ): 2 つ以上の- SELECTステートメントを比較し、重複レコードを排除せずに最初のクエリで他のステートメントから返されない行のみを返します。
変換に関する注記
Oracle の MINUS 演算子を Cloud SQL for PostgreSQL に変換する場合は、EXCEPT 演算子を使用します。
例
| Oracle の関数 | Oracle の実装 | Cloud SQL for PostgreSQL のサポート | Cloud SQL for PostgreSQL の対応ソリューションまたは代替ソリューション | 
|---|---|---|---|
| UNION | SELECT COL1 FROM TBL1 | ○ | SELECT COL1 FROM TBL1 | 
| UNION ALL | SELECT COL1 FROM TBL1 | はい | SELECT COL1 FROM TBL1 | 
| INTERSECT | SELECT COL1 FROM TBL1 | ○ | SELECT COL1 FROM TBL1 | 
| MINUS | SELECT COL1 FROM TBL1 | ○(PostgreSQL では Convert MINUSからEXCEPT) | SELECT COL1 FROM TBL1 | 
スカラー(単一行)関数とグループ化関数
Cloud SQL for PostgreSQL には、さまざまなスカラー(単一行)関数と集計関数が用意されています。一部の Cloud SQL for PostgreSQL 関数は、対応する Oracle 関数に非常によく似ています(名前と機能が似ている関数や、名前は異なっていても機能が似ている関数などがあります)。Cloud SQL for PostgreSQL の関数によっては、Oracle での対応する関数名と同じ名前が使用されていても、機能がそれぞれ異なる場合もあります。
次の表に、Oracle と Cloud SQL for PostgreSQL の間で名前と機能が同じ関数(「○」で示しています)と、変換が推奨される関数(「○」以外)を示します。
文字関数
| Oracle の関数 | Oracle 関数の仕様または実装 | Cloud SQL for PostgreSQL の同等機能 | Cloud SQL for PostgreSQL の対応関数 | Cloud SQL for PostgreSQL の関数の仕様または実装 | 
|---|---|---|---|---|
| CONCAT | str1 と str2 を連結した文字列を返します。 CONCAT('A', 1) = A1 | あり | CONCAT | Oracle と同等。 CONCAT('A', 1) = A1 | 
| LOWER/UPPER | すべての文字を小文字または大文字にして返します。 LOWER('SQL') = sql | あり | LOWER/UPPER | Oracle と同等。 LOWER('SQL') = sql | 
| LPAD/RPAD | expr1 の左側または右側に、expr2 で指定した文字を連続的に埋め込んで n 桁にして返します。: LPAD('A',3,'*') = **A | あり | LPAD/RPAD | Oracle と同等。 LPAD('A',3,'*') = **A | 
| SUBSTR | char の一部分(文字位置で始まり、部分文字列の長さ)を返します。 SUBSTR('PostgreSQL', 8, 3) | 部分的 | SUBSTR | 開始位置が正の数である場合の Oracle と同等です。 SUBSTR('PostgreSQL', 8, 3)Oracle で負の数が開始位置として指定されている場合、文字列の最後から部分文字列演算を実行します。これは Cloud SQL for PostgreSQL とは異なります。Oracle の動作が必要な場合は、代わりに RIGHT関数を使用します。 | 
| INSTR | 指定した文字列の中にある特定の文字列の位置(インデックス)を返します。 INSTR('PostgreSQL', 'e') | なし | なし | Cloud SQL for PostgreSQL には組み込みの instr関数はありません。Oracle 互換のinstr関数は、PL/pgSQL を使用して実装できます。 | 
| REPLACE | 検索文字列を置換文字列で置き換えた char を返します。 REPLACE('ORADB', 'ORA', 'PostgreSQL') | 部分的 | REPLACE | Oracle では置換文字列パラメータはオプションですが、Cloud SQL for PostgreSQL では必須です。パラメータを省略すると、検索文字列のオカレンスはすべて削除されます。Cloud SQL for PostgreSQL では、置換文字列に空の文字列を指定すると同じ動作を実現できます。 REPLACE('ORADB', 'ORA', 'PostgreSQL') | 
| TRIM | 文字列から先頭または末尾(あるいは両方)の文字を削除します。 TRIM(both '-' FROM '-PostgreSQL-') | あり | TRIM | Oracle と同等。 TRIM(both '-' FROM '-PostgreSQL-') | 
| LTRIM/RTRIM | 文字列の左端または右端から、検索で指定されたすべての文字を削除します。 LTRIM('   PostgreSQL', ' ') | あり | LTRIM/RTRIM | Oracle と同等。 LTRIM('   PostgreSQL', ' ')
= PostgreSQL | 
| ASCII | データベースの文字セットに含まれる最初の文字の 10 進表現を返します。 ASCII('A') = 65 | あり | ASCII | Oracle と同等。 ASCII('A') = 65 | 
| CHR | 文字に対応する ASCII コード値(0~225 の数値)を返します。 CHR(65) = A | あり | CHAR | Oracle と同等。 CHR(65) = A | 
| LENGTH | 指定した文字列の長さを返します。 LENGTH ('PostgreSQL') = 10 | あり | LENGTH | Oracle と同等。 LENGTH ('PostgreSQL') = 10 | 
| REGEXP_REPLACE | 正規表現パターンに一致する文字列を検索します。 REGEXP_REPLACE('John', '[hn].', '1') = Jo1 | あり | REGEXP_REPLACE | Oracle と同等。 REGEXP_REPLACE('John', '[hn].', '1') = Jo1 | 
| REGEXP_SUBSTR | 正規表現パターンに一致する文字列を検索できるように、 SUBSTR 関数の機能を拡張したものです。 REGEXP_SUBSTR('https://console.cloud.google.com/sql/instances','https://([[:alnum:]]+\.?){3,4}/?') | なし | なし | 同様の機能を実現するには、PostgreSQL の REGEXP_MATCHを使用します。 | 
| REGEXP_COUNT | ソース文字列でのパターン出現回数を返します。 | × | なし | 同様の機能を実現するには、PostgreSQL の REGEXP_MATCHを使用します。 | 
| REGEXP_INSTR | 正規表現パターンに一致する文字列の位置(インデックス)を検索します。 | × | なし | この機能をアプリケーション レイヤに変換します。 | 
| REVERSE | 文字列を反転させて返します。 REVERSE('PostgreSQL') = LQSergtsoP | あり | REVERSE | Oracle と同等。 REVERSE('PostgreSQL') = LQSergtsoP | 
数値関数
| Oracle の関数 | Oracle 関数の仕様または実装 | Cloud SQL for PostgreSQL の同等機能 | Cloud SQL for PostgreSQL の対応関数 | Cloud SQL for PostgreSQL の関数の仕様または実装 | 
|---|---|---|---|---|
| ABS | n の絶対値を返します。 ABS(-4.6) = 4.6 | あり | ABS | Oracle と同等。 ABS(-4.6) = 4.6 | 
| CEIL | n 以上の最小の整数を返します。 CEIL(21.4) = 22 | あり | CEIL | Oracle と同等。 CEIL(21.4) = 22 | 
| FLOOR | n 以下の最大の整数を返します。 FLOOR(-23.7) = -24 | あり | FLOOR | Oracle と同等。 FLOOR(-23.7) = -24 | 
| MOD | mをnで割った余りを返します。MOD(10, 3) = 1 | あり | MOD | Oracle と同等。 MOD(10, 3) = 1 | 
| ROUND | 小数点以下 n 桁に丸めた数値を返します。 ROUND(1.39, 1) = 1.4 | あり | ROUND | Oracle と同等。 ROUND(1.39, 1) = 1.4 | 
| TRUNC(数値) | n1 を小数点以下 n2 桁に切り捨てた数値を返します。 TRUNC(99.999) = 99 | あり | TRUNCATE(数値) | Oracle と同等。 TRUNC(99.999) = 99 | 
DateTime 関数
| Oracle の関数 | Oracle 関数の仕様または実装 | Cloud SQL for PostgreSQL の同等機能 | Cloud SQL for PostgreSQL の対応関数 | Cloud SQL for PostgreSQL の関数の仕様または実装 | 
|---|---|---|---|---|
| SYSDATE | データベース サーバーが存在するオペレーティング システムに設定されている現在の日付と時刻を返します。 SELECT SYSDATE FROM DUAL
 | 部分的(関数名と形式が異なる) | CURRENT_TIMESTAMP | CURRENT_TIMESTAMPは、Oracle の SYSDATE 関数とは異なる形式の日時を返します。SELECT CURRENT_TIMESTAMP
 | 
| SYSTIMESTAMP | 小数点以下の秒とタイムゾーンを含む、システムの日付を返します。 SELECT SYSTIMESTAMP FROM DUAL
 | 関数名の一部が異なる | CURRENT_TIMESTAMP | Cloud SQL for PostgreSQL は、Oracle とは異なる日付 / 時刻形式を返します。日付の形式は、元の日付 / 時刻形式と一致させる必要があります。 SELECT CURRENT_TIMESTAMP
 | 
| LOCAL TIMESTAMP | セッションのタイムゾーンでの現在の日付と時刻を TIMESTAMPデータ型の値で返します。SELECT LOCALTIMESTAMP
FROM DUAL
 | 部分的(日時形式が異なる) | LOCAL
TIMESTAMP | Cloud SQL for PostgreSQL は、Oracle とは異なる日付 / 時刻形式を返します。日付の形式は、元の日付 / 時刻形式と一致させる必要があります。 SELECT LOCALTIMESTAMP
 | 
| CURRENT_DATE | セッションのタイムゾーンでの現在の日付を返します。 SELECT CURRENT_DATE FROM DUAL
 | 部分的(日時形式が異なる) | CURRENT_
DATE | Cloud SQL for PostgreSQL は、Oracle とは異なる日付 / 時刻形式を返します。日付の形式は、元の日付 / 時刻形式と一致させる必要があります。 SELECT CURRENT_DATE
 | 
| CURRENT_TIMESTAMP | セッションのタイムゾーンでの現在の日付と時刻を返します。 SELECT CURRENT_TIMESTAMP FROM DUAL
 | 部分的(日時形式が異なる) | CURRENT_TIMESTAMP | Cloud SQL for PostgreSQL は、Oracle とは異なる日時形式を返します。日付の形式は、元の日時形式と一致する必要があります。 SELECT CURRENT_TIMESTAMP FROM DUAL
 | 
| ADD_MONTHS | 日付と、月を表す整数を返します。 ADD_MONTHS(SYSDATE, 1)
 | なし | なし | Cloud SQL for PostgreSQL で同じ機能を実現するには、 + / -演算子を使用して時間間隔を指定します。SELECT CURRENT_TIMESTAMP + INTERVAL '1 MONTH'
 | 
| EXTRACT(日付部分) | 日付 / 時刻または期間の式から、指定された日付 / 時刻フィールドの値を返します。 EXTRACT(YEAR FROM DATE '2019-01-31') | あり | EXTRACT(日付部分) | Oracle と同等。 EXTRACT(YEAR FROM DATE '2019-01-31') | 
| LAST_DAY | 指定された日付を含む月の最終日の日付を返します。 LAST_DAY('01-JAN-2019')
 | なし | なし | この問題を回避するには、 DATE_TRUNC演算子と+演算子を使用して月の最終日を計算します。日付の形式は元の日付 / 時刻形式と一致させる必要があります。SELECT DATE_TRUNC('MONTH', DATE '01-JAN-2019') + INTERVAL '1 MONTH -1 DAY'
 | 
| MONTH_BETWEEN | date1 と date2 の間の月数を返します。 MONTHS_BETWEEN(SYSDATE, SYSDATE-60)
 | 部分的 (日時形式が異なる関数) | AGE | Cloud SQL for PostgreSQL の AGE関数は、2 つのタイムスタンプ間の間隔を返します。AGE(DATE '01-JAN-2019', DATE '01-JAN-2019' - 60)
Oracle の MONTH_BETWEEN関数と同じ値を実現するには、より具体的な変換が必要になります。 | 
| TO_CHAR(日付 / 時刻) | 日付形式で指定された形式で、日時またはタイムスタンプのデータ型を VARCHAR2データ型の値に変換します。TO_CHAR(SYSDATE,'DD-MM-YYYY HH24:MI:SS')
 | あり | To_CHAR | Oracle と同等。 TO_CHAR(CURRENT_TIMESTAMP,'DD-MM-YYYY HH24:MI:SS');
 | 
エンコード関数とデコード関数
| Oracle の関数 | Oracle 関数の仕様または実装 | Cloud SQL for PostgreSQL の同等機能 | Cloud SQL for PostgreSQL の対応関数 | Cloud SQL for PostgreSQL の関数の仕様または実装 | 
|---|---|---|---|---|
| DECODE | IF-THEN-ELSEステートメントを使用して、各検索値を 1 つずつ式と比較します | × | CASE | 同様の機能を実現するには、Cloud SQL for PostgreSQL の CASEステートメントを使用します。 | 
| DUMP | データ型のコード、長さ(バイト数)、式の内部表現を含む VARCHAR2値を返します。 | × | なし | サポートされていません。 | 
| ORA_HASH | 指定した式のハッシュ値を計算します。 | × | MD5 / SHA224 / SHA256 / SHA385 / SHA512 | ハッシュ値を生成するには、128 ビットのチェックサムに Cloud SQL for PostgreSQL の MD5関数を使用するか、160 ビットのチェックサムにSHA関数を使用します。 | 
変換関数
| Oracle の関数 | Oracle 関数の仕様または実装 | Cloud SQL for PostgreSQL の同等機能 | Cloud SQL for PostgreSQL の対応関数 | Cloud SQL for PostgreSQL の関数の仕様または実装 | 
|---|---|---|---|---|
| CAST | 1 つの組み込みデータ型または集合型の値を別の組み込みデータ型または集合型の値に変換します。 CAST('1' as int) + 1
 | 部分的 | CAST | Cloud SQL for PostgreSQL の CAST関数は、Oracle のCAST 関数と同様ですが、2 つのデータベース間でのデータ型の違いにより、調整が必要になることがあります。CAST('1' as int) + 1
 | 
| CONVERT | 文字列をある文字セットから別の文字セットに変換します。 CONVERT (
'Ä Ê Í Õ Ø A B C D E ', 'US7ASCII', 'WE8ISO8859P1')
 | 部分的 | CONVERT | Cloud SQL for PostgreSQL の CONVERT関数はbytea値を返します。これは、VARCHARまたはTEXTではなく、バイナリ文字列です。PostgreSQL でサポートされている文字セットも Oracle とは異なります。CONVERT('Ä Ê Í Õ Ø A B C D E', 'UTF8', 'LATIN1')
 | 
| TO_CHAR(string/numeric) | この関数は数値または日付を文字列に変換します。 TO_CHAR(22.73,'$99.9')
 | 部分的 | TO_CHAR | Cloud SQL for PostgreSQL の TO_CHAR関数は、Oracle と同様の機能です。Cloud SQL for PostgreSQL がサポートする書式設定文字列のリストは少し異なります。デフォルトでは、Cloud SQL for PostgreSQL は符号の列を 1 つ予約するため、正数の前にスペースが挿入されます。これは、FM接頭辞を使用して抑制できます。TO_CHAR(22.73,'FM$99.9')
 | 
| TO_DATE | Oracle の TO_DATE関数は、文字列をソース固有の日付 / 時刻形式の日付に変換します。TO_DATE('2019/01/01', 'yyyy-mm-dd')
 | 部分的 | TO_DATE | Cloud SQL for PostgreSQL の TO_DATE関数は、Oracle と同様の機能です。Cloud SQL for PostgreSQL がサポートする書式設定文字列のリストは少し異なります。TO_DATE('2019/01/01', 'yyyy-mm-dd')
 | 
| TO_NUMBER | 式を NUMBERデータ型の値に変換します。TO_NUMBER('01234')
 | 部分的 | TO_NUMBER | Cloud SQL for PostgreSQL の TO_NUMBER関数では入力として書式設定文字列が必要ですが、Oracle では省略可能です。TO_NUMBER('01234','99999')
代替案として、複雑な書式設定文字列を必要としない変換に CAST関数を使用する方法があります。CAST('01234' AS NUMERIC)
 | 
条件付き SELECT 関数
| Oracle の関数 | Oracle 関数の仕様または実装 | Cloud SQL for PostgreSQL の同等機能 | Cloud SQL for PostgreSQL の対応関数 | Cloud SQL for PostgreSQL の関数の仕様または実装 | 
|---|---|---|---|---|
| CASE | CASEステートメントは、一連の条件に基づいて対応するステートメントを選択して実行します。構文は次のとおりです。 CASE WHEN condition THEN result
[WHEN ...] [ELSE result]
END | あり | CASE | Oracle と同等。 CASE WHEN condition THEN result
[WHEN ...] [ELSE result]
END | 
null 関数
| Oracle の関数 | Oracle 関数の仕様または実装 | Cloud SQL for PostgreSQL の同等機能 | Cloud SQL for PostgreSQL の対応関数 | Cloud SQL for PostgreSQL の関数の仕様または実装 | 
|---|---|---|---|---|
| COALESCE | 式のリスト内の最初の null 以外の式を返します。 COALESCE(null, '1', 'a')
 | あり | COALESCE | Oracle と同等。 COALESCE(null, '1', 'a')
 | 
| NULLIF | expr1 と expr2 を比較します。同じ式である場合は null を返します。同じ式ではない場合は、expr1 を返します。 NULLIF('1', '2')
 | あり | NULLIF | Oracle と同等。 NULLIF('1', '2')
 | 
| NVL | (空白として返された)null を、クエリ結果に含まれる文字列で置き換えます。 NVL(null, 'a')
 | なし | COALESCE | 代わりに COALESCE関数を使用します。COALESCE(null, 'a')
 | 
| NVL2 | 指定された式が null または null 以外であるかどうかによって、クエリで返す値を決定します。 | なし | COALESCE | 代わりに COALESCE関数を使用します。COALESCE(null, 1, 'a')
 | 
環境関数と ID 関数
| Oracle の関数 | Oracle 関数の仕様または実装 | Cloud SQL for PostgreSQL の同等機能 | Cloud SQL for PostgreSQL の対応関数 | Cloud SQL for PostgreSQL の関数の仕様または実装 | 
|---|---|---|---|---|
| SYS_GUID | 最大 16 バイトからなる、グローバルに一意の ID(RAW 値)を生成して返します。 SELECT SYS_GUID() FROM DUAL
 | 部分的(関数名と形式が異なる) | UUID_GENERATE_V4 | Cloud SQL for PostgreSQL は、uuid-ossp 拡張機能をサポートします。これは UUID_GENERATE_V4のような関数を生成する UUID のリストを提供します。SELECT UUID_GENERATE_v4()= eaf356a6-2847-478d-af3b-6883f5ac6af2 | 
| UID | セッション ユーザー(ログオンしているユーザー)を 一意に識別する整数を返します。 SELECT UID FROM DUAL
 | なし | なし | なし | 
| USER | 現在のセッション ユーザー名を返します。 SELECT USER FROM DUAL
 | あり | USER | Oracle と同等。 SELECT USER;
 | 
| USERENV | 現在のユーザー セッションに関する情報と現在のパラメータ構成を返します。 SELECT USERENV('LANGUAGE') FROM DUAL
 | なし | なし | Cloud SQL for PostgreSQL には同等の USERENV関数はありませんが、USERENV('SID')などの個々のパラメータは、PG_BACKGROUND_PID()のようなシステム情報関数を使用して取得できます。 | 
| ROWID | Oracle サーバーは各テーブルの行ごとに、テーブル内でその行を識別する一意の ROWIDを割り当てます。ROWIDは行のアドレスであり、データ オブジェクト番号、行のデータブロック、行の位置、データファイルからなります。 | 関数名の一部が異なる | ctid | Cloud SQL for PostgreSQL の ctidは、テーブル内の行バージョンの物理的な場所を識別します。これは、Oracle のROWIDと類似した機能です。 | 
| ROWNUM | Oracle によりテーブルまたは結合テーブルから行が選択される順番を表す数値を返します。 | なし | LIMIT or ROW_NUMBER() | Cloud SQL for PostgreSQL は、 ROWNUMを使用してクエリにより返される結果の数を制限するのではなく、同様の目的でLIMITとOFFSETをサポートします。他のシナリオでは、Oracle の ROWNUMに代わる回避策として、ROW_NUMBER()ウィンドウ関数を使用できます。ただし、結果の順序とパフォーマンスの差分を検討してから代わりとして使用する必要があります。 | 
集計(グループ化)関数
| Oracle の関数 | Oracle 関数の仕様または実装 | Cloud SQL for PostgreSQL の同等機能 | Cloud SQL for PostgreSQL の対応関数 | Cloud SQL for PostgreSQL の関数の仕様または実装 | 
|---|---|---|---|---|
| AVG | 列または式の平均値を返します | ○ | AVG | Oracle と同等 | 
| COUNT | クエリによって返される行数を返します。 | ○ | COUNT | Oracle と同等 | 
| COUNT
(DISTINCT) | 列または式に含まれる固有の値の数を返します。 | ○ | COUNT | Oracle と同等 | 
| MAX | 列または式の最大値を返します。 | ○ | MAX | Oracle と同等 | 
| MIN | 列または式の最小値を返します。 | ○ | MIN | Oracle と同等 | 
| SUM | 列または式の値の合計を返します。 | ○ | SUM | Oracle と同等 | 
| LISTAGG | 測定列の各グループに含まれる値を連結して、 ORDER BY句で指定された単一行でグループ内のデータを表示します。SELECT LISTAGG( | なし | STRING_AGG | Cloud SQL for PostgreSQL の STRING_AGG関数を使用して、Oracle と同様の結果を返します。ただし、以下の場合は構文が異なります。SELECT STRING_AGG(DEPARTMENT_NAME, ', ' order by DEPARTMENT_NAME) FROM DEPARTMENTS; | 
Oracle 12c Fetch
| Oracle の関数 | Oracle 関数の仕様または実装 | Cloud SQL for PostgreSQL の同等機能 | Cloud SQL for PostgreSQL の対応関数 | Cloud SQL for PostgreSQL の関数の仕様または実装 | 
|---|---|---|---|---|
| FETCH | 複数行クエリの結果セットからデータ行を取得します。 SELECT * FROM | なし | LIMIT | Cloud SQL for PostgreSQL の LIMIT句を使用して、特定のレコードセットのみを取得します。SELECT * FROM
EMPLOYEES
LIMIT 10; | 
基本的なフィルタリング、演算子、サブクエリ
基本的なフィルタリング、演算子関数、サブクエリは、最小限の追加の作業を行うだけで比較的簡単に変換できます。
変換に関する注記
デフォルトで返される日付形式は Oracle と Cloud SQL for PostgreSQL で異なるため、日付の形式を確認し、必要な処置を行う必要があります。
- Oracle の SYSDATE関数はデフォルトで01-AUG-19を返します。
- PostgreSQL の CURRENT_DATE関数はデフォルトで2019-08-01を返します(書式設定を行っても時刻は返されません)。現在の日時を取得するには、CURRENT_TIMESTAMP関数を使用します。デフォルトでは、2019-08-01 00:00:00.000000+00 を返します。
- 日付と時刻の形式は、Cloud SQL for PostgreSQL の TO_CHAR関数で設定できます。
| Oracle の関数またはサブクエリ | Cloud SQL for PostgreSQL の同等機能 | Cloud SQL for PostgreSQL で対応する関数またはサブクエリ | Cloud SQL for PostgreSQL の関数の仕様または実装 | 
|---|---|---|---|
| EXISTS/
NOT EXISTS | ○ | EXISTS/
NOT EXISTS | SELECT * FROM DEPARTMENTS D | 
| IN/NOT IN | はい | IN/NOT IN | SELECT * FROM DEPARTMENTS D | 
| LIKE/NOT LIKE | はい | LIKE/NOT LIKE | SELECT * FROM EMPLOYEES | 
| BETWEEN/
NOT BETWEEN | はい | BETWEEN/ | SELECT * FROM EMPLOYEES | 
| AND/OR | はい | AND/OR | SELECT * FROM EMPLOYEES | 
| SubQuery | あり | SubQuery | Cloud SQL for PostgreSQL は、 JOINステートメントおよびWHERE/AND句のフィルタリングで、SELECTレベルのサブクエリをサポートしています。-- SELECT SubQuery | 
| 演算子 | ○ | 演算子 | Cloud SQL for PostgreSQL は、すべての基本演算子をサポートしています。 > | >= | < | <= | = | <> | != | 
分析関数(またはウィンドウ関数とランキング関数)
Oracle の分析関数では、標準 SQL の分析関数の機能を拡張して、行のグループ(RANK()、ROW_NUMBER()、FIRST_VALUE() など)に基づいて集約値を計算できます。これらの関数は、1 つのクエリ式の範囲内で論理的に分割されたレコードに適用されます。一般に、データ ウェアハウジングとビジネス インテリジェンス レポートおよびアナリティクスを組み合わせて使用されます。
変換に関する注記
Cloud SQL for PostgreSQL は、Postgres で集計関数やウィンドウ関数として知られる多くの分析関数をサポートしています。Postgres でサポートされていないあまり一般的ではない関数を使用しているアプリケーションの場合、サポートされている拡張機能を探すか、ロジックをアプリケーション レイヤに移動する必要があります。
次の表に、Oracle で最も一般的な分析関数を示します。
| 関数ファミリー | 関連する関数 | Cloud SQL for PostgreSQL でのサポート | 
|---|---|---|
| 分析とランキング | RANK | ○( AVERAGE_RANKを除く) | 
| 階層表示 | CONNECT BY | × | 
| ラグ | LAG | ○( LAGとLEADのみ) | 
共通テーブル式(CTE)
CTE では、一連のコードのロジックを実装して、複雑すぎるか何度も使用するには効率的ではないと考えられる SQL コードを再利用できます。CTE に名前を付けた後、SQL ステートメントのさまざまな部分で WITH 句を使って CTE を複数回使用できます。CTE は、Oracle と Cloud SQL for PostgreSQL の両方でサポートされています。
例
| Oracle と Cloud SQL for PostgreSQL | |
|---|---|
| WITH DEPT_COUNT | 
MERGE ステートメント
MERGE(または UPSERT)ステートメントを使用すると、1 つの DML オペレーションを別個に実行するのではなく、1 つの MERGE オペレーションの中で条件付きで複数の DML オペレーションを実行する単一の SQL ステートメントを指定できます。ソーステーブルからレコードを選択した後、論理構造を指定することによって、ターゲット テーブルに対して複数の DML オペレーションを自動的に実行します。この機能を使用すると、挿入、更新、削除を何度も行う必要がありません。MERGE は確定的なステートメントです。つまり、MERGE ステートメントで行が処理された後、その行を同じ MERGE ステートメントで再処理することはできません。
変換に関する注記
Cloud SQL for PostgreSQL は、Oracle とは異なり、MERGE 機能をサポートしていません。Cloud SQL for PostgreSQL には、MERGE 機能を部分的にシミュレートするため、INSERT ... ON CONFLICT DO UPDATE ステートメントが用意されています。
- INSERT… ON CONFLICT DO UPDATE: 挿入された行によって、固有の違反または除外制約違反を引き起こす場合は、- ON CONFLICT DO UPDATE句で指定された代替のアクションを実行します。たとえば、次のようになります。
INSERT INTO tbl (a,b,c) VALUES (1,2,3)
  ON CONFLICT (a) DO UPDATE SET b = 2, c = 3;
代わりに、MERGE 機能をストアド プロシージャに変換し、例外 / 重複の処理で INSERT、UPDATE、DELETE コマンドを使用して DML オペレーションを管理することもできます。
SQL ステートメントのヒント
Oracle では、クエリ実行計画の効率化を目的に、ユーザーが豊富な SQL クエリヒントを使用してオプティマイザーの動作に影響を与えられるようになっています。Cloud SQL for PostgreSQL には、オプティマイザーに影響を与えるような、同等の SQL ステートメント レベル、ヒンティング メカニズムはありません。
Cloud SQL for PostgreSQL は、クエリ プランナーによって選択されたクエリプランに影響を与えるため、セッション レベルで適用可能な構成パラメータのセットを提供します。これらの構成パラメータの影響は、特定のアクセス メソッドの有効化と無効化や、プランナーのコスト定数の調整などさまざまです。たとえば、次のステートメントは、テーブル全体のスキャンなどの、シーケンシャル スキャンのプランタイプをクエリ プランナーで使用できなくなります。
SET ENABLE_SEQSCAN=FALSE;
ランダム ディスクのページ取得(デフォルトは 4.0)のプランナーの費用の見積もりを調整するには、次のステートメントを使用します。
SET RANDOM_PAGE_COST=2.0;
この値を削減すると、Cloud SQL for PostgreSQL はインデックス スキャンを優先します。値を引き上げることで、逆の処理が行われます。
変換に関する注記
Oracle と Cloud SQL for PostgreSQL のオプティマイザーは根本的に異なります。Cloud SQL for PostgreSQL は Oracle スタイルの SQL クエリヒントをサポートしていないため、Cloud SQL for PostgreSQL への移行時にはクエリヒントはすべて削除することをおすすめします。次に、Cloud SQL for PostgreSQL ツールを使用して厳格なパフォーマンス テストを実施し、実行プランでクエリを調べて、ユースケースに応じてインスタンス パラメータまたはセッション パラメータを調整します。
実行計画
実行計画の主な目的は、クエリ オプティマイザーがデータベースのデータにアクセスする際に行った選択についての詳細を提供することです。クエリ オプティマイザーによって、データベース ユーザー用に SELECT、INSERT、UPDATE、DELETE の各ステートメントの実行計画が生成されます。また、管理者は特定のクエリや DML オペレーションについての理解を深めることができます。これは、クエリのパフォーマンスを調整する場合に非常に有効です。たとえば、インデックスのパフォーマンスを確認する場合や、作成する必要があるインデックスがあるかどうかを判断する場合に役立ちます。
実行計画は、データ量、データ統計、インスタンス パラメータ(グローバル パラメータまたはセッション パラメータ)によって影響される可能性があります。
変換に関する考慮事項
実行計画は移行の必要があるデータベース オブジェクトではありません。これは、同じデータセットに対して同じステートメントを実行する場合に、Oracle と Cloud SQL for PostgreSQL の間のパフォーマンスの違いを分析するためのツールです。
Cloud SQL for PostgreSQL でサポートしている実行プランの構文、機能、出力は、Oracle とは異なります。
実行計画の例を次に示します。
| Oracle の実行計画 | Cloud SQL for PostgreSQL の実行計画 | 
|---|---|
| SQL> EXPLAIN PLAN FOR | postgres=> EXPLAIN SELECT * FROM EMPLOYEES WHERE EMPLOYEE_ID = 105;
                                   QUERY PLAN
--------------------------------------------------------------------------------
 Index Scan using emp_emp_id_pk on employees  (cost=0.14..8.16 rows=1 width=71)
   Index Cond: (employee_id = '105'::numeric)
(2 rows) | 
ストアド プロシージャ、関数、トリガー
PL/SQL は Oracle の拡張プロシージャ言語であり、データベース内でコードベースのソリューションを作成、保管、適用するために使用されます。通常、データベースのストアド プロシージャと関数は、Oracle の PL/SQL、MySQL の MySQL プロシージャ言語などの ANSI SQL および SQL 拡張プロシーシャ言語からなるコード要素です。PL/pgSQL は PostgreSQL の拡張プロシージャ言語向けです。
これらのストアド プロシージャと関数の目的は、パフォーマンス、互換性、セキュリティなどの要件に応じて、アプリケーションからではなくデータベース内から実行するのに適したソリューションを提供することです。ストアド プロシージャと関数では両方とも PL/SQL を使用しますが、ストアド プロシージャは主に DDL/DML オペレーションを実行するために使用されます。関数は主に、計算を行って特定の結果を返すために使用されます。
PL/SQL から PL/pgSQL
Oracle PL/SQL から Cloud SQL for PostgreSQL への移行という観点では、PL/pgSQL の構造と構文は Oracle PL/SQL と類似しています。ただし、コードの移行が必要になる大きな違いがいくつかあります。たとえば、Oracle と Cloud SQL for PostgreSQL ではデータ型が異なります。多くの場合、Cloud SQL for PostgreSQL でサポートされるデータ型名が使用されるように、移行後のコードで変換が必要になります。この 2 つの言語の違いについては、Oracle PL/SQL からの移行をご覧ください。
コード オブジェクトの権限とセキュリティ
Oracle でストアド プロシージャまたは関数を作成するには、CREATE PROCEDURE システム権限が必要です(他のユーザーでプロシージャまたは関数を作成するには、CREATE
ANY PROCEDURE 権限が必要です)。ストアド プロシージャまたは関数を実行するには、データベース ユーザーに EXECUTE 権限が必要です。
PostgreSQL では、コード手順または関数を作成するには、ユーザーには USAGE 権限が必要です。プロシージャまたは関数を実行するには、ユーザーがプロシージャまたは関数に対する EXECUTE 権限を持っている必要があります。
デフォルトでは、PL/pgSQL のプロシージャまたは関数は SECURITY INVOKER として定義されます。つまり、プロシージャまたは関数は、呼び出し元となるユーザーの権限で実行されます。または、SECURITY DEFINER を指定すると、関数を所有するユーザーの権限で関数を実行できます。
Cloud SQL for PostgreSQL のストアド プロシージャと関数の構文
次の例は、Cloud SQL for PostgreSQL のストアド プロシージャと関数の構文を示しています。
CREATE [ OR REPLACE ] PROCEDURE
    name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] )
  { LANGUAGE lang_name
    | TRANSFORM { FOR TYPE type_name } [, ... ]
    | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
    | SET configuration_parameter { TO value | = value | FROM CURRENT }
    | AS 'definition'
    | AS 'obj_file', 'link_symbol'
  } ...
CREATE [ OR REPLACE ] FUNCTION
    name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] )
    [ RETURNS rettype
      | RETURNS TABLE ( column_name column_type [, ...] ) ]
  { LANGUAGE lang_name
    | TRANSFORM { FOR TYPE type_name } [, ... ]
    | WINDOW
    | IMMUTABLE | STABLE | VOLATILE | [ NOT ] LEAKPROOF
    | CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
    | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
    | PARALLEL { UNSAFE | RESTRICTED | SAFE }
    | COST execution_cost
    | ROWS result_rows
    | SUPPORT support_function
    | SET configuration_parameter { TO value | = value | FROM CURRENT }
    | AS 'definition'
    | AS 'obj_file', 'link_symbol'
  } ...
トリガー
トリガーは、特定のイベントが発生したときに実行されるストアド プロシージャです。Oracle では、トリガー イベントはテーブル、ビュー、スキーマ、またはデータベースに関連付けられます。トリガーとなるイベントの種類は次のとおりです。
- データ操作言語(DML)ステートメント(例: INSERT、UPDATE、DELETE)
- データ定義言語(DDL)ステートメント(例: CREATE、ALTER、DROP)
- データベース イベント(例: LOGON、STARTUP、SHUTDOWN)
Oracle のトリガーには次のタイプがあります。
- シンプル トリガー: 指定したトリガー イベントの前後に 1 回だけ起動
- 複合トリガー: 複数のイベントで起動
- INSTEAD OFトリガー: 複雑な編集不可能なビューに対して透過的な更新メカニズムを提供する、特殊なタイプの DML トリガー
- システム トリガー: 特定のデータベース イベントで起動
Cloud SQL for PostgreSQL では、特定のテーブル、ビュー、外部テーブルに対する DML オペレーションの前または後にトリガーが起動します。INSTEAD OF トリガーは、ビューの更新メカニズムを提供するためにサポートされています。DDL オペレーションのトリガーは、イベント トリガーと呼ばれます。Cloud SQL for PostgreSQL は、データベース イベントに基づく Oracle のシステム トリガーをサポートしていません。
Oracle のトリガーとは異なり、Cloud SQL for PostgreSQL のトリガーは、トリガーの本文として匿名の PL/pgSQL ブロックをサポートしていません。0 個以上の引数を取り、トリガータイプを返す名前付き関数は、トリガー宣言で指定する必要があります。この関数は、トリガーが起動すると実行されます。
Cloud SQL for PostgreSQL のトリガーとイベント トリガーの構文
次の例は、Cloud SQL for PostgreSQL のトリガーとイベント トリガーの構文を示しています。
CREATE [ CONSTRAINT ] TRIGGER name { BEFORE | AFTER | INSTEAD OF } { event [ OR ... ] }
    ON table_name
    [ FROM referenced_table_name ]
    [ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ]
    [ REFERENCING { { OLD | NEW } TABLE [ AS ] transition_relation_name } [ ... ] ]
    [ FOR [ EACH ] { ROW | STATEMENT } ]
    [ WHEN ( condition ) ]
    EXECUTE { FUNCTION | PROCEDURE } function_name ( arguments )
event には、INSERT、UPDATE [ OF column_name [, ... ] ]、DELETE、TRUNCATE のいずれか 1 つを設定できます。
CREATE EVENT TRIGGER name
    ON event
    [ WHEN filter_value IN (filter_value [, ... ]) [ AND ... ] ]
    EXECUTE { FUNCTION | PROCEDURE } function_name()
event には、ddl_command_start、ddl_command_end、table_rewrite、sql_drop のいずれか 1 つを設定できます。
filter_value には TAG のみを設定できます。
filter_value は、サポートされているコマンドタグのいずれかに設定できます。
次のステップ
- Cloud SQL for PostgreSQL ユーザー アカウントの詳細について確認する。
- Google Cloud に関するリファレンス アーキテクチャ、図、ベスト プラクティスを確認する。Cloud アーキテクチャ センターをご覧ください。