rink_rewさんの助け合いフォーラム投稿一覧
ユーザー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
私は同じ状況になったことはないのですが、試しに今PCからログインしてみましたところ、特に問題なくログインできました。
ログインできないとのことですが、何かエラーなど出ている場合には、Oracle側に問い合わせをしてみた方が早いかもしれませんね。
https://www.oracle.com/jp/education/certification/migration-to-certview.html#Contact
ここの、「オラクル認定資格事務局(oraclecert_jp@oracle.com)」でしょうか。
例として挙げておられるデータで実際に試してみました。
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>
こういうことでしょうか。
SQL> select * from emp;
EMP_ID EMP_NAME SAL
---------- ---------- ----------
1001 aaa 100000
1002 bbb 200000
SQL> create view emp_view_check as select * from emp where sal = 200000 with check option;
ビューが作成されました。
SQL> select * from emp_view_check;
EMP_ID EMP_NAME SAL
---------- ---------- ----------
1002 bbb 200000
SQL> delete from emp_view_check where emp_id = 1001;
0行が削除されました。
SQL> delete from emp_view_check where emp_id = 1002;
1行が削除されました。
SQL> select * from emp;
EMP_ID EMP_NAME SAL
---------- ---------- ----------
1001 aaa 100000
SQL>
作成したビューを通して元表のデータを削除する場合、そのビューに含まれるレコードは作成時の条件を満たす(with check optionのチェックを通っている)ものだけなので、もしdelete文の対象とするレコードがビューの作成条件を満たしていないのならば、そのビューからはそもそも見えていないデータだと思います。
このようなdelete文においては、上記の実行例によれば、delete文自体はエラーにはならないが、実際には何も削除されないようです。
解説に
①数値→文字への暗黙的な型変換が出来る
②文字→数値への暗黙的な型変換は出来ない
解説のどの部分でしょうか?最後に記述されている以下の文章でしょうか。
また、2つ目のSQL文では、第3引数には数値データ(salary)が指定されており、その後、2つ目の戻り値として文字データ('-')が指定されています。'-'は暗黙的データ変換で数値データへ変換できないため、このSQL文もエラーとなります。
もしこの文章のことであれば、「文字→数値への暗黙的な型変換は出来ない」とは書かれておらず、「'-'は暗黙的データ変換で数値データへ変換できない」なので、'-' が数値データへの変換ができないという意味かなと思いました。
※例えば、'abc'のような文字列の場合、数値に変換しようがない。'-'も同様に数値に変換しようがない。'100'のような文字列であれば、Oracleは数値の 100 に暗黙的に変換できる。
Engineer1993 さんが仰っている通り、私も「文字→数値の暗黙的な型変換もできる」という理解ですが、あくまでもその変換が意味を持つ場合という認識です。
参考までに、マニュアルの暗黙的なデータ変換に関する部分に以下の記述がありました。
https://docs.oracle.com/cd/E16338_01/server.112/b56299/sql_elements002.htm#i46862
暗黙的なデータ変換
あるデータ型から別のデータ型への変換が意味を持つ場合、Oracle Databaseは値を自動的に変換します。
的外れな意見となっていましたらごめんなさい。
「NOMOUNT状態の時に読み込まれる」を「NOMOUNT状態の時に『MOUNT状態に遷移するために次に』読み込まれる」と捉えるか、「NOMOUNT状態の時に『既に』読み込まれている」と捉えるかという感じでしょうか。前者だと正解は「制御ファイル」、後者だと「初期化パラメータ・ファイル」ですが、ちょっと問題の表現が曖昧なような気もします。
設問の選択肢は「データベースがNOMOUNT状態の時に読み込まれる」ですが、「NOMOUNT状態の時」という時点においては、既に「初期化パラメータ・ファイル」は読み込み済みと判断して良いと思います。しかし、次に「制御ファイル」を読み込むとは限りませんし(startup nomountで起動しただけかもしれない)、startup openを実行した前提のような表現になってしまっているような気もします。
「NOMOUNTに遷移する時に読み込まれる」や「マウントする際に読み込まれる」のような表現なら勘違いしなくて済みそうですが、本試験で前述のような表現が出てくると迷ってしまいそうですね...。
問題の以下の解説にも記載されているように、結合列に表接頭辞を使用することはできないので、正答とされているクエリで正しいと思います。
USING句を指定した結合では、結合列に表接頭辞を使用することはできません。SELECT句やORDER BY句に指定されたDEPARTMENT_ID列に表接頭辞が指定されているためエラーとなります。
Ping-tさんのこちらの問題集には検証環境準備用のスクリプトが提供されているので、そちらを利用して正答のクエリを実際に実行してみましたがエラーは発生しませんでした。
参考:
https://docs.oracle.com/cd/F19136_01/sqlrf/SELECT.html#GUID-CFA006CA-6FF1-4972-821E-6996142A51C6