rink_rewさんの助け合いフォーラム投稿一覧

助け合いフォーラムの投稿
2024/07/24 返信
MERGE文 入れ替え

「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>

ただし、処理順序(条件を評価する順序)は変わると思うので、実運用においてはデータの内容によっては結果が異なる可能性はあります。
また、パフォーマンスにも違いが出てくる可能性はあると思います。(そのような場合には実行計画の取得などして、チューニングしていくことになると思います。)

2024/07/01 コメント
制御ファイルの多重化の意味について
制御ファイルを多重化しておくことで、一部の制御ファイルが破損してデータベースが起動できなくなった場合でも、正常な制御ファイルをコピーして素早く復旧ができる、という点は推奨されるに値するメリットかなと思います。
2024/07/01 返信
制御ファイルの多重化の意味について

解説の以下の文が多重化の目的の説明になっていると思います。

制御ファイルの多重化の目的は、障害が発生してもシステムを停止させずに運用することではなく、制御ファイルに格納されている情報を保護することにあります。

ただ、破損の仕方にもよると思うのですが、多重化された制御ファイルの1つだけ破損しても、必ずしも即時に停止してしまうとは限らなかったと思います。
例えば、制御ファイル自体が消失(誤って削除)してしまった場合や、制御ファイル自体はOS上のファイルとして依然として存在しているが、バイナリファイルとして中身が不正な状態になってしまった場合など、それぞれ挙動はちょっと違ったような気がします。
Bronze試験の範囲としてこの辺について問われる問題が出題されるかはわかりませんが、もう少し正確に言うと「破損した制御ファイルにアクセスするような操作が実行されると停止する」という感じでしょうか。

※今の試験体系ではなく古いバージョンでの話ですが、Gold試験では、バックアップからのリストア・リカバリ関連の問題は結構出題されていたような記憶があります。

2024/06/27 返信
最小値?

この問題の副問合せ(SELECT MAX(salary) / 2 FROM employees GROUP BY department_id)は、複数行を返す可能性があります。
「ALL」は「リスト内の全ての値が条件を満たす場合TRUE」です。この問題では「<ALL」が使用されているので、「左辺の値(部署の平均給与)が、右辺の値(全ての部署の最高給与の半分)より少ないもの」が結果として返されます。

「全ての値より少ない」は「最小値より少ない」に言い換えられると思います。

2024/06/24 返信
オプションにハイフンが漏れている

誤答として「その効果の中身で迷わせたい」のだろうと思いますし、「-E」が本来意図した選択肢の記述でしょうね。

2024/06/17 返信
GROUP BY句とHAVING句は入れ替えができるというのは正しいか

私も個人的には GROUP BY 句が先にくるイメージでしたが、気になったので19cや21cのマニュアルも確認してみたところ、やはり同様に「どちらの順序でも指定できます」と記載されていますね。勉強になりました。

2024/05/17 コメント
「Oracle Database 12cで利用可能なメモリー管理方法の説明」について
> ⇒確かにそのような説明がありますね。 > 前提としてこの説明欄の内容は各メモリ管理方法が有効になっているという場合という理解でよろしいでしょうか。 はい、そのように考えて良いと思います。 この表の「説明」列には、その設定を有効にする方法(どのパラメータを設定するか)と、有効にした場合の挙動、が書かれています。
2024/05/15 返信
「Oracle Database 12cで利用可能なメモリー管理方法の説明」について

ご提示のURLに私はアクセスできなかったので、どの図のことはわからないのですが、もし、メモリー管理方法として4つ列挙されている表のことでしたら、「説明」の列に※PGAは自動PGAメモリー管理となると記載があるので、その部分ですかね。
うろ覚えですが、以前にどこかの書籍かマニュアル・ドキュメント類で「自動共有メモリー管理を有効にすると、自動PGAメモリー管理が暗黙的に有効になる」みたいな記載があったような気がしますが、ちょっと正確に覚えてません。※私が取得したのは古いバージョンのOracle Masterなので、すみません。

この表現の意味するところは、おそらく、初期化パラメータとしてPGA_AGGREGATE_TARGETが自動的に設定されるわけではないが、V$PARAMETERビューやEnterprise Manager上は表示される、というような意味で「暗黙的」とされていたのかなと、今更になって改めて思いました。
公式マニュアルをざっとみてみましたが明確に記載されている箇所は見つけることができなかったので、この内容が実際の試験で出題されるのかは、なんとも言えない気がします...。

