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

助け合いフォーラムの投稿
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
2024/01/06 返信
WITH CHECK OPTION

過去にも同じ質問があったようです。
https://mondai.ping-t.com/g/posts/603

INSERT時は範囲外の値をセットすると「範囲外の値は入力できない(エラー)」となりますが、UPDATE時は更新指示自体がエラーになるのではなく「処理を実行した結果0件でした」となるのだよ、という違いですね。_

ちなみに、ping-tさん提供のテストデータで実際に実行してみた結果は以下のとおりです。

SQL> select * from v_emp;

DEPARTMENT_ID EMPLOYEE_ID EMPLOYEE_NAME 		     SALARY
------------- ----------- ------------------------------ ----------
            1        1001 山田二郎                           500000
            1        1008 中山大輔                           400000
            1        1013 米村真司                           350000

SQL> UPDATE v_emp SET salary = 500000 WHERE department_id = 3;

0行が更新されました。

SQL> select * from v_emp;

DEPARTMENT_ID EMPLOYEE_ID EMPLOYEE_NAME 		     SALARY
------------- ----------- ------------------------------ ----------
            1        1001 山田二郎                           500000
            1        1008 中山大輔                           400000
            1        1013 米村真司                           350000

SQL>
2023/12/28 返信
ブロンズDBA後のシルバーDBA

私は新体系の試験にはあまり詳しくないのですが、以下のサイトで試験範囲の比較情報が出ておりました。

[FAQ] 新Silver DBAとSilver SQLのどちらを受験すべきか?
https://cosol.jp/techdb/2022/06/faq_new_oracle_master_silver_dba_silver_sql_2/

何割程度被るかということはわかりませんが、こちらをみる限りでは、Silver SQLの知識をもっていればSilver DBAの「SQL範囲」はカバーできそうですので、もしSilver SQLの学習から日が経ってしまい内容を忘れてしまったという場合には、Silver SQLの復習をすれば良さそうです。

また、同じブログにて以下のような記事もあがっていました。

[FAQ] 新Bronze DBAと新Silver DBAのどちらから受験すべきか?
https://cosol.jp/techdb/2022/06/faq_new_oracle_master_bronze_dba_silver_dba/

Bronze DBA合格している方であれば、Silver DBAの学習にもスムーズに入っていけそうなことが書かれていますので、もし、実務でOracle Databaseまたはその他データベースに日々触れているという状況でない場合には、せっかくなのでBronze DBAの知識を忘れてしまう前に、一気にSilver DBAまでやり切ってしまうのもアリかもしれませんね。

2023/12/24 コメント
2023/12/21 返信
新たにファイルを加える場合正解手順は一体どちです

どちらの手順も、結果としてやっていることは同じだと思います。

Ping-tの説明では、最初に ALTER SYSTEM 文で初期化パラメータ「CONTROL_FILE」を編集していますが、解説にも記載のとおり「CONTROL_FILE」は静的パラメータなので、SCOPE=SPFILEを指定して、spfileだけを変更しています。
つまり、この時点で稼働中のインスタンスには何の影響もありません。変更内容が反映されるのは、次回の起動時です。

重要なのは、制御ファイルをコピーするタイミングで、これについてはping-tの手順でも公式ドキュメントの手順でも、インスタンスが停止した状態で、OSコマンドで制御ファイルのコピーを行っています。あとは、起動すれば初期化パラメータ「CONTROL_FILE」の変更内容も反映されます。

2023/12/17 返信
選択肢が2つ?

Ping-tさん提供の検証用データで試してみましたが、結果は以下の通りエラーとはなりませんでした。

SQL> SELECT employee_id, employee_name, salary FROM employees WHERE department_id IN (SELECT department_id FROM departments WHERE department_name = '開発') OR salary >ANY (SELECT MIN(AVG(salary)) FROM employees GROUP BY department_id);

