DBデータベーススペシャリスト試験 午後Ⅰ
平成30年度春期 データベーススペシャリスト 午後Ⅰ 問2
事例を読んで設問の答えを考えてから、解説のポイントとIPA公式の解答例・採点講評で確認しましょう。
問題

![表1 退職した従業員の行を削除するSQLの構文(未完成)。SQL1:DELETE FROM 従業員 WHERE 退職フラグ = [a] AND ((DAYELEMENT(退職年月日) < [b]) OR (MONTHELEMENT(退職年月日) < MONTHELEMENT([c])))。注記でDAYELEMENT関数とMONTHELEMENT関数をユーザ定義関数として説明。](/figures/a4a6dc3b684d6c98f339e5d437a1c064b76f3ec06ba51b25d0df8804b880f9bf.webp)

![表2 一覧表を作成するSQLの構文(未完成)。SQL2:SELECT [d], COUNT([e] 従業員家族.従業員コード) AS 従業員数, COUNT(*) AS 扶養対象者数 FROM 従業員, 従業員家族 WHERE 従業員コードで結合し,扶養フラグ='1'かつ生年月日>=TO_DATE('2007-01-01')。GROUP BY [d] [f] [d]。TO_DATE関数の注記付き。](/figures/2633d51b530e2ef8a5941d1871ffc715431fd5e23bf1750c9678ee3304a9f49f.webp)