2024/05/14 コメント
SELECT文の実行時の処理の流れについて
別の問題ですが、問題ID:29541にSGAや共有プールの解説がありましたので、こちらも参照してみると良いかもしれません。 ▼問題ID: 29541 ---------------------------------------- [共有プール] 共有プールは、実行されたSQLやその解析結果、データ・ディクショナリ(データベースに関する様々な管理情報が格納された読取り専用の表)の情報などを保持する領域です。 Oracle Databaseでは、SQL文を実行する際、構文に誤りはないか、指定された表が存在するか、アクセス権はあるか等、SQL文の解析作業を行いますが、解析作業にはそれなりのCPUリソースを消費します。そこで、SQL文の解析結果を共有プールにキャッシュし、次に同じSQL文が実行される際に共有プールから情報を取り出し、処理の高速化や、リソースの浪費を防ぐために使用されます。共有プールのサイズを増やせば、より多くのSQL文をキャッシュできます。 なお、共有プールの情報は他のユーザーと共有されます。 ----------------------------------------
2024/05/14 コメント
SELECT文の実行時の処理の流れについて
> 「受け取ったSQL文」というのはその前の文章にある(「サーバープロセスがユーザープロセスからSQL文を受け取った後」)サーバープロセス側が受け取るSQLを指していると思いますが、 はい、ご認識の通りです。 > 「一致するSQL文」というのは一体いつから共有プールに存在しているのでしょうか。 「一致するSQL文」は、過去に実行されたSQL文のことをさしています。Oracleデータベースでは、一度実行されたSQL文やその解析結果の情報が、SGAの共有プール内に保持され、将来、同一のSQL文がユーザープロセスから発行された場合に、この共有プール内に「過去に実行されて解析済みのSQLの情報があるか」を確認します。 これらは、共有プールのサイズが不足すると古いものから削除されていきます。※パラメータの設定などで多少挙動の変更は可能。
2024/05/12 返信
SELECT文の実行時の処理の流れについて

[1]でSELECT文をサーバープロセスに送信していますが、その後、共有プールにそれが格納されているかどうかの確認をしています。何故でしょうか。格納されていないからユーザプロセスからSELECT文が送信されているのであって、格納されているのであればユーザプロセスからSELECT文を送信する必要はないと考えています。

そもそも、SQL文がユーザープロセス側からサーバープロセス側に送信されなければ、Oracleデータベース側は何もしませんし、何をしていいかもわかりません。ユーザープロセスからサーバープロセスに対してSQL文が送信されなければ、実行しようとしているSQL文がどのようなものか、サーバープロセスは知ることができません。ですので、共有プールにキャッシュされているSQL文と一致するかも確認しようがありません。

ユーザープロセスは、クライアントPC上で起動したSQLPlusのようなクライアントアプリケーションによって、クライアントPC側に生成されます。サーバープロセスは、サーバーマシン側に生成され(厳密にはリスナープロセスによって生成される)、ユーザープロセスからの処理要求を受け付けて、実際のSQL実行などを行います。
※1台のマシンにOracleデータベースがインストールされており、同マシン上でSQL
Plusのようなクライアントアプリケーションを実行する場合でも、動きは同様です。

サーバープロセスがユーザープロセスからSQL文を受け取った後に、はじめて、その受け取ったSQL文と一致するSQL文が共有プールにあるかどうかを確認することができます。

質問の意図を理解できておらず、的外れな返答となっていたらすみません。

2024/04/30 返信
解説について

この問題の場合は、外部キーにユニーク制約が設定されているため、NULLを格納することも可能です。

解説のこの文章は、参照先のテーブルのカラムには「主キー制約」または「ユニーク制約」が設定されている必要がある、という外部キー制約作成時の条件が前提になっていると思います。(参考: 問題ID35376)

  • 外部キー作成時には、参照先のテーブルのカラムに「主キー制約」または「ユニークキー制約」が必要
  • この問題では、参照先のテーブルのカラムに「ユニーク制約」が設定されている
  • 従って、「customer」テーブルの「addressid」カラムに対して、NULLを格納することも可能

ただ、この問題の解説の文章だけ読むと、もう少し補足があっても良いかなと感じますね。