EMPLOYEE_ID EMPLOYEE_NAME		       SALARY
----------- ------------------------------ ----------
       1001 山田二郎                           500000
       1002 佐藤昭夫                           500000
       1003 山口洋子                           500000
       1004 田中浩介                           500000
       1005 加藤昭彦                           500000
       1006 佐々木明子                         800000
       1007 菊池浩二                           800000
       1008 中山大輔                           400000
       1009 星野健一                           400000
       1010 斎藤京子                           400000
       1011 吉田亜希                           400000

EMPLOYEE_ID EMPLOYEE_NAME		       SALARY
----------- ------------------------------ ----------
       1012 阿部伊吹                           400000
       1015 橋本淳                             300000

13行が選択されました。

SQL>

参考までに、以下は整形したSQL文ですが、特に余計な括弧はなさそうです

SELECT
    employee_id,
    employee_name,
    salary
FROM
    employees
WHERE
    department_id IN (
        SELECT
            department_id
        FROM
            departments
        WHERE
            department_name = '開発'
    )
    OR salary > ANY (
        SELECT
            MIN(AVG(salary))
        FROM
            employees
        GROUP BY
            department_id
    );
2023/12/12 返信
ディフォルト値とはそもそも何ですか?

何故ビューの列にデフォルト値を設定できないのかが分かりません。

この問題の解説部分にも記載の構文の通り、そもそも CREATE VIEW で ビュー名の直後に記述できる列名は、あくまでもビューで使用する列名(列の別名)というだけなので、DEFAULT値云々は元のテーブル側での話となります。

したがって、1番目のSQL文は構文エラーになるため、選択肢「1番目はEMP_VIEWビューの列にデフォルト値を設定できないのでエラーとなる」は正になるかなと思います。

私は古いバージョンのOracle Masterしか持っておらず、実際にこのような問題が実際のBronze DBA 2019試験で出題されるかどうかまではわからないのですが、Ping-tさんの合格体験記などをみてみると、合格された方々の感触として実試験の難易度は黒本よりは高いと言えそうですので、余力があれば、今回の問題についても解説や参考に記載の内容は覚えておいて損はないかもしれません。

2023/12/12 返信
ディフォルト値とはそもそも何ですか?

Oracle Master Bronze DBA 2019 は DBA カテゴリの試験なので、あまり突っ込んだSQL文が出題されることはないのではないかな、とは思いますが、「デフォルト値」については「表」に関する問題の参考部分に以下の記述がありましたので、参考までに。

【表の作成】
*SQL文での表の作成
CREATE TABLE文を使用します。

 CREATE TABLE [スキーマ名.]表名
  (列名 データ型(サイズ) [DEFAULT デフォルト値] [[CONSTRAINT 制約名] 制約タイプ]
   [, 列名 データ型(サイズ)...]
  ) [TABLESPACE 表領域名];

・DEFAULT
行の挿入時に値が指定されていない場合のデフォルト値を指定します。

CREATE TABLE で表を作成する際に、カラムに「DEFAULT」句を指定することで、デフォルト値を設定できます。
INSERT文でデータを挿入する際に、そのカラムに対して値を指定しなかった場合に、設定したデフォルト値が割り当てられる、というものです。

2023/12/04 返信
回答の選択肢について

解説にも記載されている「マルチアタッチ」を想定した選択肢なのかなと思いました。

(※)一部のボリュームタイプでは複数インスタンスからのアタッチが可能な「マルチアタッチ」機能に対応しています。ただし、利用できるインスタンスタイプやリージョンが限られているなどの制限事項があります。

マルチアタッチは、どのような環境でも使用できるわけではないので、実運用環境としてどのようなユースケースがあるのか微妙なところではありますが、以下のように公式情報でも同時にアタッチできることが述べられているので、「1つのEBSボリュームは1つのEC2インスタンスからしかアタッチできない」と言いきってしまうと嘘になってしまいます。

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-volumes-multi.html
https://aws.amazon.com/jp/about-aws/whats-new/2020/02/ebs-multi-attach-available-provisioned-iops-ssd-volumes/

ですので、設問の選択肢としては妥当かなと思いました。

2023/12/04 返信
後どの位、学習したら良いでしょうか?

