Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Cursor and Trigger

2025年10月02日に「Dev.to」が公開したITニュース「Cursor and Trigger」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

カーソルはデータベースのクエリ結果を1行ずつ処理し、特定の条件でデータを取り出す。トリガーはデータベースでイベントが起きた時に処理を自動実行する機能だ。これらを使えば、給与抽出や登録記録など、データベース操作の自動化と効率化が可能になる。

出典: Cursor and Trigger | Dev.to公開日:

ITニュース解説

データベースは、現代のITシステムにおいて情報の核となる存在であり、そのデータを効率的かつ正確に管理するために、様々な機能が提供されている。その中でも、「Cursor(カーソル)」と「Trigger(トリガー)」は、データベースの高度な操作を可能にする重要な機能であり、システムエンジニアを目指す上で基本的な理解が求められる。

まず、Cursorについて解説する。通常、データベースからデータを取得する際には、SELECT文を使って一度に複数の行をまとめて取得し、それをアプリケーション側で処理することが多い。しかし、特定のシナリオでは、取得した結果セットの各行に対して、一つ一つ個別の、より詳細な処理を行いたいというニーズが発生する。Cursorは、このような「結果セットの各行を順番に、一つずつ処理する」ことを可能にする機能だ。これは、例えば長いリストの項目を上から順に確認していくようなイメージに近い。

今回の記事の例では、給与が50,000を超える従業員の名前を表示するという課題をCursorを使って解決している。具体的な手順を見ていこう。 まず、schoolという名前のデータベースを作成し、その中にEmployeeというテーブルを作成する。このEmployeeテーブルには、従業員ID(EmpID)、従業員名(EmpName)、給与(Salary)の三つの列が定義されている。その後、Alice(給与60000)、Bob(給与45000)、Charlie(給与70000)という三人の従業員データをテーブルに挿入している。

このデータに対して、EmployeeCursorProcというストアドプロシージャを定義する。ストアドプロシージャとは、一連のSQL文をまとめてデータベースに保存し、必要に応じて呼び出して実行できるようにする機能であり、複雑な処理を効率的に実行するために用いられる。 プロシージャの中では、まずいくつかの変数を定義する。doneはCursorによるデータ処理が完了したかを示すフラグであり、初期値は0だ。emp_nameは、Cursorが読み取った従業員名を一時的に格納するための変数である。 次に、DECLARE cur CURSOR FOR SELECT EmpName FROM Employee WHERE Salary > 50000;という文でCursorcurを定義している。これは、「Employeeテーブルから給与が50,000より大きい従業員の名前だけを取得する」という条件に合致する結果セットを操作するためのCursorを作成するという意味だ。 さらに、DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;という文は、Cursorがこれ以上行を見つけられなくなった(つまり、結果セットの最後に到達した)場合に、done変数を1に設定するエラーハンドリングの仕組みを設定している。これにより、繰り返し処理を安全に終了させることができる。

Cursorを定義したら、実際にデータの処理を開始する。 OPEN cur;という命令でCursorを開き、データの読み取り準備を整える。 その後、read_loop: LOOP ... END LOOP;という構造で繰り返し処理に入る。このループの中で、FETCH cur INTO emp_name;という命令を使って、Cursorが現在指し示している行からEmpNameの値をemp_name変数に取得する。 IF done THEN LEAVE read_loop; END IF;という条件文は、もしFETCHの結果、もうデータがないと判断された場合(doneが1になった場合)に、ループを終了させるためのものだ。 データがまだあれば、SELECT emp_name;という命令で取得した従業員名を表示する。 すべての行の処理が終わったら、CLOSE cur;でCursorを閉じ、データベースのリソースを解放する。 最終的にCALL EmployeeCursorProc();を実行すると、定義されたストアドプロシージャが呼び出され、給与が50,000を超える従業員であるAliceとCharlieの名前が順に表示されるという結果になる。

Cursorは行ごとのきめ細やかな処理を可能にする一方で、大量のデータを扱う際にはパフォーマンス上のオーバーヘッドが発生しやすいという特性がある。これは、一行ずつ処理するためにデータベースとアプリケーション間のやり取りが多くなるためだ。そのため、Cursorの使用は、本当に各行に対して複雑なロジックが必要な場合に限定し、可能であればUPDATEDELETEのようなセットベースのSQL文で一括処理することを検討するのが一般的だ。

