Oracleでのセッションやプロセス数には上限があり、それを超えてしまうとデータベースにアクセス出来ずに予期せぬエラー(ORA-12519)が発生するなどの不具合が発生してしまいます。
Oracleで最大プロセス数や最大セッション数は初期化パラメータを管理しているSPFILEに定義されています。変更前にSPFILEのバックアップを取得しておくのをオススメします。
SPFILEの配置場所
Oracle DB 18cの場合の例です。
配置位置:[ORACLE_HOME]/database/SPFILE[ORACLE_SID].ORA (例)C:\ORACLE\WINDOWS.X64_180000_db_home\database\SPFILEORCL.ORA
最大プロセス数、最大セッション数の変更方法
最初に「V$SYSTEM_PARAMETER」から現在の最大プロセス数と最大セッション数の設定値を確認します。「V$SYSTEM_PARAMETER」はインスタンスに現在有効になっている初期化パラメータ情報を示します。
SELECT NAME, VALUE
FROM V$SYSTEM_PARAMETER
WHERE NAME IN ('processes' , 'sessions' );
次にALETER文でプロセス数の上限を変更します。
ALTER SYSTEM SET PROCESSES = 1000 SCOPE = SPFILE;
SPFILEの変更はOracleを再起動しないと適用されないため、Oracle DBを再起動します。 詳細は「Oracle Database(Oracleサーバ)の再起動(停止・起動)手順 」参照
再度プロセス数とセッション数を確認すると上限が変更されているのが確認出来ます。セッション数は明示的に変更しなくてもプロセス数の変更に比例して上限が増えます。
SELECT NAME, VALUE
FROM V$SYSTEM_PARAMETER
WHERE NAME IN ('processes' , 'sessions' );
OracleではTRUC関数を使用することで年、月、日、時、分、秒以下を切り捨てて取得することが可能となります。
使用例
サンプルテーブル「BIRTHDAY」
クエリー(SQL)
BIRTHDAYテーブルのUPDATE_DATEに対してTRUNC関数を使用した例となります。第2引数へformatを指定することで指定した単位で切り捨てた値を取得することが出来ます。
SELECT
TRUNC (b.UPDATE_DATE, 'YYYY' ),
TRUNC (b.UPDATE_DATE, 'MM' ),
TRUNC (b.UPDATE_DATE, 'DD' ),
TRUNC (b.UPDATE_DATE, 'HH' ),
TRUNC (b.UPDATE_DATE, 'MI' )
FROM BIRTHDAY b;
formatの種類
format 説明
YYYY 年まで取得して月日時分秒を切り捨て
MM 年月まで取得して日時分秒を切り捨て
DD 年月日まで取得して時分秒を切り捨て
HH 年月日時まで取得して分秒を切り捨て
MI 年月日時分まで取得して秒を切り捨て
出力結果
Oracle Databaseをインストールすると自動的に作成される管理者ユーザー「SYS」と「SYSTEM」のデフォルトパスワードについてメモしておきます。
SYSユーザーのデフォルトパスワード:change_on_install
SYSTEMユーザーのデフォルトパスワード:manager
SQLでシステム日付、誕生日を使用して年齢、システム日付~誕生日までの月数、日数を取得するSQLをメモしておきます。
以下はOracleでの実行例となっています。
サンプルテーブル
「BIRTHDAY」テーブル
【Oracle】システム日付と誕生日から年齢、誕生日までの月数、日数を表示する例
クエリー(SQL)例
SELECT
TO_CHAR (sysdate ,'YYYY-MM-DD' ) "本日の日付" ,
TO_CHAR (b.BIRTHDAY,'YYYY-MM-DD' ) "誕生日" ,
EXTRACT (YEAR FROM sysdate ) - EXTRACT (YEAR FROM b.BIRTHDAY) "年齢" ,
TRUNC (MONTHS_BETWEEN (sysdate ,b.BIRTHDAY)) "誕生日までの月数" ,
TRUNC (sysdate - b.BIRTHDAY) "誕生日までの日数"
FROM dual, BIRTHDAY b;
実行結果
SQL PlusやSQL Developerに用意されている「DESCRIBE」コマンドを使用することでテーブル構造を確認することが出来ます。
DESCRIBEコマンドはDESCと省略することも出来ます。
SQL PlusでのDESCRIBEコマンド実行例
「DESCRIBE テーブル名」でテーブル構造が確認できます。
SQL PlusでのDESCコマンド実行例
DESCでもDESCRIBEと同じ結果を取得できます。
SQLを見てるとたまにWHERE句内で「(+)」と記載されているのを見かけることがあります。
この「(+)」はOracle独自で記載が可能となる外部結合演算子といって、「g.GOODS_CODE = gt.GOODS_CODE(+)」のように指定するとLEFT OUTER JOINと同じ結果を取得することが出来ます。
サンプルテーブル
「GOODS」テーブル
「GOODS_TYPE」テーブル
外部結合演算子を利用したクエリー(SQL)例
SELECT g.name, gt.type_name
FROM USER1.GOODS g, USER1.GOODS_TYPE gt
WHERE g.GOODS_CODE = gt.GOODS_CODE(+);
通常の左外部結合でのクエリー(SQL)例
SELECT g.name, gt.type_name
FROM USER1.GOODS g
LEFT OUTER JOIN USER1.GOODS_TYPE gt ON g.GOODS_CODE = gt.GOODS_CODE;
実行結果
外部結合演算子、左外部結合どちらも同じ結果となります。
補足
「(+)」演算子の歴史的背景 Oracle の古いバージョンからサポートされていた外部結合の書き方で、ANSI SQL 標準が普及する以前によく使われていました。ANSI 標準(LEFT JOIN
/ RIGHT JOIN
/ FULL OUTER JOIN
)が登場して以降は、可読性・移植性の観点から推奨されないことが多いです。
制限・注意点
可読性・保守性 :g.GOODS_CODE = gt.GOODS_CODE(+)
のような記述は、JOIN の方向やどのテーブルに外部結合をかけているかが分かりにくく、後でクエリを読む人が迷いやすいです。
複雑な結合 :複数テーブルを結合する場合、どこに (+)
を付けるか、また付け方によって結果が変わるため、注意深く設計する必要があります。
NULL の扱い :外部結合によって NULL が返る行が含まれますが、条件節で他の条件と組み合わせると意図しない行の除外が起きることがあります(例えば WHERE 節で AND
条件として別の非 NULL 条件を加えると外部結合の意味が薄れる等)。
ANSI 標準との違い
項目 (+) 外部結合演算子 ANSI SQL 外部結合 (LEFT OUTER JOIN 等)
可読性 やや分かりにくい 比較的分かりやすい
移植性 Oracle に依存 多くの RDBMS でサポートされる
複雑な JOIN の組み立て エラーや誤解の元になりやすい ON 句で明示的に指定できるため制御しやすい
サポート状況 最新 Oracle でも非推奨の方向 推奨される方式
現代のベストプラクティス
新規開発では ANSI SQL の外部結合構文 を使うことを推奨。可読性や他 DBMS への移植性が高いため。
既存システムで (+)
を使っているなら、リファクタリングやドキュメント整備を行い、「なぜこの構文になっているか」「どのような影響があるか」を明らかにしておく。
テストを用意して、クエリ変更後に結果が同じになることを検証する(特に NULL の扱いや結合の漏れが起きていないか)。
実際の書き換え例
旧構文を ANSI 標準に書き換えるときの例をもう一つ:
互換性・移行のヒント
Oracle のバージョンによっては (+)
構文が将来削除される可能性があり、非推奨の警告が出ることもあります。
他の RDBMS(PostgreSQL、MySQL、SQL Serverなど)で同じSQLを使うことを想定するなら、ANSI JOINに統一しておくと移行がスムーズです。
クエリのパフォーマンスにも注意。古い構文でも Oracle のオプティマイザが合理化する場合がありますが、可視性や保守性を取る方が長期的には有利。
投稿ナビゲーション
「駑馬十駕」を信念に IT系情報を中心に調べた事をコツコツ綴っています。