周回を重ねるごとに正答率が上がってるのはとても良い状況だとおもいます。
3週目以降、間違えた問題のみ集中して解いて復習し、間違える問題がなくなってきたら仕上げに再度全問を通してみると良いかもしれません。
模試は80%程度は取れるようにはしておいた方が当日安心だと思いますので、時間の許す限り周回を繰り返すと良いかなと思います。
最後の仕上げ、頑張ってください。

2023/11/24 返信
スキーマと領域の違いについて

概ねご認識の通りだと思います。
ただ、物理的か論理的かという話で分けてしまうと、若干誤解があるかもしれません。

領域は物理的なデータを格納する場所で、そこには様々なユーザの実際の表データが格納されている。
一方で、スキーマはユーザごとに論理的にデータを区別するための概念であり実際のデータは領域に格納されている。

表領域は、一つ以上のデータファイルから構成される論理的な領域で、オブジェクトの格納先として指定する場所。(正確には、表や索引の物理的な格納場所はデータファイル)

  • データファイルの概念は、OSレベルで物理的
  • 表領域の概念は、Oracleレベルで論理的

私はこんな感じで理解しております。

2023/10/27 返信
Cが該当する理由を知りたい

解説に記載されている以下内容の通りかなと思います。

WHERE句に条件が複数指定されている場合は、論理演算子の優先順位に従って条件が評価されます。
AND演算子とOR演算子ではAND演算子のほうが先に評価されますが、()括弧がある場合は、括弧内の演算子を優先して評価します。

設問では「(department_id = 3 OR salary > 400000)」の部分が先に評価され、次にANDですので、「DEPARTMENT_ID列が3かSALARY列が400000より大きく、かつCOMMISSION列が1200000以下である」列(E)、または、「HIREDATE列が2008年4月1日より大きい(新しい)」列(B,C)が検索されます。

実際に実行すると、確かに「C」のレコードは表示されます。

SQL> select department_id, salary, commission, hiredate from employees where (department_id = 3 or salary > 400000) and commission <= 1200000 or hiredate > '2008-04-01';

DEPARTMENT_ID	  SALARY COMMISSION HIREDATE
------------- ---------- ---------- --------
	    3	  400000    1200000 02-12-01
	    5	  400000     800000 10-04-01
	    1	  350000     800000 11-04-01
	    2	  300000     800000 10-04-01
	    3	  300000     800000 09-12-01
	    4	  200000     800000 10-04-01   <--- C
~~~ 以下略 ~~~

記載いただいた以下の内容がChatGPTの回答でしょうか。

提供された行が条件にマッチしない理由は、条件 (department_id = 3 OR salary > 400000) AND commission <= 1200000 OR hiredate > '2008-04-01' に対して、以下の評価結果です

department_id = 4 は条件 (department_id = 3 OR salary > 400000) にマッチしません。
salary > 400000 もマッチしません。
commission <= 1200000 もマッチしません。
hiredate > '2008-04-01' もマッチしません。
以上の理由から、提供された行は条件式全体を満たさないため、マッチしません。条件内で指定されている条件に対して、department_id が 4 であることや他の列の値が具体的な値を持っていることは影響しません。

どのようなプロンプトを投げたかわからないので何とも言えませんが、「C」の選択肢は「hiredate > '2008-04-01'」の条件にマッチすると思います。
私も試しにChatGTPに質問してみました。最後の説明文がわかりやすいかなと感じました。

まず、SQLのWHERE句の条件式の評価の順序を理解する必要があります。AND、OR、NOTなどの論理演算子の優先順位は以下のようになっています:

1. NOT
2. AND
3. OR

上記のSQL文において、WHERE句の条件式は以下のように括弧を使って明確に示されています:

1. (department_id = 3 OR salary > 400000)
2. AND commission <= 1200000
3. OR hiredate > '2008-04-01'

この条件式の評価の順序を考慮すると、次のようなステップで評価されます:

