oracleの独自関数のCOALESCE(コアレス)関数の用途についてメモしておきます。
COALESCE関数とは
COALESCE関数は引数のリストから最初のNULL以外の値を返却するOracle独自関数となります。
NVL2関数との違いは必ずしも引数へ指定するデータ型を全て合わせる必要はないことです。
ただデータの一貫性を保ちたい場合は極力データ型は合わせた方が望ましいです。
サンプルテーブル
- サンプルテーブル「CLIENT_ADDRESS」
oracleの独自関数のCOALESCE(コアレス)関数の用途についてメモしておきます。
COALESCE関数は引数のリストから最初のNULL以外の値を返却するOracle独自関数となります。
NVL2関数との違いは必ずしも引数へ指定するデータ型を全て合わせる必要はないことです。
ただデータの一貫性を保ちたい場合は極力データ型は合わせた方が望ましいです。
oracleの独自関数としてNVL関数やNVL2関数があります。
知ってると結構便利な関数なので、この2つの関数の違いについて整理しておきます。
NVL関数は第1引数がNULLなら第2引数の値(代替値)を返します。
もし第1引数の結果がNULLでなければ、そのまま第1引数の値を返します。
注意点として第1引数と第2引数へは同じデータ型を指定する必要があります。
1 |
SELECT NVL(END_DATE, sysdate) FROM CLIENT_ADDRESS; |
NVL2関数は第1引数がNULLの場合に、第2引数の値を返却し、第1引数がNULLの場合は第3引数の値を返却します。
注意点として第1引数、第2引数、第3引数に指定する値は全て同じデータ型を指定する必要があります。
性能試験などであるテーブルに大量データの作成が必要になった場合にINSERT文をループで処理できれば便利!という事で、SQLとロジックを組み合わせたストアドプロシージャでのサンプルプログラムとなります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
DECLARE -- 変数の宣言 counter NUMBER := 1; loop_limit NUMBER := 10; goods_id NUMBER := 1; BEGIN WHILE counter <= loop_limit LOOP -- 実行するSQL INSERT INTO USER1.GOODS (GOODS_ID,NAME,GOODS_CODE,PRICE) VALUES (goods_id,'パソコン',101,5000); -- インクリメント counter := counter + 1; -- カウンタをインクリメント goods_id := goods_id + 1; -- GOODS_IDをインクリメント END LOOP; -- 正常終了すれば自動的にCOMMITされるため明示的なCOMMITは不要。途中で失敗した場合は全件ロールバックされる -- DBクライアントソフトが自動コミットしない場合は明示的なCOMMITが必要 END; |
上記の例では、loop_limitに指定した件数分「GOODS」テーブルへレコードを追加するサンプルコードです。
上記の例では、loop_limit
を10としていますが、必要に応じて任意の数値に変更できます。
DBeaverで上記のストアドプロシージャを実行する場合は「SQLスクリプトを実行する」を選択することで正常に実行されます。
Oracleではデータベースを作成すると自動的に以下の表領域が作成されます。
表領域 説明
SYSTEM Oracleサーバーがデータベースを管理するために使用する表領域
SYSAUX SYSTEM表領域の補助表領域
TEMP データベースのデフォルトの一時表領域
UNDOTBS1 UNDO表領域
USERS 永続表領域
SYSやSYSTEMユーザー以外のユーザー用のデフォルト表領域
EXAMPLE データベース作成時に「サンプル・スキーマの作成」を指定すると作成される表領域
Oracleデータベースを起動すると内部的に以下の段階でデータベースが使用可能な状態となります。
段階 ステータス 状態
1 SHUTDOWN データベースが停止している状態
2 NOMOUNT インスタンスが起動している状態
※制御ファイル、データファイル、REDOログファイルはクローズ
3 MOUNT インスタンスが起動し、制御ファイルがオープンしている状態
※データファイル、REDOログファイルはクローズ
4 OPEN インスタンスが起動し、制御ファイル、データファイル、REDOログ・ファイルもオープンしている状態
※一般ユーザーが使用可能な状態
Oracleデータベースでは以下の制約を設定することが出来ます。
制約 説明
NOT NULL制約 NULL値の設定を許可しない
UNIQE制約
(一意キー制約)一意の値のみ許可します。複数レコード登録時、重複する値を許可しません。NULL値は許可します。
CHECK制約 指定した条件の値のみ許可します。
PRIMARY KEY制約
(主キー制約)一意の値のみ許可し、重複する値は許可しません。NULL値も許可しません。
FOREIGN KEY制約
(外部キー制約)指定した親テーブルに存在する値のみ許可します。
1 2 3 4 5 6 7 |
CREATE TABLE "USER1"."BIRTHDAY" ( "NAME_NO" NUMBER, "NAME" VARCHAR2(50) CONSTRAINT "BIRTHDAY_NAME_NN" NOT NULL ENABLE, "BIRTHDAY" DATE, "UPDATE_DATE" TIMESTAMP (6), CONSTRAINT "BIRTHDAY_NAME_NO_U" UNIQUE ("NAME_NO") ); |
Oracle DBのプロセス構造は大きく「ユーザープロセス」、「サーバープロセス」、「バックグラウンドプロセス」があります。
種類 | 説明 |
---|---|
DBWn (データベースライター) | データベースバッファキャッシュ内の変更されたデータをデータファイルへ書き込む |
LGWR (ログライター) | REDOログバッファにあるREDOログをREDOログファイルへ書き込む |
CKPT (チェックポイント) | チェックポイント情報を制御ファイルとデータファイルヘッダーへ書き込む |
SMON (システムモニター) | インスタンスのリカバリを実行する |
PMON (プロセスモニター) | ユーザープロセス障害からリカバリを実施する |
ARCn (アーカイバー) | REDOログファイルのコピー(アーカーブファイル)を作成する |
REDO (リカバラ) | 分散トランザクションに関する障害を自動的に解決する。 |
MMON (マネージメントモニター) | メモリー内の統計情報をスナップショットとして定期的にデーターベースへ格納する。 |
MMAN (メモリーマネージャ) | メモリーを必要な場所に動的に割り当てる |
SQLでsysdateなどの日付型へ加算、減算してxx日後、xxヶ月後、xx年後を求める方法をメモしておきます。
1 2 3 4 5 |
SELECT sysdate "本日の日付", sysdate + 30/86400 "本日の日付 + 30秒", sysdate - 30/86400 "本日の日付 - 30秒" FROM dual; |
1 2 3 4 5 |
SELECT sysdate "本日の日付", sysdate + 5/1440 "本日の日付 + 5分", sysdate - 5/1440 "本日の日付 - 5分" FROM dual; |
1 2 3 4 5 |
SELECT sysdate "本日の日付", sysdate + 2/24 "本日の日付 + 2時間", sysdate - 2/24 "本日の日付 - 2時間" FROM dual; |
1 2 3 4 5 |
SELECT sysdate "本日の日付", TO_CHAR(sysdate + 1,'YYYY-MM-DD') "本日の日付 + 1日", TO_CHAR(sysdate - 1,'YYYY-MM-DD') "本日の日付 - 1日" FROM dual; |
1 2 3 4 5 |
SELECT sysdate "本日の日付", TO_CHAR(ADD_MONTHS(sysdate, 1),'YYYY-MM-DD') "本日の日付 + 1ヶ月", TO_CHAR(ADD_MONTHS(sysdate, -1),'YYYY-MM-DD') "本日の日付 - 1ヶ月" FROM dual; |
1 2 3 4 5 |
SELECT sysdate "本日の日付", TO_CHAR(ADD_MONTHS(sysdate, 12),'YYYY-MM-DD') "本日の日付 + 1年", TO_CHAR(ADD_MONTHS(sysdate, -12),'YYYY-MM-DD') "本日の日付 - 1年" FROM dual; |
Oracleでのセッションやプロセス数には上限があり、それを超えてしまうとデータベースにアクセス出来ずに予期せぬエラー(ORA-12519)が発生するなどの不具合が発生してしまいます。
Oracleで最大プロセス数や最大セッション数は初期化パラメータを管理しているSPFILEに定義されています。変更前にSPFILEのバックアップを取得しておくのをオススメします。
Oracle DB 18cの場合の例です。
1 2 3 |
SELECT NAME, VALUE FROM V$SYSTEM_PARAMETER WHERE NAME IN('processes', 'sessions'); |
1 |
ALTER SYSTEM SET PROCESSES = 1000 SCOPE=SPFILE; |
1 2 3 |
SELECT NAME, VALUE FROM V$SYSTEM_PARAMETER WHERE NAME IN('processes', 'sessions'); |