rink_rewさんの助け合いフォーラム投稿一覧
EMPLOYEES表のレコードはEMPLOYEES_IDをキーに、その従業員の名前や上司の情報が格納されているものだと思いますが、MANAGER_ID列自体は「その従業員の上司のEMPLOYEE_ID」を表していて、その従業員に上司がいなければ空です。
本設問の問題文では、
EMPLOYEE_IDが「1008」の従業員と上司が同じである従業員の名前と、上司のEMPLOYEE_IDを出力します。
となっていますが、ここで「上司のEMPLOYEE_ID」の代わりに「上司のMANAGER_ID」と言ってしまうと、「上司の上司のEMPLOYEE_ID」を出力したいということになります。
解説にある正解の実行結果を見ると、列名は MANAGER_ID になりますが、実際に表示されているのは「上司のEMPLOYEE_ID」です。
実務でこういう出力を求めるシチュエーションなら、列別名とかつけると見やすいかなとは思いますけど、ちょっと趣旨から外れますね。
「オブジェクトを格納」はその通りだと思うのですが、「領域」かと問われると、解説にも記載の通りスキーマは「論理的な概念」と捉える方が適切だと思うので、ちょっと違うかなと感じます。
データベースの記憶域として考えれば、表や索引などのオブジェクトが実際に格納されるのはデータファイルということになりますし、スキーマはどちらかといえば、オブジェクトの管理単位のようなものだと理解しています。
とはいえ、黒本などでも「スキーマに格納される」といった表現もありますので、設問の選択肢としてはもう少し具体的な表現となっていた方がスッキリする気がしますね。
この設問だと、確かにおっしゃる通りemployees表のdepartment_idはNULLになり得るので、選択肢のSQLだと「全従業員の」表示にならない可能性ありますね。外部結合が適切ですね。
画像のオプションですが、-l(小文字のエル)ではなく、-I(大文字のアイ)になってるみたいですね...。
dropdbの-iに関しては環境によっては大文字でも小文字でも同じ結果が返るみたいですので間違いではないと言えるかもしれませんが、画像の前の説明部分で小文字ですし、小文字で統一されてた方が望ましいですね。
③の副問合せのSELECT文はUSING句を使用した結合を行ってます。USINGはそもそも2つの表に共通する列(同じ名前の列)を結合条件として使用するので、接頭辞をつける必要はありません。副問合せの出力結果は以下のとおりとなり、問題なくINSERTに使用できます。
SQL> SELECT department_id, department_name, avg_sal FROM v_emp JOIN departments USING (department_id);
DEPARTMENT_ID DEPARTMENT_NAME AVG_SAL
------------- ------------------------------ ----------
1 総務 431250
2 営業 400000
3 開発 400000
4 マーケティング 366666.667
5 品質管理 450000
以前の試験体系ですとBronzeの科目として「SQL基礎」があって、その頃はDECODE関数も主要なテキストでは試験範囲として紹介されていたと思います。
確かに最新の黒本を見てみるとDECODE単体では取り上げられてないようですが、現在の試験体系では、Silver SQLがSQL関連の最も低いレベルに該当すると思いますので、無視してしまうとちょっと怖いかな、という気はします。
メディア・リカバリの流れが、
- バックアップファイルをリストア
- リストアしたファイルに対してREDOログやアーカイブREDOログを適用
という手順であることを理解しているか、を問うために選択肢に含まれている誤答であるとは推察しますが、「リカバリ」という表現だけ見ると、nonstickmite866 さんもおっしゃる通り「これはリストア後の話で、リカバリ操作で必要なのはREDOデータではないか」と捉えることもできないことはないですね。
※「リストアしたバックアップファイルにREDOを適用するんだから、バックアップファイルは必要だ」という主張もできますが、この問題の解説では「まずバックアップ・ファイルのリストアが必要です」と説明されているので、観点が違いますね。
選択肢が「リカバリにバックアップ・ファイルは必要としない」ではなく「 メディア・ リカバリにバックアップ・ファイルは必要としない」だったら、しっくりくるんですが...。
そもそも問題集の分野分けは、オラクル社公式のチェックリストのカテゴリの名称と完全に対になっているわけではなさそうですので、この辺は現在の仕様?という感じでしょうか。
必要な知識を得るという観点では、ざっとみる限り現行の問題集で一通りしっかりとカバーされているようには思いますが、将来的に、問題集の分野名も公式情報に追従する形になったらいいなと思うところでもありますね。
ON句の代わりにWHERE句に記載することは可能ですが、その場合、FROM句でJOIN句が使用できなくなるため、結合するテーブルをカンマ区切りで列挙する必要があります。
ただ、複雑なSQL文の中で出力結果に対して複数のフィルタリング条件を適用する場合など、WHERE句内にANDやORを連ねることになるので、可読性は低くなるかもしれません。
SQL> SELECT p.promo_name, p.promo_begin_date, p.promo_end_date, s.time_id, s.quantity_sold
2 FROM promotions p JOIN sales3 s
3 ON p.promo_id = s.promo_id
4 AND s.time_id BETWEEN p.promo_begin_date AND NVL(p.promo_end_date, SYSDATE);
PROMO_NAME PROMO_BE PROMO_EN TIME_ID QUANTITY_SOLD
------------------------------ -------- -------- -------- -------------
プロモーション1 10-05-10 10-05-10 10-05-10 25
プロモーション5 10-10-01 10-12-31 10-11-05 21
プロモーション2 11-08-01 12-01-01 11-10-30 34
プロモーション2 11-08-01 12-01-01 11-12-31 15
プロモーション3 12-02-22 12-04-01 9
プロモーション4 11-12-24 12-12-31 12-07-10 16
6行が選択されました。
SQL> SELECT p.promo_name, p.promo_begin_date, p.promo_end_date, s.time_id, s.quantity_sold
2 FROM promotions p JOIN sales3 s
3 WHERE p.promo_id = s.promo_id
4 AND s.time_id BETWEEN p.promo_begin_date AND NVL(p.promo_end_date, SYSDATE);
WHERE p.promo_id = s.promo_id
*
行3でエラーが発生しました。:
ORA-00905: キーワードがありません。
SQL> SELECT p.promo_name, p.promo_begin_date, p.promo_end_date, s.time_id, s.quantity_sold
2 FROM promotions p, sales3 s
3 WHERE p.promo_id = s.promo_id
4 AND s.time_id BETWEEN p.promo_begin_date AND NVL(p.promo_end_date, SYSDATE);
PROMO_NAME PROMO_BE PROMO_EN TIME_ID QUANTITY_SOLD
------------------------------ -------- -------- -------- -------------
プロモーション1 10-05-10 10-05-10 10-05-10 25
プロモーション5 10-10-01 10-12-31 10-11-05 21
プロモーション2 11-08-01 12-01-01 11-10-30 34
プロモーション2 11-08-01 12-01-01 11-12-31 15
プロモーション3 12-02-22 12-04-01 9
プロモーション4 11-12-24 12-12-31 12-07-10 16
6行が選択されました。
SQL>
「WHEN MATCHED THEN」と「WHEN NOT MATCHED THEN」の順序は入れ替えても、MERGE文としてはエラーにはなりません。
ご提示のケースでもエラーにはならず、実行後は同様の結果となりました。
SQL> select * from cust_source;
ID NAME A EMAIL BIRTH_DAY
------ ---------- - -------------------- -----------
1 scott Y scott@xx.com 66-06-03
2 allen N al@yy.com 82-04-18
3 john Y John@zz.com 73-12-30
4 king Y king@zz.com 91-01-15
SQL> select * from cust_copy;
ID NAME A
------ ---------- -
1 SCOTT Y
2 ALLEN Y
3 TBD
SQL> MERGE INTO cust_copy c USING (SELECT id, UPPER(name) name, active FROM cust_source) p ON (c.id=p.id)
WHEN NOT MATCHED THEN
INSERT VALUES (p.id, p.name, p.active)
WHEN MATCHED THEN
UPDATE SET c.name=p.name, c.active=p.active;
4行がマージされました。
SQL> select * from cust_copy;
ID NAME A
------ ---------- -
1 SCOTT Y
2 ALLEN N
3 JOHN Y
4 KING Y
SQL>
ただし、処理順序(条件を評価する順序)は変わると思うので、実運用においてはデータの内容によっては結果が異なる可能性はあります。
また、パフォーマンスにも違いが出てくる可能性はあると思います。(そのような場合には実行計画の取得などして、チューニングしていくことになると思います。)
解説の以下の文が多重化の目的の説明になっていると思います。
制御ファイルの多重化の目的は、障害が発生してもシステムを停止させずに運用することではなく、制御ファイルに格納されている情報を保護することにあります。
ただ、破損の仕方にもよると思うのですが、多重化された制御ファイルの1つだけ破損しても、必ずしも即時に停止してしまうとは限らなかったと思います。
例えば、制御ファイル自体が消失(誤って削除)してしまった場合や、制御ファイル自体はOS上のファイルとして依然として存在しているが、バイナリファイルとして中身が不正な状態になってしまった場合など、それぞれ挙動はちょっと違ったような気がします。
Bronze試験の範囲としてこの辺について問われる問題が出題されるかはわかりませんが、もう少し正確に言うと「破損した制御ファイルにアクセスするような操作が実行されると停止する」という感じでしょうか。
※今の試験体系ではなく古いバージョンでの話ですが、Gold試験では、バックアップからのリストア・リカバリ関連の問題は結構出題されていたような記憶があります。
この問題の副問合せ(SELECT MAX(salary) / 2 FROM employees GROUP BY department_id)は、複数行を返す可能性があります。
「ALL」は「リスト内の全ての値が条件を満たす場合TRUE」です。この問題では「<ALL」が使用されているので、「左辺の値(部署の平均給与)が、右辺の値(全ての部署の最高給与の半分)より少ないもの」が結果として返されます。
「全ての値より少ない」は「最小値より少ない」に言い換えられると思います。
私も個人的には GROUP BY 句が先にくるイメージでしたが、気になったので19cや21cのマニュアルも確認してみたところ、やはり同様に「どちらの順序でも指定できます」と記載されていますね。勉強になりました。
ご提示のURLに私はアクセスできなかったので、どの図のことはわからないのですが、もし、メモリー管理方法として4つ列挙されている表のことでしたら、「説明」の列に※PGAは自動PGAメモリー管理となると記載があるので、その部分ですかね。
うろ覚えですが、以前にどこかの書籍かマニュアル・ドキュメント類で「自動共有メモリー管理を有効にすると、自動PGAメモリー管理が暗黙的に有効になる」みたいな記載があったような気がしますが、ちょっと正確に覚えてません。※私が取得したのは古いバージョンのOracle Masterなので、すみません。
この表現の意味するところは、おそらく、初期化パラメータとしてPGA_AGGREGATE_TARGETが自動的に設定されるわけではないが、V$PARAMETERビューやEnterprise Manager上は表示される、というような意味で「暗黙的」とされていたのかなと、今更になって改めて思いました。
公式マニュアルをざっとみてみましたが明確に記載されている箇所は見つけることができなかったので、この内容が実際の試験で出題されるのかは、なんとも言えない気がします...。
[1]でSELECT文をサーバープロセスに送信していますが、その後、共有プールにそれが格納されているかどうかの確認をしています。何故でしょうか。格納されていないからユーザプロセスからSELECT文が送信されているのであって、格納されているのであればユーザプロセスからSELECT文を送信する必要はないと考えています。
そもそも、SQL文がユーザープロセス側からサーバープロセス側に送信されなければ、Oracleデータベース側は何もしませんし、何をしていいかもわかりません。ユーザープロセスからサーバープロセスに対してSQL文が送信されなければ、実行しようとしているSQL文がどのようなものか、サーバープロセスは知ることができません。ですので、共有プールにキャッシュされているSQL文と一致するかも確認しようがありません。
ユーザープロセスは、クライアントPC上で起動したSQLPlusのようなクライアントアプリケーションによって、クライアントPC側に生成されます。サーバープロセスは、サーバーマシン側に生成され(厳密にはリスナープロセスによって生成される)、ユーザープロセスからの処理要求を受け付けて、実際のSQL実行などを行います。
※1台のマシンにOracleデータベースがインストールされており、同マシン上でSQLPlusのようなクライアントアプリケーションを実行する場合でも、動きは同様です。
サーバープロセスがユーザープロセスからSQL文を受け取った後に、はじめて、その受け取ったSQL文と一致するSQL文が共有プールにあるかどうかを確認することができます。
質問の意図を理解できておらず、的外れな返答となっていたらすみません。
この問題の場合は、外部キーにユニーク制約が設定されているため、NULLを格納することも可能です。
解説のこの文章は、参照先のテーブルのカラムには「主キー制約」または「ユニーク制約」が設定されている必要がある、という外部キー制約作成時の条件が前提になっていると思います。(参考: 問題ID35376)
- 外部キー作成時には、参照先のテーブルのカラムに「主キー制約」または「ユニークキー制約」が必要
↓ - この問題では、参照先のテーブルのカラムに「ユニーク制約」が設定されている
↓ - 従って、「customer」テーブルの「addressid」カラムに対して、NULLを格納することも可能
ただ、この問題の解説の文章だけ読むと、もう少し補足があっても良いかなと感じますね。
・セグメントは連続した複数のエクステントで構成される
エクステントは連続した領域に確保されるとは限りません。
この説明文の言いたいことは、「セグメントを構成するエクステントは、連続した領域に確保されるとは限らない」、ということですよね。
※「参考」の以下記述の部分
表領域に複数のデータファイルが割り当てられている場合は、セグメントを構成する個々のエクステントが異なるデータファイル上に格納される場合もあります。つまり、1つのセグメントが複数のデータファイルにまたがる場合もあります。
ですが、この問題の解説の文章だと、若干モヤっとしますね。少し表現を変えてもらえると良さそうですが...。
recovery.conf は PostgreSQL 12で廃止され、postgresql.conf に統合されたようです。
https://www.postgresql.jp/document/14/html/recovery-config.html
本問題の解説にも以下の記載がありました。
PostgreSQL 11 以前のバージョンでは、リカバリに関する設定を「recovery.conf」というファイルを作成して記述していましたが、これらの設定は PostgreSQL 12 から「postgresql.conf」ファイルに統合されました。
OSS-DB Silver Ver.3.0 は PostgreSQL 12 以上を基準としているので、postgresql.conf を用いるという説明は妥当かなと思います。
https://oss-db.jp/outline/silver
この問題の解説に記載のとおり、GENERATED ALWAYS AS IDENTITYが指定されているid列に明示的に値を指定したUPDATEやINSERTはエラーになるので、name=Suzukiのレコードのid列は変更されませんし(3番目のSQL)、id列に3を指定したレコードも追加されない(4番目のSQL)、結果、1番目のSQLと2番目のSQLで挿入された2レコードだけがそのまま残る、ということではないですか?
質問の意図が理解できていなかったらすみません。