次に、Triggerについて解説する。Triggerは、データベース内で特定のイベント(例えば、データの挿入、更新、削除など)が発生した際に、自動的に実行される特別な種類のストアドプロシージャのようなものだ。手動でSQL文を実行しなくても、データベースがイベントを検知して、あらかじめ定義された処理を自律的に実行してくれるため、データの整合性維持や、ログ記録などのタスクの自動化に非常に役立つ。

記事の例では、学生が登録された際にその履歴を自動で記録するTriggerを作成している。 まず、Studentsテーブルと、学生の登録履歴を記録するためのStudent_Auditテーブルを作成する。Student_Auditテーブルには、AuditID、登録された学生のStudentID、実行されたアクション(ここでは'Inserted'という文字列)、アクションが発生した日時(ActionDate)が記録されるように定義されている。

Triggerの定義は、CREATE TRIGGER trg_Student_Insertから始まる。 AFTER INSERT ON Studentsという部分は、「Studentsテーブルにデータが挿入されたに」このTriggerの処理を実行するという条件を指定している。AFTERの代わりにBEFOREを指定すれば、データの挿入前に処理を実行することも可能だ。 FOR EACH ROWは、もし一度に複数の学生データが挿入されたとしても、挿入される1行ごとにTriggerの処理が実行されることを意味する。 BEGIN ... ENDブロックの中には、実際に実行したいSQL文を記述する。ここでは、INSERT INTO Student_Audit (StudentID, Action, ActionDate) VALUES (NEW.StudentID, 'Inserted', NOW());という文が書かれている。 ここで重要なのはNEW.StudentIDという記述だ。TriggerがINSERTイベントに対して動作する場合、新しく挿入されようとしている行のデータをNEWというキーワードを使って参照できる。NEW.StudentIDは、まさに今Studentsテーブルに挿入されようとしている学生のIDを指している。 NOW()は、現在のシステム日時を返す関数だ。つまり、このTriggerは「Studentsテーブルに新しい学生情報が挿入されたら、その学生のIDと'Inserted'というアクション、そして現在の時刻をStudent_Auditテーブルに自動的に記録する」という動作を行う。

このTriggerが作成された後、実際にINSERT INTO Students (StudentID, StudentName, Course) VALUES (1, 'John Doe', 'Mathematics');という文を実行して、新しい学生情報をStudentsテーブルに挿入する。このINSERT文の実行と同時にTriggerが自動的に起動し、Student_AuditテーブルにはJohn Doeの登録情報が自動的に記録される。 最後にSELECT * FROM Student_Audit;を実行すると、Student_Auditテーブルに1行のデータが追加されており、手動でStudent_AuditテーブルにINSERT文を実行することなく、自動でログが記録されていることが確認できるだろう。

Triggerの最大の利点は、データベースのロジックをアプリケーション層から分離し、データベース自体にビジネスルールを組み込むことができる点にある。これにより、どのアプリケーションからデータ操作が行われても、一貫した処理が保証され、データの整合性を維持しやすくなる。また、ログ記録のような定型作業を自動化することで、開発者の手間を省き、エラーの発生を抑える効果も期待できる。

まとめると、Cursorはデータベースのクエリ結果を「行ごとに」詳細に処理したい場合に強力なツールとなる。一方、Triggerはデータベース内で特定の「イベントが発生した際」に自動で特定の処理を実行させたい場合に非常に有効だ。これらの機能は、それぞれ異なる目的と特性を持つが、どちらもデータベースの機能を拡張し、より高度なデータ管理を実現するために不可欠な要素である。CursorとTriggerを適切に活用することで、データ整合性の維持、作業の自動化、そしてデータベースアプリケーション全体の効率性と信頼性の向上に大きく貢献できる。システムエンジニアとして、これらの機能を理解し、適切に使いこなす能力は、データベースを扱う上で非常に重要なスキルとなる。

関連コンテンツ

関連IT用語