PR

【SQL】カーソル(cursol)とは?仕組みと使い方を3分でわかりやすく解説

Database

カーソル(cursol)とは、データベースの中のデータ(行)を1つずつ見ていくための「目印」や「指標」のようなもの。

イメージとしては、本を読むときに使うしおりのようなものです。ページ(行)を1つずつ開いて読み(処理)進んでいくと考えるとわかりやすいかもしれません。

ポイント カーソル(cursol)

  1. 1行ずつ処理: カーソルを使うと、データベースの中の情報(行)を1つずつ取り出して処理ができる。
  2. 大量のデータも安心: たくさんのデータがある場合でも、一度にすべてを読み込む必要がないので、パソコンが重くなりにくい。
  3. 自由な操作: カーソルが指し示す各行に対して、様々な処理(読み取り、更新、削除など)を行うことができる。
  4. 順番に処理: カーソルはデータベースの中を順番に移動しながら、必要な処理を行う。

このページはカーソルって何?という方のために、基本的な意味や具体的な実装方法までを簡潔にわかりやすく解説します。

このページで学べる内容
  • カーソル(cursol)とは?
  • カーソル(cursol)を利用するメリット / デメリット
  • カーソル(cursol)の実装方法

プログラマーやシステムエンジニアを目指す方であれば、知らないと恥ずかしい超・基本知識の1つ。是非最後までご覧ください。

スポンサーリンク

カーソル(cursol)とは?

冒頭でも解説した通り、カーソル(cursol)とはデータベースの中のデータ(行)を1つずつ見ていくための「目印」や「指標」のようなものです。

言葉だけではイメージしづらいかもしれませんので、実際の例を見ながら学習を進めていきましょう!

カーソルを利用するシナリオ

  • studentsテーブルがあり、idnameというフィールドが存在する。
  • カーソルを使って、特定の条件に一致する学生(student)の名前(name)を"John Doe"に変更します。

ステップ1 カーソルの定義

最初に、条件に一致するidを取り出す(SELECTする)カーソルを宣言します。

DECLARE my_cursor CURSOR FOR SELECT id FROM students WHERE name='John';

上記SQLの詳細は↓の通り。

cursolとは?
図1:cursolとは?

ざっくりいえば、John という行に合致する行に本のしおり(=カーソル)を挟むようなイメージです。

  • DECLARE: 変数やカーソルを宣言するSQLキーワード。
  • my_cursor: カーソルの名前。
  • CURSOR FOR: カーソルで処理するSQLクエリを指定。
  • SELECT id FROM students WHERE name='John': 実行するSQLクエリ。

本来MySQLでは、カーソルはストアドプロシージャ関数内でしか宣言できませんが、ここでは理解促進のためあえてコードを改変しています。

ステップ2 カーソルを開く

OPEN my_cursor;

ステップ3 データの取得

カーソルから次のidを取り出し、一時的な変数(たとえば@student_id)に格納します。

FETCH my_cursor INTO @student_id;
  • FETCH: カーソルからデータを一行取り出す。
  • INTO @student_id: 取り出したデータを@student_id変数に格納。

ステップ4 特定の行を更新

ここでカーソルが指している行の名前を"John Doe"に更新します。

UPDATE students SET name='John Doe' WHERE CURRENT OF my_cursor;
  • UPDATE students SET name='John Doe': studentsテーブルのname列を"John Doe"に更新します。
  • WHERE CURRENT OF my_cursor: カーソルが現在指している行だけを更新

ステップ5 カーソルを閉じる

CLOSE my_cursor;
様々なサンプルコード

1. データの集計

行ごとに特定の計算を行い、その結果を集計する際にカーソルが役立ちます。

-- カーソルを宣言
DECLARE sales_cursor CURSOR FOR SELECT amount FROM sales;

-- 変数を宣言
DECLARE @total_sales INT;
SET @total_sales = 0;

-- カーソルを開く
OPEN sales_cursor;

-- 各行を処理
-- FETCH NEXT: カーソルが現在指している位置から次の行に移動。
FETCH NEXT FROM sales_cursor INTO @amount;
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @total_sales = @total_sales + @amount;
    FETCH NEXT FROM sales_cursor INTO @amount;
END;

-- カーソルを閉じる
CLOSE sales_cursor;

2. 条件に基づくデータの更新

特定の条件に合致する行だけを対象としてデータを更新する場合にカーソルが有用です。

-- カーソルを宣言
DECLARE student_cursor CURSOR FOR SELECT id FROM students WHERE grade < 60;

-- 変数を宣言
DECLARE @student_id INT;

-- カーソルを開く
OPEN student_cursor;

-- 各行を処理
FETCH NEXT FROM student_cursor INTO @student_id;
WHILE @@FETCH_STATUS = 0
BEGIN
    UPDATE students SET status = 'Failed' WHERE id = @student_id;
    FETCH NEXT FROM student_cursor INTO @student_id;
END;

-- カーソルを閉じる
CLOSE student_cursor;

3. データのエクスポート

行ごとにデータをファイルや外部システムにエクスポートする際にもカーソルが役立つ場合があります。

-- カーソルを宣言
DECLARE export_cursor CURSOR FOR SELECT name, email FROM users;

