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

助け合いフォーラムの投稿
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さんの問題集はたいてい不正解の選択肢についても説明が載ってるような気がするのですが、確かにこの問題にはないですね...なんででしょう...。

2024/01/30 返信
シーケンスの欠番について

コミットだけでは飛ばされないと思います。共有プールがクリアされたりすれば、欠番が発生することになると思いますが。

SQL> create sequence seq01 cache 20;

順序が作成されました。

SQL> select seq01.nextval from dual;

   NEXTVAL
----------
	 1

SQL> select sequence_name, last_number from dba_sequences where sequence_name = 'SEQ01';

SEQUENCE_NAME	     LAST_NUMBER
-------------------- -----------
SEQ01			      21

SQL> select seq01.nextval from dual;

   NEXTVAL
----------
	 2

SQL> commit;

コミットが完了しました。

SQL> select seq01.nextval from dual;

   NEXTVAL
----------
	 3

SQL>
2024/01/29 返信
WHERE yomi = '' について

''(空文字/長さ0の文字値)はNULLとして扱われるので、

  • =での比較はできない (結果がUNKNOWNとなる)
  • NULLを検索したければ、IS NULL / IS NOT NULL を使用しなければならない。

ということですね。「WHERE yomi = ''」では、NULLを=で検索することになります。

確かにOracleのNULLの扱いはクセがあると言えるかもしれませんが、参考URLに記載のマニュアルに以下のとおり記載されてますので。

NULLを検査するには、比較条件IS NULLおよびIS NOT NULLのみを使用します。NULLを他の条件で使用して、その結果がNULLの値に依存する場合、結果はUNKNOWNになります。
SELECT文のWHERE句でUNKNOWNと評価される条件が使用された場合、その問合せに対して行は戻されません。

2024/01/29 返信
85%以上がnullの場合でもこの式は成立しますか?

成立しますね。SELECT文のとおり、並び替えられた上で上位15%(この問題の例であれば4行)が返されます。
ping-tさん提供のサンプルデータで、salaryの85%をnullにして試した結果は以下のとおりです。

SQL> SELECT employee_id, employee_name, salary FROM employees ORDER BY salary DESC NULLS LAST;

EMPLOYEE_ID EMPLOYEE_NAME		       SALARY
----------- ------------------------------ ----------
       1003 山口洋子                           500000
       1002 佐藤昭夫                           500000
       1001 山田二郎                           500000
       1007 菊池浩二
       1008 中山大輔
       1009 星野健一
(中略)

22行が選択されました。

SQL> SELECT employee_id, employee_name, salary FROM employees ORDER BY salary DESC NULLS LAST FETCH FIRST 15 PERCENT ROWS ONLY;

EMPLOYEE_ID EMPLOYEE_NAME		       SALARY
----------- ------------------------------ ----------
       1003 山口洋子                           500000
       1002 佐藤昭夫                           500000
       1001 山田二郎                           500000
       1007 菊池浩二

2024/01/24 返信
馬鹿な私を助けてください。

RPADやLPADの第2引数は「表示される全体の長さ」で、第1引数の文字列の長さが第2引数で指定された長さよりも長い場合には、第2引数で指定された長さまでのみ表示され、残りは切り捨てられます。

SUBSTR(cust_postal_code, INSTR(cust_postal_code, '-'))
→ 「-0063」※長さ 5

LENGTH(cust_postal_code) - INSTR(cust_postal_code, '-')
→ 8 - 4 = 4

第一引数の文字列の長さ「5」、第2引数で指定された長さ「4」で、第一引数の方が長いため、RPADの結果は長さ4まで(「-0063」のうち「-006」まで)が表示されることになります。

参考URLのマニュアルだと、以下の部分ですね。

expr1がnより長い場合、このファンクションはnに収まるexpr1の一部を戻します。

あと、この問題の解説には書いてなかったのですが、他の問題(ID:26812)の解説に以下の記述がありました。

RPAD関数やLPAD関数の引数に指定された文字列が、長さで指定されたサイズよりも長い場合、次のように指定されたサイズ分の文字列が表示されます。

2024/01/24 返信
シーケンスの参照について

ping-tさん提供の検証用データがあります。スクリプト形式で提供されているので、問題集で実行されているSQLはすぐに試せますよ。
https://ping-t.notion.site/Ping-t-Silver-SQL-6f833fb434994343bcc338233e058bb2

本件も、実際に実行してみれば一発でわかります。

SQL> CREATE SEQUENCE seq_id MAXVALUE 100;

順序が作成されました。

SQL> CREATE TABLE list (id NUMBER(3) DEFAULT seq_id.NEXTVAL PRIMARY KEY, name VARCHAR2(10));

表が作成されました。

SQL> GRANT SELECT, INSERT ON list TO userA;

権限付与が成功しました。

SQL> conn userA
パスワードを入力してください:

接続されました。
SQL> SELECT * FROM pingt.list;

レコードが選択されませんでした。

SQL> INSERT INTO pingt.list (name) VALUES ('Sato');
INSERT INTO pingt.list (name) VALUES ('Sato')
        *
行1でエラーが発生しました。:
ORA-01031: 権限が不足しています

SQL> conn pingt
パスワードを入力してください:
接続されました。
SQL> GRANT SELECT ON pingt.SEQ_ID to userA;

権限付与が成功しました。

SQL> conn userA
パスワードを入力してください:

接続されました。
SQL> INSERT INTO pingt.list (name) VALUES ('Sato');

1行が作成されました。

SQL> SELECT * FROM pingt.list;

	ID NAME
---------- ----------
	 1 Sato

SQL>
2024/01/12 返信
+ 12/24の形式について

同じ結果になります。実務的には、時なら1/24、分なら1/1440の表記を使うことが多いような気がします。パッと見て分かりやすいので。

SQL> select to_date('12-01-01') from dual;

TO_DATE('12-01-01
-----------------
12-01-01 00:00:00

SQL> select to_date('12-01-01') +12/24 from dual;

TO_DATE('12-01-01
-----------------
12-01-01 12:00:00

SQL> select to_date('12-01-01') +1/2 from dual;

TO_DATE('12-01-01
-----------------
12-01-01 12:00:00
戻る