1. 最初に括弧内の条件が評価される。すなわち、department_idが3のレコード、またはsalaryが400000を超えるレコードが該当します。
2. 次に、上記の結果の中からcommissionが1200000以下のレコードが選ばれます。
3. 最後に、hiredateが'2008-04-01'よりも新しいレコードが上記の条件に関係なく選ばれます。

そのため、結果として返されるレコードは以下の3つの条件のいずれかを満たすものになります:

1. department_idが3で、salaryが任意、commissionが1200000以下のレコード。
2. salaryが400000を超え、commissionが1200000以下のレコード。
3. hiredateが'2008-04-01'よりも新しいレコード。

注意点として、OR条件はAND条件よりも優先順位が低いため、上記のSQL文を実行すると、hiredateの条件は他の条件とは独立して評価される点に注意してください。
2023/10/10 返信
実際にインストールしての学習について

環境構築については、Oracle Master Bronze DBA 2019(1Z0-085)のWeb問題集のトップページに、「環境構築手順のご紹介」というリンクがあるので、その内容に従うと良いかもしれません。

あと、VirtualBox上のLinuxにOracle Database 19cを導入する手順について、とても良くまとまったブログ記事がありましたので、参考までに載せておきます。※記事はLinuxにインストールしてますが、インストールイメージのダウンロードからVMの作成、インストーラーのGUI画面も載っていて、ステップバイステップで書かれているので参考になると思います。

VM作成からのOracle 19cインストール手順 前編(Linuxシングル)
https://cosol.jp/techdb/2021/06/oracle19c_setup_1of2/

VM作成からのOracle 19cインストール手順 後編(Linuxシングル)
https://cosol.jp/techdb/2021/06/oracle19c_setup_2of2/

ちなみに、上記のブログでも言及されていますが、学習目的であれば無償版の「Oracle Database Express Edition」を使用する必要はないようです。(OTNライセンス)

私がOracle Masterを取得したのはもう何年も前の話にはなりますが、

  • Oracle Master 教科書(黒本と呼ばれるやつ?)の内容は読み込んでおさえておく。
  • Ping-tのWeb問題集は何周もする。解説や参考も面倒くさがらずに読む。
  • 黒本やWeb問題集の内容については、可能な限り実機でも動きを確認しておく。
    あたりが、自分の学習方法でした。

あと、欲を言えば、黒本やWeb問題集でよく理解できなかった部分などは、Oracleのマニュアルも参照してみるのが良いと思います。
※公式マニュアルは、慣れないうちは読みにくいかもしれませんが、もし将来的に実際の業務でOracle Databaseを使用するようになったら、マニュアルとは嫌でも付き合っていくことになると思うので、その準備も兼ねて慣れておくといいかもしれません。

学習頑張ってください。合格されることを願っております。

2023/10/10 返信
「I/Oの最小単位」とはそもそも何でしょうか

「I/O」については、おっしゃられているとおり「インプット/アウトプット」のことです。つまり、データの読み込み/書き込みを指しています。

この問題の解説や参考に以下の記述があります。

データ・ブロックには通常複数の行データが格納されているため、1行にアクセスしたい場合でも、データ・ブロックに含まれるすべての行データがロードの対象となります。

「I/Oの最小単位」ですので、Oracle Databaseがレコードの読み込みや書き込みを行う際には、データブロック単位で処理をしている、例えば、クライアントから「一行のレコードのみを結果として返すようなSELECT文」が投げられた場合でも、Oracle Databaseは「そのレコードが格納されているデータブロック」を丸ごと読みこみ(つまり複数のレコードを読み込んでいる)、その中の一行だけをクライアントに返すような動きをしています。
※正確にはキャッシュや書き込み遅延の話などがあり、ツッコミどころがあるかもしれませんが、大まかにいえばこういうことです。

すみません、疑問に思われている点に対する回答になっていないかもしれません。

2023/08/29 返信
なぜ逆にすると上司の名前が表示されるのか

ping-tさん提供の検証用データに基づいて、順をおって動きを見てみるとこんな感じでしょうか。

SELECT e.employee_name FROM employees e WHERE EXISTS (SELECT * FROM employees m WHERE e.manager_id = m.employee_id);

  1. employees e の1行を取得
