rink_rewさんの助け合いフォーラム投稿一覧
「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
すでに実際に試されているとおり、自己結合の場合にUSING句を使用してもエラーにはなりませんよね。
・USING句に結合条件を指定する
USING句は同じ名前の列のみを結合することができます。自己結合の実行例のように結合列に表接頭辞(表別名)を使用できないので、誤りです。
おそらくこの解説文で言いたいのは、USING句を用いる場合で「結合条件としての結合列に表接頭辞(表別名)を使用できない」ということだと思いますが、自己結合のクエリでUSING句に結合条件を指定する(表接頭辞を含まない列名を指定する)こと自体は不可能ではないので、この問題の選択肢として「USING句に結合条件を指定する」が「正しくない」とは言えないですよね。問題の修正をお願いしたいところです。
SQL> SELECT emp.employee_name, mgr.employee_name FROM employees emp JOIN employees mgr USING(emp.manager_id);
SELECT emp.employee_name, mgr.employee_name FROM employees emp JOIN employees mgr USING(emp.manager_id)
*
行1でエラーが発生しました。:
ORA-01748: ここでは修飾された列名は使用できません。
これは、上司の人はmanager_idを持たず、上司のいる従業員のmanager_id列に上司のemployee_idが入るという認識で合ってますでしょうか。
そうですね。その理解で良いと思います。
前提として「manager_id列に値が入っているレコードは、上司がいることを意味する」と判断しておく必要はありますが、実際の表データは見なくても問題は解けるかなと思います。
以下の2つの選択肢は構文エラーになるので除外。
・SELECT emp.employee_name, mgr.employee_name FROM employees emp NATURAL JOIN employees mgr;
・SELECT employee_name, mgr.employee_name FROM employees JOIN employees mgr ON manager_id = mgr.employee_id;
以下の選択肢は、同じ名前が表示されるだけなので、期待する結果(従業員名とその上司の氏名)にはならないと判断できる。
・SELECT emp.employee_name, mgr.employee_name FROM employees emp JOIN employees mgr USING (employee_id);
そして残りの2つについては、manager_id列に値を持つemployee_nameと、そのmanger_idに該当するemployee_nameが表示されるので、本設問で期待されている「従業員名とその上司の氏名」(と思われるもの)が表示されるので正答である、と判断はできないことはないかなと思いました。
・SELECT emp.employee_name, mgr.employee_name FROM employees emp, employees mgr WHERE emp.manager_id = mgr.employee_id;
・SELECT emp.employee_name, mgr.employee_name FROM employees emp JOIN employees mgr ON emp.manager_id = mgr.employee_id;
もし、運営さんに修正してもらうとしたら、「manager_id列に値が入ってるレコードは、その従業員に上司がいることを意味する」のような補足を問題文に追記してもらうぐらいでしょうか。
実際のSilver SQL 2019の試験問題で、どのような出題がされるかはなんとも言えないところですが...。
②は理由が分かりませんでした
(¥を記載したため?,文字として¥を記載するのはエラーにならないと思ったのですが…)
そうですね。第一引数の文字列として¥が含まれていること自体は問題ないので、エラーにもなりませんが、出力結果は期待したものにはなりません。
実際に実行してみると、出力結果は以下のとおり「500000」が出力されます。
TO_NUMBERはNUMBERに変換するので、出力結果として桁区切りのカンマや通貨記号は含まれません。
※第二引数で指定したフォーマットは、第一引数の文字列を数値に変換するにあたり、どう解釈すれば良いかの指定。
SQL> SELECT TO_NUMBER('¥500,000.0', 'L999G999D0') FROM dual;
TO_NUMBER('¥500,000.0','L999G999D0')
------------------------------------
500000
下記問題が×である理由の説明が記載されていないため、ご教授いただきたいです
Ping-tさんの問題集はたいてい不正解の選択肢についても説明が載ってるような気がするのですが、確かにこの問題にはないですね...なんででしょう...。