SQL PlusやSQL Developerに用意されている「DESCRIBE」コマンドを使用することでテーブル構造を確認することが出来ます。
DESCRIBEコマンドはDESCと省略することも出来ます。
SQL PlusでのDESCRIBEコマンド実行例
- 「DESCRIBE テーブル名」でテーブル構造が確認できます。
DBクライアントソフトなどでOracle DBへ接続時に「ORA-01109:データベースがオープンされていません。」が表示された場合の原因と対応方法についてメモしておきます。
上記の対応だけで解決しない場合や、環境によっては以下のようなケースもあるので参考にしてください。
ALTER PLUGGABLE DATABASE ALL SAVE STATE;
を実行しても、再起動後に PDB が自動的にオープンされないことがあります。
その際は以下を確認してみてください。
ENABLE_PLUGGABLE_DATABASE
が設定されているかPDB を開こうとしたときに ORA-01031: insufficient privileges が出る場合は、権限不足の可能性があります。SYSDBA
権限を持つユーザーで接続して実行する必要があります。
今の状態を確認したいときは、次のコマンドを使うと便利です。
1 2 3 4 |
```sql SELECT name, open_mode FROM v$pdbs; -- または SELECT name, status FROM dba_pdbs; |
READ WRITE
であればオープン済み、MOUNTED
ならまだ開いていない状態です。
もし原因が分からない場合は、アラートログ(alert log)や trace ファイルを確認してみてください。
「ファイルが読み込めない」「整合性が取れていない」といったエラーが記録されていることもあります。
Data Guard や RAC のような構成では、PDB のオープン状態が自動で引き継がれないことがあります。
フェイルオーバー後に PDB が閉じたままになるケースもあるので注意が必要です。
今回の ORA-01109 以外にも、以下のエラーが一緒に出ることがあります。
ORA-01110
ORA-01113
これらも「データベースがオープンされていない」状態に関係するため、併せて確認してみてください。
SQLを見てるとたまにWHERE句内で「(+)」と記載されているのを見かけることがあります。
この「(+)」はOracle独自で記載が可能となる外部結合演算子といって、「g.GOODS_CODE = gt.GOODS_CODE(+)」のように指定するとLEFT OUTER JOINと同じ結果を取得することが出来ます。
1 2 3 |
SELECT g.name, gt.type_name FROM USER1.GOODS g, USER1.GOODS_TYPE gt WHERE g.GOODS_CODE = gt.GOODS_CODE(+); |
1 2 3 |
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 のオプティマイザが合理化する場合がありますが、可視性や保守性を取る方が長期的には有利。
Oracleのインストール後にSQL*Plusなどでユーザー作成しようとした際、「ORA-65096」エラーが発生した場合の原因と対応方法についてメモしておきます。
原因が分かってしまえば対応はシンプルです。接続先がコンテナ・データベース(CDB)であるのがまずいのであればプラガブル・データベース(PDB)に変更してしまえばいいだけです。
ORA-65096: invalid common user or role name
は、マルチテナント構成の Oracle Database(12c以降) において、
ルートコンテナ(CDB$ROOT)上でローカルユーザーを作成しようとした場合に発生するエラーです。
以下のポイントを押さえておくと、再発を防ぎやすくなります。
観点 | 内容 |
---|---|
エラーの本質 | 共通ユーザーとローカルユーザーの区別を誤ったことによる構文エラー |
共通ユーザー名の規則 | C## または c## のプレフィックスが必須(COMMON_USER_PREFIX パラメータで変更可) |
発生条件 | CDB$ROOT に接続したままユーザーを作成/命名規則を満たさない場合 |
解決策 | ALTER SESSION SET CONTAINER = <PDB名> でPDBに切り替えてから CREATE USER を実行する |
参考 | SHOW CON_NAME; で現在の接続先(コンテナ)を確認可能 |
もしルートコンテナ側で共通ユーザーを作成したい場合は、以下のようにします。
SHOW PDBS;
で現在のPDB一覧を確認可能。OPEN_MODE
が READ WRITE
でなければユーザー作成はできません。
バージョン19c以降では、CDB構成がデフォルトのため、PDB接続の意識が必須 です。
TNS接続文字列(SERVICE_NAME
)が CDB
を指していると、意図せずルート側に接続してしまうことがあります。