EMPLOYEE_ID EMPLOYEE_NAME		   MANAGER_ID
----------- ------------------------------ ----------
       1001 山田二郎
  1. 副問合せの条件は「e.manager_id = m.employee_id」なので、副問合せで参照している employees m 表から、m.employee_id と e.manager_id が等しい行を取得する。
  • 上の 1. で employees e から取得した山田二郎の manager_id は null。
  • 副問合せで参照している employees m 表の m.employee_id と一致する行がない。
    -> 副問合せから行が返されないので、主問合せの EXISTS 条件は FALSE。この行の e.employee_name は返されない。(出力されない)
  1. employees e の他の1行を取得
EMPLOYEE_ID EMPLOYEE_NAME		   MANAGER_ID
----------- ------------------------------ ----------
       1008 中山大輔                             1001
  1. 副問合せの条件は「e.manager_id = m.employee_id」なので、副問合せで参照している employees m 表から、m.employee_id と e.manager_id が等しい行を取得する。
  • 上の 3. で employees e から取得した中山大輔の manager_id は 1001。
  • 副問合せで参照している employees m 表の m.employee_id と一致する行(山田二郎)がある。
    -> 副問合せから行が返されるので、主問合せの EXISTS 条件は TRUE。この行の e.employee_name は返される。(出力される)

=> 結果として、employees 表 の manager_id 列に、同表内に存在する employee_id の値を持つ行(上司のいる従業員)が返される。


SELECT m.employee_name FROM employees m WHERE EXISTS (SELECT * FROM employees e WHERE e.manager_id = m.employee_id);

  1. employees m の1行を取得
EMPLOYEE_ID EMPLOYEE_NAME		   MANAGER_ID
----------- ------------------------------ ----------
       1001 山田二郎
  1. 副問合せの条件は「e.manager_id = m.employee_id」なので、副問合せで参照している employees e 表から、m.employee_id と e.manager_id が等しい行を取得する。
  • 上の 1. で employees m から取得した山田二郎の employee_id は 1001。
  • 副問合せで参照している employees e 表の e.manager_id と一致する行(中山大輔、米村真司、等)がある
    -> 副問合せから行が返されるので、主問合せの EXISTS 条件は TRUE。この行の m.employee_name は返される。(出力される)
  1. employees e の他の1行を取得
EMPLOYEE_ID EMPLOYEE_NAME		   MANAGER_ID
----------- ------------------------------ ----------
       1008 中山大輔                             1001
  1. 副問合せの条件は「e.manager_id = m.employee_id」なので、副問合せで参照している employees m 表から、m.employee_id と e.manager_id が等しい行を取得する。
  • 上の 3. で employees e から取得した中山大輔の employee_id は 1008。
  • 副問合せで参照している employees e 表の e.manager_id と一致する行がない。
    -> 副問合せから行が返されないので、主問合せの EXISTS 条件は FALSE。この行の m.employee_name は返されない。(出力されない)

=> 結果として、employees 表の manager_id 列に存在する値を、employee_id 列の値として持つ行(部下を持つ従業員(上司))が返される。

2023/08/21 返信
セッションの意味

セッションというのは各ユーザーがオラクルにアクセスするたびにそれぞれのセッションが作成されるイメージを持っています。←あっているでしょうか?

はい。その認識で良いと思います。
sqlplusなどを使用して対話的にアクセスしている状況ならば「各ユーザ」と呼べますし、開発した複数のアプリケーションからのアクセスであれば「各アプリケーション」とも呼べると思います。

もし、セッションが各ユーザがオラクルにアクセスするたびに作成されるのであれば、上記セッションは終了しておらず他のセッションからTEMP表を参照するとデータが1件表示されるのではないか?

ご認識の通り、セッションは終了していないと考えられます。終了しているのは「トランザクション」のみです。テーブル定義時に「ON COMMIT PRESERVE ROWS」を指定しているので、トランザクション終了後もデータを参照できています。(解説の実行例の通り)

