平成30年 午後1 問2 設問2(2)

お茶っ葉さん  
(No.1)
トリガーの実行タイミングですが、従業員家族の削除前でもいいと思うのですが、回答では削除あとになっていました。削除前では行けない理由をおしえていただけないでしょうか?
2022.10.02 00:01
にゃんちゃんさん 
DB シルバーマイスター
(No.2)
問題用紙P.12に以下の記述があるためです。
「ただし、実行タイミングを挿入・更新・削除の前として定義したトリガの処理の中で、テーブルに対する変更操作を行うことはできない。」

これにより、削除前を契機とした場合に、別テーブルへのINSERTができなくなります。
2022.10.02 00:19
logres_Fanさん 
DB ブロンズマイスター
(No.3)
>No2
  トリガを起動したテーブルに対する変更操作不可、別テーブルに対する変更操作可能と読むのは駄目でしょうか?
2022.10.02 00:33
にゃんちゃんさん 
DB シルバーマイスター
(No.4)
>logres_Fanさん
言われてみれば、そう読めなくもない気はします。

ただし、トリガ定義において
BEFOREトリガ:対象レコードを用いたDML(update,insert,delete)不可
が一般的(製品による??)なので
「テーブルに対する変更操作を行うことはできない。」については
「(すべての)DMLを扱うことはできない。」と読むのが普通なのかなと思います。

「(トリガを定義した)テーブルに対する変更操作を行うことはできない。
(ただし他テーブルに対する変更操作は行うことができる。)」
という解釈は、無理があるようにも感じます。

多分ですが、そもそもこの一文を書いた意図としては
実行タイミングが前か後かをこの文章で確定させたかったのかなと思います。
「INSERT・UPDATE・DELETE文を使用することはできない。」とかの方が良かったのかもしれません。
2022.10.02 01:55
にゃんちゃんさん 
DB シルバーマイスター
(No.5)
ちなみにBEFOREトリガの制限は製品依存ありそうですね。
手元のpostgreSQLだと、別テーブルへのINSERT(削除する行ではなく適当な文字列)はできちゃいました(僕の書き方が良くなかったのかも)。
Db2の公式ページでは、BEFOREトリガにはINSERT,UPDATE,DELETE,MERGE文は含められないとされています。
2022.10.02 02:08
初受験さん 
(No.6)
logres_Fanさん(No.3)  
>トリガを起動したテーブルに対する変更操作不可、別テーブルに対する変更操作可能と読むのは駄目でしょうか? 

設問2(2)の問いは「参照制約を利用することによって発生する不具合への対策」なので、その解釈は駄目と考えます。実行タイミングは(参照制約に紐付いた)トリガの実行後にせざるをえないでしょう。
2022.10.02 02:29
お茶っ葉さん  
(No.7)
ご回答いただきありがとうございます。

私も「別テーブルに対する変更操作可能」と解釈してしまいました。

初受験様
不具合が発生するのは従業員テーブルのトリガ実行時の話で、対策として定義した従業員家族テーブルのトリガの実行前後ではどちらでもいいと思ったのですが、どうでしょうか?
2022.10.02 12:34
GinSanaさん 
DB ゴールドマイスター
(No.8)
>にゃんちゃんさん(No.5)
DB2のBEFOREトリガの制約は、むしろANSI sql-99に沿っているので、ある意味ただしいですね。
postgresはsql99前の自前の拡張なのかもしれない。oracleもbeforeで制約をかけているのは調べた限りではない。

SQL-99 Complete, Really.
Peter Gulutzan, Trudy Pelzer
github.com/crate/sql-99/blob/55ee2e51d91e8201109f9f1a74ea0a9e4b402532/docs/chapters/24.rst

If Trigger action time is BEFORE, the Trigger action may include these SQL statements: DECLARE TABLE, DECLARE CURSOR, OPEN, CLOSE, FETCH, SELECT (for a single row only), FREE LOCATOR, HOLD LOCATOR, CALL, RETURN and GET DIAGNOSTICS. It may also name an SQL-invoked routine, as long as that routine isn't one that possibly modifies SQL-data.
If Trigger action time is AFTER, the Trigger action may include all of the SQL statements allowed for BEFORE Triggers, plus: INSERT, UPDATE and DELETE. It may also name any SQL-invoked routine.

トリガー アクション時間が BEFORE の場合、トリガー アクションには次の SQL ステートメントを含めることができます。 また、そのルーチンが SQL データを変更する可能性がない限り、SQL によって呼び出されるルーチンを指定することもできます。
トリガー アクションの時間が AFTER の場合、トリガー アクションには、BEFORE トリガーに許可されているすべての SQL ステートメントに加えて、INSERT、UPDATE、および DELETE が含まれる場合があります。 また、SQL によって呼び出されるルーチンを指定することもできます。

あくまでANSIの定義は、INSERT、UPDATE、および DELETEはAFTERに「加えてもいいよ」というだけで、BEFOREは許す気がないようです。
2022.10.02 13:59
GinSanaさん 
DB ゴールドマイスター
(No.9)
ANSI SQL(JISのほうだかは忘れた)にのっかってデータベーススペシャリスト試験が進む以上は、beforeトリガでは更新処理そのものが許されない、という前提で話を進めないとならんでしょうね。
2022.10.02 14:10
にゃんちゃんさん 
DB シルバーマイスター
(No.10)
GinSanaさん
調べていただきありがとうございます!
BEFOREトリガは実行前のレコードの検査
AFTERトリガで、別テーブルへの操作
などに使うのが普通っぽいですかね。

問題文に明記してくれるはず(多分)なので、本番でも見落とさないようにします!!
2022.10.02 15:01
logres_Fanさん 
DB ブロンズマイスター
(No.11)
  beforeトリガは、全てのテーブル(起動したテーブル、その他テーブル)を対象に、UPDATE句、INSERT句、DELETE句が使えない、という事でした。すみません、お騒がせしました。
  
2022.10.02 15:32

返信投稿用フォーム

スパム防止のためにスレッド作成日から30日経過したスレッドへの投稿はできません。

その他のスレッド


Pagetop