解き方のヒントを見る
整合性確保は処理の順序と状態で考える
データ整合性に関わる問題では、ある操作が行われる前後で各表のデータがどのような状態にあるかを、問題に示された条件に沿って一段階ずつ追うことが基本です。思い込みの一般論ではなく、与えられた設定だけを根拠に考えましょう。
この問題で問われていること
確認すべき観点は一つ、処理の各時点におけるデータの状態です。どの操作がどの順で実行され、その時点で関連するデータが存在するか・どの値を持つかを整理し、制約や自動処理がどの状態を前提に働くかを照らし合わせてください。
視点
整合性を保つ仕組みは、データが変化する瞬間に何らかの判定や処理を行います。そのため、仕組みの名前や一般的な印象から結論を急ぐと誤りやすくなります。まず、関係する表とデータの関係を書き出します。次に、一連の更新を時系列に並べ、各段階でデータがどう変わるかを追います。問題に示された定義や条件を根拠にし、書かれていない前提は補わないことが大切です。
確認ポイント
- 一連の更新を時系列に並べ、各段階の直前と直後でデータがどう変わるかを書き出したか
- 各段階で、関連するデータが存在するか、どの値を持つかを問題の記述から確認したか
- 制約や自動処理が働く時点のデータ状態を、問題に示された定義や条件だけを根拠に照合したか
正解と解説を見る
解説
人事情報管理DBを題材に、参照制約を導入したときの影響を問う問題です。SQLの穴埋め(退職者の削除条件、部署別の集計)に加え、次の三つを読み解きます。①NULLの外部キーとNO ACTIONによるエラー、②CASCADEの連鎖削除が既存トリガを壊す仕組みとその対策、③部署の削除によって所属従業員まで連鎖削除される不具合と、それを避ける手順の組み替えです。最後に、猶予モードの検査内容と、索引がないことによる性能リスクを説明します。
問題の全体像
Y社の人事情報管理DB(部署・職位・従業員・従業員家族)では、手作業で作った入力データのミスにより、存在しないコードでテーブルが更新されるトラブルが起きていました。これを防ぐため、表3のとおり参照制約を導入します。各外部キーのUPDATEはNO ACTIONです。DELETEは、従業員の部署コード・職位コードと従業員家族の従業員コードがCASCADE、部署の管理者従業員コードがNO ACTIONです。検査契機は、従業員の部署コードだけが猶予モードで、それ以外は即時モードです。出題趣旨では、参照制約の影響で予期せぬ結果が起きないよう、処理の内容や順序を注意深く設計する力と、SQLの基礎知識を問うとしています。採点講評では、全体の正答率は低く、設問3は参照制約の知識の有無で出来が二分されたと述べています。
設問1(1)a
SQL1は、退職済みの従業員を削除するSQLです。問題文には「退職すると退職フラグを‘0’(在籍)から‘1’(退職)に更新する」とあります。したがって、退職フラグと比較する値は‘1’です。公式解答例も '1' です。退職フラグは文字の値として定義されているので、引用符付きで書く点に注意します。
設問1(1)b
削除は毎月25日に行い、対象は「当月の20日までに退職した従業員」です。この条件は二つに分けて書かれています。一つはDAYELEMENTで日の部分を比べる条件、もう一つはMONTHELEMENTで年月を比べる条件です。退職フラグが‘1’なので、退職年月日は処理日(25日)以前であることが保証されています。当月分は「日が20以下」、つまり「日 < 21」で表せます。そのため公式解答例は 21 です。前月の21日以降に退職した人は前月の処理で消されずに残っていますが、今月は後半の年月条件(前月以前)に当てはまるので削除されます。
設問1(1)c
後半の条件は「退職年月日の年月が当月より前」を表します。比較相手には、SQL実行時点の日付の年月が必要です。公式解答例では、SQL標準の日付関数 CURRENT_DATE を入れています。採点講評では、設問1のうち(1)cだけ正答率が低く、SQLの基礎知識なので是非知っておいてほしいと述べています。
設問1(2)d
図2の一覧表は、部署コードごとに集計し、部署コード順に並べたものです。SELECT句・GROUP BY句・ORDER BY句の三か所に同じ字句が入るので、集計と並べ替えのキーである部署コードを入れます。部署コードを持つのは“従業員”テーブルなので、公式解答例では表名で修飾した「従業員.部署コード」としています。FROM句で2表を結合しているため、どの表の列かを明示する書き方です。
設問1(2)e
従業員と従業員家族を結合すると、扶養対象者1人につき1行ができます。扶養対象者数は COUNT(*) で数えられます。しかし従業員数をそのまま数えると、扶養対象者を複数もつ従業員が重複して数えられます。図2でも、78001は従業員数4に対して扶養対象者数7です。そこで COUNT(DISTINCT 従業員家族.従業員コード) で重複を除いて数えます。公式解答例は DISTINCT です。
設問1(2)f
依頼は「部署コード順に」一覧表を作ることです。GROUP BY だけでは結果の並び順は保証されません。そのため最終行で並べ替えを指定します。公式解答例は ORDER BY で、後ろに d(従業員.部署コード)が続く形です。
設問2(1)(a)
従業員の部署コードは部署(部署コード)を参照します。参照制約(外部キー)は、値がNULLの行を検査しないのが基本の仕様です。所属未定でNULLの行を挿入しても、存在しないコードを参照していることにはなりません。そのため公式解答例は「正常終了」で、理由は(なし)です。採点講評では、設問2(1)は正答率が高く、題意が理解されていたとしています。
設問2(1)(b)
表3では、“部署”テーブルの管理者従業員コードが従業員(従業員コード)を参照しており、DELETEの挙動は NO ACTION、検査は即時モードです。管理者である従業員の行を削除すると、部署の行は何も変更されず、存在しない従業員を参照したまま残ります。この状態はSQL実行の終了時に検査され、エラーになります。公式解答例は「エラー」で、理由は「“部署”テーブルの管理者従業員コードの参照制約に違反するから」です。40字以内の答案では「どのテーブルの、どの列の参照制約に違反するか」を具体的に書くことが要点です。なお、従業員家族(CASCADE)の行は連鎖削除されるので、エラーの原因にはなりません。
設問2(2)
既存のトリガは、“従業員”テーブルの削除の後に動きます。削除された従業員の行を別テーブルへ保存したうえで、その従業員の家族の行を別テーブルへ挿入し、削除する処理です。ところが参照制約導入後は、従業員家族.従業員コードがDELETE CASCADE(即時)になります。従業員の行を削除した時点で家族の行が連鎖削除されるため、トリガが家族の行を保存しようとしても、行はもう残っていません。そこで、従業員側のトリガは従業員の行の保存だけに変えます。そのうえで、公式解答例のとおり新たなトリガを定義します。対象テーブルは“従業員家族”、実行タイミングは「削除の後」、処理内容は「削除した行を別テーブルに挿入する」です。こうすればCASCADEで削除される家族の行も、行ごとに保存できます。削除の前に動くトリガでは、仕様上テーブルへの変更操作(別テーブルへの挿入)ができないので、タイミングは「後」になります。採点講評では、「挿入・更新・削除」だけを書いて前か後かを答えていない解答や、実行条件を答えた解答が多かったと指摘しています。
設問3(1)
図3の順序は、①部署の削除→②コミット→③部署の挿入→④コミット→⑤従業員の部署コード更新→⑥コミットです。①の時点では、廃止される部署に所属している従業員が、まだ異動前の部署コードのまま残っています。従業員.部署コードのDELETEはCASCADEなので、部署の行を削除するとその従業員の行まで連鎖削除されてしまいます。公式解答例では、契機を①、不具合を「削除された部署に所属している従業員が、“従業員”テーブルから削除される」としています。40字以内で「どの従業員が、どのテーブルから消えるか」を書きます。
設問3(2)
不具合を避けるには、部署を削除する前に、所属していた従業員を異動先の部署へ付け替えておく必要があります。また、異動先となる新設部署は、従業員の部署コードを更新する前に存在していなければなりません。したがって順序は、部署の新規挿入(③)→従業員の部署コード更新(⑤)→不要な部署の削除(①)になります。公式解答例は[③]→②→[⑤]→④→[①]→⑥です。この順序なら、①の時点で削除対象の部署に所属する従業員がいないので、CASCADEによる連鎖削除は起きません。
設問3(3)(a)
部署コードの更新に対する挙動は NO ACTION で、参照元の値は書き換えられません。猶予モードでは、トランザクション終了時にまとめて検査します。確認すべきなのは、更新によって部署テーブルから無くなった旧部署コードを参照している従業員が残っていないかどうかです。公式解答例では「更新によって無くなった部署コードが、“従業員”テーブルの“部署コード”に存在しないことを確認する」としています。55字以内の答案では、①検査する値(更新で無くなった部署コード)、②検査先(“従業員”テーブルの部署コード)、③確認内容(存在しないこと)の三つを押さえます。
設問3(3)(b)
問題文には「索引は、主キーだけに定義されている」とあります。“従業員”テーブルの部署コードは外部キーで、主キーではないので索引がありません。(a)の検査では、無くなった部署コードを参照する従業員がいないかを調べるため、“従業員”テーブルを全件走査することになります。そのため処理時間が想定より長くなるおそれがあります。公式解答例は「“従業員”テーブルの“部署コード”に索引がなく、全行を参照しなければならないから」です。50字以内で「索引がないこと」と「全行を参照すること」の因果を書くのが要点です。
学習のポイント
表3の参照制約(挙動モード・検査契機モード)を一行ずつ業務操作に当てはめ、連鎖削除・エラー・検査コストを予測できるようにすることが重点です。あわせて、COUNT(DISTINCT)・GROUP BY・ORDER BY・CURRENT_DATEといったSQLの基礎を確実に押さえます。
出典:独立行政法人 情報処理推進機構(IPA)平成30年度春期 データベーススペシャリスト試験 午後Ⅰ 問2(公式資料:問題冊子(PDF) / 解答例 / 採点講評)
関連する過去問一覧
IPA Advancedは非公式の学習サイトです。解説にはAIによる補助生成を含む場合があります。公式の問題冊子・解答例・採点講評を優先し、誤りは確認後に訂正します。運営・編集方針