この設問でのポイントは、「一時表のデータはあくまでもセッション内でのみ参照可能である」という点だと思います。他のセッションからは「表の構造」は参照できますが(解説の画像でいうところのDESC)、「データ」は参照できません(解説の画像でいうところのSELECT文の結果)。

一つのコマンドプロンプト(Linuxやmacであればターミナル等)を立ち上げて設問で提示されているSQLを実行後、同じコマンドプロンプト上から(同じセッション内からの意)はCOMMIT後も挿入したデータが参照できます。

もう一つ別のコマンドプロンプトを立ち上げて「temp」表に対してSELECT文を実行しても、データは参照できません。これは、前のコマンドプロンプトにおける最後の「COMMIT;」の前でも後でも同様です。

このことから「他のセッションからTEMP表を参照すると、データは0件である」が正答であると導き出せると思います。

2023/08/08 返信
NOT NULL制約

問題文の冒頭に「EMPLOYEE_ID列にはPRIMARY KEY制約だけが定義されています」とあるので、画像の「NOT NULL」は、明示的に付与したNOT NULL制約というわけではなく、PRIMARY KEY制約を付与した際に暗黙的に作成されたものだと判断できると思います。

運営さんに修正してもらうとしたら、明示的か暗黙的かを明記してもらうぐらいでしょうか。
実際の試験において、どの程度明確な問題文が提示されるかはわかりませんが...。

2023/08/03 返信
FOR UPDATE WAIT  について

ユーザーAが発行したFOR UPDATE WAIT 10はユーザーAの前の処理に対して働いていると考えますがあっているでしょうか?

そうですね。
①のSELECT文で「FOR UPDATE」を用いてロックを取得しようとしていますが、競合するトランザクションがすでにある場合には待たされます。「WAIT 10」は競合するトランザクションがすでにあった場合に「10秒までは待つ」という意味で、10秒経過するとエラーが返ります。
この設問では、①の前に何かトランザクションがあるか否かといった情報は特に提示されていないので、ロックを取得できると考えられます。

また、解説③にはユーザーAがかけた排他ロックが解除されるまで待機するとありますが、これはユーザーBのSQL文でUPDATE prod SET name = 'Chopin' WHERE prodid = 2 の後に FOR UPDATE WAIT がありませんがデフォルトでそのような挙動になるのでしょうか?

FOR UPDATE句はSELECT文で使用できる句です。UPDATE文ではそもそもロックを取得するので、FOR UPDATE句はありません。(「SELECT ... FOR UPDATE」文としてひと塊りで覚えてしまった方がわかりやすいかもしれません)

参考: DML操作での自動ロック
https://docs.oracle.com/cd/F19136_01/sqlrf/Automatic-Locks-in-DML-Operations.html#GUID-3D57596F-8B73-4C80-8F4D-79A12F781EFD

2023/08/03 返信
certviewのログインについて

私は同じ状況になったことはないのですが、試しに今PCからログインしてみましたところ、特に問題なくログインできました。
ログインできないとのことですが、何かエラーなど出ている場合には、Oracle側に問い合わせをしてみた方が早いかもしれませんね。

https://www.oracle.com/jp/education/certification/migration-to-certview.html#Contact
ここの、「オラクル認定資格事務局(oraclecert_jp@oracle.com)」でしょうか。

2023/07/24 返信
INTERSECTの解釈について

例として挙げておられるデータで実際に試してみました。
INTERSECTは積をとり、重複行は含まれないのでこのような結果となるようです。

SQL> select * from test_prod;

   PROD_ID PROD_NAME
---------- -----------
      1001 Alpha
      1001 Blavo
      1001 Charlie
      1002 Delta

SQL> select * from test_sales;

   PROD_ID    CUST_ID
---------- ----------
      1001	 2001
      1001	 2002
      1001	 2003
      1002	 2004

SQL> select prod_id from test_prod intersect select prod_id from test_sales;

   PROD_ID
----------
      1001
      1002

SQL> select distinct prod_id from test_prod p join test_sales s using(prod_id);

   PROD_ID
----------
      1001
      1002

SQL>
戻る