PostgreSQLの関数は、タスクの自動化やビジネスロジックの作成、サーバーにもっと賢さを持たせるための強力なツールだよ。関数はデータベースの中で実行されるミニプログラムみたいなもの。こんな時に便利:
- コードの再利用。 同じクエリを何度も書くなら、関数にまとめて必要なとき呼び出せばOK。
- タスクの自動化。 例えば、従業員の労働時間から給料を計算したい時。関数なら楽勝!
- ロジックのカプセル化。 複雑な計算をサーバー側に任せて、クライアントはSQLクエリで悩まなくて済む。
基本のシンタックス CREATE FUNCTION
関数を作るときの基本構造はこんな感じ:
CREATE FUNCTION function_name(parameters) RETURNS return_type AS $$
BEGIN
-- 関数の本体(ロジック)
RETURN 結果;
END;
$$ LANGUAGE plpgsql;
主なパーツを見てみよう:
CREATE FUNCTION function_name(parameters):
ここで関数名function_nameと、必要ならパラメータを指定するよ。
パラメータは名前とデータ型を持てる:my_param INTEGER、another_param TEXTみたいに。
RETURNS return_type:
関数が返すものを指定する:単一の値(INTEGER、TEXTなど)か、データセット(TABLE、RECORD)。
BEGIN ... END:
このキーワードの間が関数の「本体」で、ここで全部の魔法が起きる。
RETURN 結果:
関数の実行結果を返すよ。注意:戻り値の型はRETURNSで指定したものと一致してないとダメ。
LANGUAGE plpgsql:
PL/pgSQL言語を使うって指定してる。他の言語も使えるけど、今はこれでOK。
シンプルな例:2つの数字を足す
2つの整数の合計を返す関数を作ってみよう。
CREATE FUNCTION add_numbers(a INT, b INT) RETURNS INT AS $$
BEGIN
RETURN a + b;
END;
$$ LANGUAGE plpgsql;
これを呼び出すと:
SELECT add_numbers(5, 7); -- 結果: 12
何が起きてる?
- 関数は2つのパラメータ
aとb(型はINT)を受け取る。 - 関数の中で単純に足し算(
a + b)して結果を返す。 - まるで電卓みたいにシンプル!
変数を使った例
例えば、大学のデータベースがあって、登録されてる学生の数を知りたいとする。
関数を作ろう:
CREATE FUNCTION count_students() RETURNS INT AS $$
DECLARE
total INT; -- 結果を保存する変数を宣言
BEGIN
SELECT COUNT(*) INTO total FROM students; -- テーブルの行数を数える
RETURN total; -- 結果を返す
END;
$$ LANGUAGE plpgsql;
関数の呼び出し:
SELECT count_students(); -- 例えば、結果: 120
ここで:
- 変数
totalを使ってSQLクエリの結果を保存してる。 SELECT ... INTOでクエリの結果を変数に入れる。
このやり方は、データを一度処理してから返したい時に特に便利!
複数の値を返す:RETURNS TABLE
さっきの例では1つの値だけ返してたけど、もし関数でデータセット(例えば学生のリスト)を返したい場合は?ここでRETURNS TABLEが役立つ!
例:
CREATE FUNCTION get_students() RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
RETURN QUERY SELECT id, name FROM students;
END;
$$ LANGUAGE plpgsql;
関数の呼び出し:
SELECT * FROM get_students();
想定される結果:
| id | name |
|---|---|
| 1 | Alice |
| 2 | Bob |
| 3 | Charlie |
関数内でクエリを返すRETURN QUERYの便利さ
RETURN QUERYを使うと、SQLクエリの結果をそのまま関数から返せる。余計な手順が減って、関数がシンプルになるよ。
アクティブな学生だけ返す関数を作ってみよう:
CREATE FUNCTION get_active_students() RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
RETURN QUERY SELECT id, name FROM students WHERE active = TRUE;
END;
$$ LANGUAGE plpgsql;
get_active_students()を呼ぶ前に、studentsテーブルを作ってテストデータを入れておこう。例えば:
-- 学生テーブルを作成
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
active BOOLEAN DEFAULT TRUE
);
-- いくつかレコードを追加
INSERT INTO students (name, active) VALUES
('Alice', FALSE),
('Bob', TRUE),
('Charlie', TRUE),
('Dana', FALSE);
テーブル:
| id | name | active |
|---|---|---|
| 1 | Alice | false |
| 2 | Bob | true |
| 3 | Charlie | true |
| 4 | Dana | false |
呼び出し:
SELECT * FROM get_active_students();
結果:
| id | name |
|---|---|
| 2 | Bob |
| 3 | Charlie |
実行前にデータの正しさをチェックする
関数の中でIFを使って、データが正しいかチェックできる。例えば、全ての試験に合格した学生だけ次のコースに進める関数を作る場合。
例:
CREATE FUNCTION promote_student(student_id INT) RETURNS TEXT AS $$
DECLARE
passed_exams INT;
BEGIN
-- 学生が合格した試験の数を数える
SELECT COUNT(*) INTO passed_exams
FROM exams
WHERE student_id = promote_student.student_id AND status = 'passed';
-- 条件をチェック
IF passed_exams < 5 THEN
RETURN '学生は十分な試験に合格していません';
END IF;
-- 学生のコースを更新
UPDATE students
SET course = course + 1
WHERE id = promote_student.student_id;
RETURN '学生が進級しました!';
END;
$$ LANGUAGE plpgsql;
関数作成時によくあるミス
戻り値の型がない。 PostgreSQLは必ず関数の戻り値の型を指定しないとダメ。例えば:
CREATE FUNCTION fail() AS $$ -- エラー: RETURNSがない
BEGIN
RETURN 1;
END;
$$ LANGUAGE plpgsql;
修正例:
CREATE FUNCTION succeed() RETURNS INT AS $$
BEGIN
RETURN 1;
END;
$$ LANGUAGE plpgsql;
戻り値の型が合ってない。 RETURNS INTなら、必ず数字を返さないとダメ。文字列を返そうとするとダメだよ。
関数内のSQLクエリのミス。 関数で使う前に、クエリをちゃんとテストしよう。psqlやpgAdminで手動で試すのがオススメ!
GO TO FULL VERSION