データベースの世界には、普通のSQLの機能を拡張して、DBMSの中で本格的なビジネスロジックを書けるようにする言語がいくつかあるんだ。それぞれ自分のプラットフォーム向けに最適化されてるけど、基本的には同じような目的――データ操作の自動化、簡素化、スピードアップ――を達成するためのもの。代表的なのはPostgreSQL用のPL/pgSQL、Oracle用のPL/SQL、SQL Server用のT-SQL。それぞれに特徴やメリット、細かい違いがあるから、今からそれについて話すね。
PL/pgSQL(Procedural Language/PostgreSQL Structured Query Language)は、PostgreSQLに組み込まれてるプロシージャルプログラミング言語だよ。主な目的はSQLの機能を拡張して、変数、ループ、制御構造、エラー処理ブロックを使えるようにすること。これでDB側で複雑なビジネスロジックを実装できる強力なツールになるんだ。
PL/SQL(Procedural Language/SQL)は、Oracle DBMSに組み込まれてるプロシージャルプログラミング言語。データ処理やプロシージャ、ファンクション、パッケージの作成など、似たような機能を提供してる。PL/SQLは何十年も改良されてきた成熟した言語で、ツールのエコシステムも超充実してるよ。
T-SQL(Transact-SQL)は、MicrosoftがSQL Server用に開発した言語。標準SQLを拡張して、変数や制御構造、他にもプロシージャルプログラミングの要素を追加してる。T-SQLはトランザクション、カーソル、JSON操作の部分で独自の特徴があるよ。
PL/pgSQL、PL/SQL、T-SQLの共通点
パッと見だと、この3つの言語はかなり似てる感じがするよね。実際、目的は同じ――DBの中でビジネスロジックを実装すること。主な共通点を見てみよう:
ブロック構文
どの言語もプロシージャルなコードを書くための構造化されたフォーマットを持ってる。主な要素は:
- 変数の宣言
- メインの実行ブロック(
BEGIN ... END) - 例外処理のサポート
変数
どの言語でも変数を宣言して使えるよ。PL/pgSQLでの変数宣言の例:
DECLARE student_id INT; BEGIN student_id := 10; END;同じことはPL/SQLやT-SQLでもできるよ。
制御構造
どの言語も
IF...THEN、CASE、LOOP、FOR、WHILEをサポートしてて、複雑なアルゴリズムも書ける。ファンクションとプロシージャ
ユーザー定義のファンクションやプロシージャを作って呼び出せるし、単一の値やテーブルを返すこともできる。
PL/pgSQL、PL/SQL、T-SQLの違い
開発者はよく、あるDBから別のDBに移行しなきゃいけない場面に出くわすよね。そんなときは言語の細かい違いを知っておくのが大事。主な違いを見てみよう。
変数の宣言
PL/pgSQL:変数はDECLAREブロックで宣言する。値の代入は:=を使うよ。
DECLARE
total_students INT;
BEGIN
total_students := 5;
END;
PL/SQL:宣言方法はPL/pgSQLと似てるけど、変数の型をテーブルのカラムから%TYPEで継承できる。
DECLARE
student_name students.name%TYPE;
BEGIN
student_name := 'John';
END;
T-SQL:変数はDECLAREキーワードで宣言、代入はSETかSELECTでやる。
DECLARE @total_students INT;
SET @total_students = 5; -- または
SELECT @total_students = COUNT(*) FROM students;
エラー処理
PL/pgSQL:エラー処理はEXCEPTIONブロックを使う。例:
BEGIN
SELECT * INTO my_var FROM nonexistent_table;
EXCEPTION
WHEN others THEN
RAISE NOTICE 'エラーが発生したよ!';
END;
PL/SQL:同じくEXCEPTIONを使うけど、エラーの分類がもっと細かい。
BEGIN
SELECT * INTO my_var FROM nonexistent_table;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('データが見つからなかった!');
END;
T-SQL:TRY...CATCH構文を使う。
BEGIN TRY
SELECT 1/0; -- ゼロ除算エラー
END TRY
BEGIN CATCH
PRINT 'エラーが発生したよ!';
END CATCH;
カーソルの使い方
PL/pgSQL:カーソルは暗黙的で、ループの中で使える。
FOR row IN SELECT * FROM students LOOP
RAISE NOTICE '学生: %', row.name;
END LOOP;
PL/SQL:カーソルは明示的に宣言する必要がある。例:
DECLARE
CURSOR student_cursor IS SELECT * FROM students;
student_row students%ROWTYPE;
BEGIN
OPEN student_cursor;
FETCH student_cursor INTO student_row;
CLOSE student_cursor;
END;
T-SQL:CURSORキーワードでカーソルを宣言する。
DECLARE student_cursor CURSOR FOR SELECT name FROM students;
OPEN student_cursor;
FETCH NEXT FROM student_cursor;
CLOSE student_cursor;
DEALLOCATE student_cursor;
トランザクションの扱い
PL/pgSQL:トランザクションはBEGIN、COMMIT、ROLLBACKで管理する。
PL/SQL:トランザクションも同じくCOMMIT、ROLLBACKで管理、SAVEPOINTもサポート。
T-SQL:トランザクション開始を示すBEGIN TRANSACTIONが追加されてる。
JSONサポート
PL/pgSQL:JSONやJSONB型で強力なJSON操作ができる。例:
SELECT data->>'key' FROM json_table;
PL/SQL:JSONサポートは後から追加されて、ちょっと柔軟性が低い。
T-SQL:JSON_QUERYやJSON_VALUE関数でJSON操作がすごく便利。
PL/pgSQL、PL/SQL、T-SQLはいつ使う?
PL/pgSQL:
- DBがPostgreSQLならこれ一択。
JSONBや配列など強力なデータ型サポートで大量データ処理に最適。- オープンなエコシステムで柔軟性も高い。
PL/SQL:
- Oracle製品を使うならこれ。
- パッケージや組み込みプロシージャなど、データ操作のエコシステムが超充実。
T-SQL:
- Microsoft SQL Serverで使う。
- MicrosoftアプリやMicrosoft Azureとの連携に最適。
同じ課題をPL/pgSQL、PL/SQL、T-SQLで書く例
課題:学生の数を数えて結果を返す
PL/pgSQL:
CREATE FUNCTION count_students() RETURNS INT AS $$
DECLARE
total INT;
BEGIN
SELECT COUNT(*) INTO total FROM students;
RETURN total;
END;
$$ LANGUAGE plpgsql;
PL/SQL:
CREATE OR REPLACE FUNCTION count_students RETURN NUMBER IS
total NUMBER;
BEGIN
SELECT COUNT(*) INTO total FROM students;
RETURN total;
END;
T-SQL:
CREATE FUNCTION count_students()
RETURNS INT
AS
BEGIN
DECLARE @total INT;
SELECT @total = COUNT(*) FROM students;
RETURN @total;
END;
これでPL/pgSQL、PL/SQL、T-SQLのざっくりした違いがわかったよね。それぞれの言語には独自の特徴や使いどころがあって、それが個性になってる。どの言語(そしてDB)を選ぶかは、君のニーズやプロジェクトの特性次第だよ。
GO TO FULL VERSION