rink_rewさんの助け合いフォーラム投稿一覧
メディア・リカバリの流れが、
- バックアップファイルをリストア
- リストアしたファイルに対して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レコードだけがそのまま残る、ということではないですか?
質問の意図が理解できていなかったらすみません。
下記のDESCの後に表示されている「1」は何をあらわしているのでしょうか。
これは、ORDER BY 句における項目の指定方法で、列名や列別名以外に、SELECT句で指定した項目の順番を数値で指定することができるというものです。
DESCの後の数字というか、DESCはその前の数字にかかっています。
SELECT employee_name, salary, grade FROM employees, grade
WHERE salary = (SELECT MAX(salary) FROM employees)
AND salary BETWEEN low AND high
ORDER BY 3, 2 DESC, 1
この例だと、まず最初に「3」(grade)で昇順にソート、次に「2」(salary)で降順にソート、最後に「1」(employee_name)で昇順にソート、という動きになります。
※ORDER BY句のデフォルトが昇順で、ASCは省略可能、降順にしたい場合はDESCを指定する。
ORDER BY句に着目した別の問題(26443)に、以下の説明がありました。
ORDER BY句の項目には「列名」の他、以下を指定できます。どれも重要です。
・列別名(*WHERE句では指定不可)
・算術式
・SELECT句に指定されている項目の順番(数値)
ASCとDESCは昇順/降順を指定するキーワードです。ASCで昇順(小さい順)、DESCで降順(大きい順)にソートします。省略するとASCが指定されたものとみなされます。
ORDER BY句では複数の項目を指定できますが、ASC/DESCも項目ごとに指定できます。
何件表示されるかとの問いに対し、
問題文で「何件表示されるか」とは書かれてないですね。
問題文は「以下のSQLを実行した場合、取得されるデータとして正しいものは?」と書かれていて、countの結果5件のデータが取得されているので、選択肢として「5件」で良いのではないでしょうか。
もし、「以下のSQLを実行した場合、出力される値は?」のような問題文であれば、選択肢は「5」のように「件」がついていない方が適切だと思いますが。
少し古い情報にはなりますが、私が受験した際にはテストセンターで受付済ませて試験を受ける部屋に入室する前に、厚紙をラミネートしたようなペラペラのホワイトボード代わりのシートと黒のマーカーが配布されました。
他の設問ですが26677の参考のNULLIF関数の説明部分に以下の記載がありました。
なお、第1引数にはリテラルのNULL値以外の値を指定しなければなりません。
上記のように第1引数にリテラルのNULL値は指定できませんが、第1引数で指定した列の値などが結果としてNULL値となる場合は問題ありません。
第1引数が結果としてNULL値となる場合は、第2引数がいかなる値であっても、NULL値が返されます。(第2引数がNULL値であれば等しいのでNULL値、第2引数がNULL値以外であれば等しくないので第1引数のNULL値が返される為)
実際にsalary列にnullが含まれるデータで、選択肢のSQLを実行した場合エラーにはなりません。
NULLIF関数の結果としてnullが返され、DECODE関数の条件と一致して、結果、「-」として表示されます。
SQL> select employee_id, employee_name, salary from employees where salary is NULL;
EMPLOYEE_ID EMPLOYEE_NAME SALARY
----------- -------------------- ----------
1017 渡辺和也
1018 塚本孝
1019 野口圭子
SQL> select employee_id, employee_name, NULLIF(salary, 500000) from employees where salary is NULL;
EMPLOYEE_ID EMPLOYEE_NAME NULLIF(SALARY,500000)
----------- -------------------- ---------------------
1017 渡辺和也
1018 塚本孝
1019 野口圭子
SQL> SELECT employee_id, employee_name, DECODE(NULLIF(salary, 500000), NULL, '-', salary) sal FROM employees;
EMPLOYEE_ID EMPLOYEE_NAME SAL
----------- -------------------- -------------------------
1001 山田二郎 -
1002 佐藤昭夫 -
1003 山口洋子 -
1004 田中浩介 -
1005 加藤昭彦 -
1006 佐々木明子 800000
1007 菊池浩二 800000
1008 中山大輔 400000
1009 星野健一 400000
1010 斎藤京子 400000
1011 吉田亜希 400000
1012 阿部伊吹 400000
1013 米村真司 350000
1014 伊藤佳奈 300000
1015 橋本淳 300000
1016 井上悦子 200000
1017 渡辺和也 -
1018 塚本孝 -
1019 野口圭子 -
1020 内田雄介 200000
1021 高田明 200000
1022 坂本真 200000
22行が選択されました。
このSQL文自体には特段問題はなく、言語環境の問題だと思います。
私はUTF8環境ですが、解説と同じ出力結果でした。
※検証用データの提供ページに「DBのキャラクタセットは「Unicode(AL32UTF8)」を想定」と記載されていたのでそれに従っていました。
問題文の冒頭で「実行環境は日本語とする」と言及しているのは、通貨記号「¥」が含まれているからですかね。
SQL> !echo $NLS_LANG
Japanese_Japan.AL32UTF8
SQL> select parameter, value from NLS_DATABASE_PARAMETERS where parameter = 'NLS_CHARACTERSET';
PARAMETER VALUE
-------------------- --------------------
NLS_CHARACTERSET AL32UTF8
SQL> SELECT TO_NUMBER('¥500,000.0', 'L999G999D0') FROM dual;
TO_NUMBER('¥500,000.0','L999G999D0')
------------------------------------
500000
試しに英語に変えてみると、ORA-01722のエラー(「数値が無効です」のエラー)が発生しました。
通過記号「¥」が一致しなくなるためだと思います。
SQL> !echo $NLS_LANG
American_America.WE8MSWIN1252
SQL> SELECT TO_NUMBER('¥500,000.0', 'L999G999D0') FROM dual;
SELECT TO_NUMBER('¥500,000.0', 'L999G999D0') FROM dual
*
ERROR at line 1:
ORA-01722: invalid number
余談ですが、「$」などとすればエラーは発生しません。
SQL> !echo $NLS_LANG
American_America.WE8MSWIN1252
SQL> SELECT TO_NUMBER('$500,000.0', 'L999G999D0') FROM dual;
TO_NUMBER('$500,000.0','L999G999D0')
------------------------------------
500000