2024/04/15 コメント
選択肢の説明の意味がよくわかりません
良いと思います。 データファイルAに存在するエクステントと、データファイルBに存在するエクステントの2つのエクステントから構成される1つのセグメントが存在し得るということです。(本問題の参考の[エクステント]の説明にある図の「表Bのエクステント」が、そのケースを示しています)
2024/04/15 返信
選択肢の説明の意味がよくわかりません

・セグメントは連続した複数のエクステントで構成される
エクステントは連続した領域に確保されるとは限りません。

この説明文の言いたいことは、「セグメントを構成するエクステントは、連続した領域に確保されるとは限らない」、ということですよね。
※「参考」の以下記述の部分

表領域に複数のデータファイルが割り当てられている場合は、セグメントを構成する個々のエクステントが異なるデータファイル上に格納される場合もあります。つまり、1つのセグメントが複数のデータファイルにまたがる場合もあります。

ですが、この問題の解説の文章だと、若干モヤっとしますね。少し表現を変えてもらえると良さそうですが...。

2024/03/21 返信
解説文について

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

2024/03/12 返信
GENERATED ALWAYS AS IDENTITY が指定された列の値をUPDATEしたときの挙動について

この問題の解説に記載のとおり、GENERATED ALWAYS AS IDENTITYが指定されているid列に明示的に値を指定したUPDATEやINSERTはエラーになるので、name=Suzukiのレコードのid列は変更されませんし(3番目のSQL)、id列に3を指定したレコードも追加されない(4番目のSQL)、結果、1番目のSQLと2番目のSQLで挿入された2レコードだけがそのまま残る、ということではないですか?

質問の意図が理解できていなかったらすみません。

2024/03/12 返信
DESCの後の数字について

下記の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も項目ごとに指定できます。
2024/03/08 返信
解答が間違い

何件表示されるかとの問いに対し、

問題文で「何件表示されるか」とは書かれてないですね。

問題文は「以下のSQLを実行した場合、取得されるデータとして正しいものは?」と書かれていて、countの結果5件のデータが取得されているので、選択肢として「5件」で良いのではないでしょうか。
もし、「以下のSQLを実行した場合、出力される値は?」のような問題文であれば、選択肢は「5」のように「件」がついていない方が適切だと思いますが。

2024/03/05 コメント
試験当日のメモ用紙について
ちょっと調べてみたところ、以下のブログの方が2022年ごろにBronze DBAを受験されて、同じようなアイテムを配布されたようです。 https://note.com/bakuzensan/n/n1e304abc70f1
2024/03/05 返信
試験当日のメモ用紙について

少し古い情報にはなりますが、私が受験した際にはテストセンターで受付済ませて試験を受ける部屋に入室する前に、厚紙をラミネートしたようなペラペラのホワイトボード代わりのシートと黒のマーカーが配布されました。

2024/02/26 返信
NULLIF関数の挙動について

他の設問ですが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行が選択されました。
2024/02/21 返信
TO_NUMBER関数がエラーになる

この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
2024/02/21 返信
自己結合にUSING句が使用できない理由

すでに実際に試されているとおり、自己結合の場合に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: ここでは修飾された列名は使用できません。
2024/02/13 返信
Employeesテーブルのデータについて

これは、上司の人は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の試験問題で、どのような出題がされるかはなんとも言えないところですが...。

2024/02/13 返信
×である選択肢が誤りである理由

②は理由が分かりませんでした
(¥を記載したため?,文字として¥を記載するのはエラーにならないと思ったのですが…)

そうですね。第一引数の文字列として¥が含まれていること自体は問題ないので、エラーにもなりませんが、出力結果は期待したものにはなりません。

実際に実行してみると、出力結果は以下のとおり「500000」が出力されます。
TO_NUMBERはNUMBERに変換するので、出力結果として桁区切りのカンマや通貨記号は含まれません。
※第二引数で指定したフォーマットは、第一引数の文字列を数値に変換するにあたり、どう解釈すれば良いかの指定。

SQL> SELECT TO_NUMBER('¥500,000.0', 'L999G999D0') FROM dual;

TO_NUMBER('¥500,000.0','L999G999D0')
------------------------------------
			      500000

下記問題が×である理由の説明が記載されていないため、ご教授いただきたいです

Ping-tさんの問題集はたいてい不正解の選択肢についても説明が載ってるような気がするのですが、確かにこの問題にはないですね...なんででしょう...。

戻る