-- 変数を宣言
DECLARE @name VARCHAR(50), @email VARCHAR(50);

-- カーソルを開く
OPEN export_cursor;

-- 各行を処理
FETCH NEXT FROM export_cursor INTO @name, @email;
WHILE @@FETCH_STATUS = 0
BEGIN
    -- ここで、@nameと@emailを外部ファイルやシステムにエクスポートするロジックを実装
    FETCH NEXT FROM export_cursor INTO @name, @email;
END;

-- カーソルを閉じる
CLOSE export_cursor;

実践:MySQLにおけるカーソルの利用

先ほども述べた通りカーソル(cursol)は、一般的にカーソルはストアドプロシージャや関数内でしか使えません。

実際にカーソルを利用する際のサンプルコードをお見せします。

DELIMITER //
CREATE PROCEDURE ListStudentNames()
BEGIN
  DECLARE done INT DEFAULT 0;
  DECLARE student_id INT;
  DECLARE student_name VARCHAR(255);
-- ↓の行でstudentsテーブルからIDと名前を選択するカーソルを宣言。
  DECLARE cur CURSOR FOR SELECT id, name FROM students;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

-- カーソルを開く
  OPEN cur;

  read_loop: LOOP
-- カーソルからレコードを取得し、その値を変数student_idとstudent_nameに格納します。
    FETCH cur INTO student_id, student_name;
-- カーソルが最後の行に達したかどうかを確認→最後の行ならループを終了
    IF done THEN
      LEAVE read_loop;
    END IF;
    SELECT CONCAT('Student ID: ', student_id, ', Name: ', student_name);
  END LOOP;

  CLOSE cur;
END;
//
DELIMITER ;

このMySQLのストアドプロシージャでは、カーソルを使ってstudentsテーブルから学生の情報を一行ずつ取得し、その名前を出力しています。

このように、カーソルは行を一つずつ処理する複雑なロジックを実装する場合に非常に便利です。

Pythonでの実装例

以下は、PythonとSQLiteを使用してカーソルを使う簡単な例です。

import sqlite3

# データベースに接続
conn = sqlite3.connect('example.db')
cursor = conn.cursor()

# SQLクエリを実行
cursor.execute('SELECT * FROM table_name')

# 結果を一行ずつ取得して処理
for row in cursor:
    print(row)  # 出力: テーブルの各行の内容

# カーソルと接続を閉じる
cursor.close()
conn.close()

このようにカーソルの考え方はデータベースを操作する他のプログラムでも応用されます。

参考 Pythonの基本

カーソルを利用するメリット

カーソルを利用する主なメリットは、データの行に対して個別に処理を行える点です。

SQLは基本的にセット操作が得意ですが、一度に多数の行を処理する場合、リソースの消費が大きくなったり、一部の行に対して特別な操作を行いたい場合には不便です。カーソルはこのようなシナリオで有用であり、行単位での処理を効率よく、かつ柔軟に行うことができます。

また、処理中に他の操作を挟むことが容易であり、複雑なビジネスロジックを組み込む際にも役立ちます。

カーソルを利用するメリット
  • 行単位の処理: カーソルを使用することで、データベース内の各行を個別に操作できる。
  • リソース効率: 大量のデータを一度に操作するよりも、カーソルで行単位で処理を行う方がリソースを効率よく使用できる場合がある。
  • 処理の柔軟性: カーソルを用いると、途中で条件を変更したり、特定の行に特別な操作を加えたりすることが容易。
  • 複雑なロジックの組み込み: カーソルを使用すると、各行に対して独自のビジネスロジックや計算を効率よく適用可能。
  • 逐次的な操作: カーソルはデータを逐次処理するため、巨大なデータセットでもメモリを節約しながら操作が可能。

まとめ:カーソル(cursol)とは?

  • 行単位の操作: カーソルはデータベース内のテーブルから行を一行ずつ取得するためのツールです。
  • 逐次処理: 大量のデータに対しても、一行ずつ処理を行うことでリソースを節約します。
  • 柔軟性: カーソルを使うことで、各行に対して独自の条件やロジックを適用できます。
  • 手続き型プログラミング: ストアドプロシージャや関数内でよく使用され、複雑なデータ操作を行う際に有用です。

SQLやデータベースの仕組みを1から学習したい方(学び直したい方)向けに、現役エンジニア達のスキルを結集して 完全無料 のSQL教材を作成しました。

SQLは決して難しい技術ではないので、エンジニアであれば「当たり前のように」扱えて当然かも・・・?

とはいえ、案外SQLをちゃんと使ったことがない人も多いはずです。この機会に是非一度ご覧になってみてください。

このWebサイトは現役のエンジニアが以下3点を目的として運営しています。

  1. 勉強:一度理解した内容を忘れないように。
    → アウトプットは「最強のインプット」である! 
  2. 備忘:忘れたとしても後から見返せるように。
    → 未来の自分への「お手紙」を書いています。 
  3. 共有:〇〇ってこうだったんだ!の感動をシェアできるように。
    → あなたの知識は誰かにとっての「価値ある情報」です。 

副業ブログの始め方はこちらから

スポンサーリンク
DatabaseIT-Skills
シェアする
ビズドットオンラインをフォローする
タイトルとURLをコピーしました