PL/SQLはProcedural Language/SQLの略で、OracleがSQLに手続き型プログラミング(変数・制御文・例外処理・サブルーチン)を加えたOracle専用のプログラミング言語です。学習の最初に必ず出会うのが「DECLARE/BEGIN/EXCEPTION/END」の4セクション構造ですが、入門書の多くはこの基本形を示して「詳しくは次章」で終わってしまいます。
実務でPL/SQLを書き始めると、セミコロン(;)とスラッシュ(/)の使い分け、DBMS_OUTPUTが表示されない原因、無名ブロックとストアドプロシージャの違い、ブロックの7種類(匿名/プロシージャ/ファンクション/パッケージ/トリガー/型メソッド等)、USER_ERRORSでコンパイル失敗を追跡する方法など、入門書では扱われない実用知識が次々必要になります。
この記事では、PL/SQLの基本構文を初心者向けの丁寧さと実務レベルの深さで両立させます。4セクション詳解、7種類のブロック形態、セミコロン/スラッシュ使い分け、DBMS_OUTPUTの設定、コメント2種類、コンパイルエラー(PLS-00103等)の読み方、ラベル・ネストブロック、変数・代入、学習ロードマップまで、ゼロから始めてPL/SQL開発の現場に立てるレベルに引き上げる2026年版の決定版です。関連は【PL/SQL】IF文完全ガイド/【PL/SQL】例外処理完全ガイド/【PL/SQL】ループ処理完全ガイド/【PL/SQL】変数・定数完全ガイドも順次ご参照ください。
この記事で学べること
- PL/SQLと通常SQLの決定的な違い
- PL/SQLブロックの4セクション(DECLARE/BEGIN/EXCEPTION/END)完全解説
- ブロック7種類:匿名/プロシージャ/ファンクション/パッケージ/トリガー/型メソッド等
- セミコロン(
;)とスラッシュ(/)の使い分け DBMS_OUTPUT.PUT_LINEが表示されない時のSERVEROUTPUT設定- コメント2種類(
--//* */)とドキュメントコメント - コンパイルエラー(PLS-00103/PLS-00201等)の読み方と
USER_ERRORSビュー - 無名ブロック vs 名前付きブロック(ストアドプロシージャ/ファンクション)の比較
- ラベル付きブロック(
<<label>>)とネストの基本 - 変数・代入(
:=)・NULL 初期値の基礎 - 実行環境別の使い方(SQL*Plus/SQLcl/SQL Developer/VS Code Database Client)
- PL/SQL学習ロードマップ(16ステップ)
30秒で分かるPL/SQLブロックの基本
-- ① 最小:BEGIN ~ END;だけでも動く
BEGIN
DBMS_OUTPUT.PUT_LINE('Hello PL/SQL');
END;
/
-- ② フル構成:4セクション
DECLARE
v_name VARCHAR2(50); -- 変数宣言
v_count NUMBER := 0; -- 初期値付き
BEGIN
v_name := 'PL/SQL';
v_count := v_count + 1;
DBMS_OUTPUT.PUT_LINE('Hello ' || v_name);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('エラー: ' || SQLERRM);
RAISE;
END;
/
3つの暗記ポイント:①DECLAREとEXCEPTIONは省略可、BEGIN~END;が最小構成、②代入は:=(=ではない、=は比較演算子)、③ブロック末尾はEND;+スラッシュ/(ツール実行用)。
PL/SQLと通常SQLの違い
PL/SQLの最大のメリット
ネットワークラウンドトリップ削減が最大の強み。「100件取得→判定→更新」を通常SQLで書くと3往復、PL/SQLなら1往復で完結。大量データ処理が劇的に高速化します。さらにSQLインジェクション耐性、トリガー/パッケージ化によるロジック一元管理、業務ルール集約などのメリットもあります。
4セクション構造の詳解
[<<ラベル名>>]
DECLARE ← 省略可
-- 変数/定数/例外/カーソル/ネスト型の宣言
BEGIN ← 必須
-- 実行本体(SQL実行・PL/SQL制御文)
EXCEPTION ← 省略可
WHEN 例外名 THEN
-- 例外処理
END [ラベル名]; ← 必須(セミコロン含む)
/ ← ツール実行の合図(スクリプト内必須)
①DECLARE:宣言セクション(省略可)
DECLARE -- 変数 v_name VARCHAR2(50); v_count NUMBER := 0; -- 初期値 v_flag BOOLEAN DEFAULT FALSE; -- := でも DEFAULT でも同じ -- 定数 c_tax_rate CONSTANT NUMBER := 0.10; -- 型継承 v_email users.email%TYPE; -- users.emailと同じ型 v_user users%ROWTYPE; -- users全列のレコード -- カスタム型 TYPE t_ids IS TABLE OF NUMBER; v_ids t_ids := t_ids(); -- 例外 e_custom EXCEPTION; PRAGMA EXCEPTION_INIT(e_custom, -20001); -- カーソル CURSOR cur_users IS SELECT id FROM users WHERE status = 'A'; BEGIN NULL; END;
DECLAREで宣言できるもの
- 変数(
VARCHAR2/NUMBER/DATE/BOOLEAN等) - 定数(
CONSTANTキーワード) - ユーザー定義型(
TYPE ... IS RECORD/TABLE/VARRAY) - サブタイプ(
SUBTYPE) - 例外(
EXCEPTION+PRAGMA EXCEPTION_INIT) - カーソル(
CURSOR ... IS SELECT ...) - 入れ子ブロック内ローカルプロシージャ/ファンクション
詳細は【PL/SQL】変数・定数完全ガイド参照。
②BEGIN:実行セクション(必須)
BEGIN -- SQL文 SELECT email INTO v_email FROM users WHERE id = 1; INSERT INTO orders VALUES (...); UPDATE users SET status = 'active' WHERE id = 1; DELETE FROM logs WHERE created_at < SYSDATE - 365; -- 代入 v_name := 'Taro'; v_count := v_count + 1; -- 制御文 IF v_count > 10 THEN ... FOR i IN 1..10 LOOP ... WHILE v_flag LOOP ... CASE v_type WHEN 'A' THEN ... -- サブプログラム呼び出し my_procedure(p_id => 1); v_result := my_function(p_x => 10); -- 例外を手動発生 RAISE e_custom; RAISE_APPLICATION_ERROR(-20001, 'エラー'); -- トランザクション制御 COMMIT; ROLLBACK; SAVEPOINT sp_1; END;
③EXCEPTION:例外処理セクション(省略可)
BEGIN
SELECT email INTO v_email FROM users WHERE id = 999; -- 0件ならNO_DATA_FOUND
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('該当なし');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('複数件検出');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('予期せぬエラー: ' || SQLCODE || ' / ' || SQLERRM);
RAISE; -- 呼出し元に再送出
END;
EXCEPTIONの3つの鉄則:①具体例外(NO_DATA_FOUND等)を先に書く、②WHEN OTHERSは最後の網、③WHEN OTHERS THEN NULL;は例外窒息のアンチパターン——必ずRAISEで再送出。詳細は【PL/SQL】例外処理完全ガイド参照。
④END:終了(必須)
-- 基本 END; -- ラベル付きブロックの終了時はラベル名で対応を明示 <<main_block>> BEGIN ... END main_block; -- ネストされたPROCEDUREの終了 CREATE OR REPLACE PROCEDURE calc_tax(p_amount IN NUMBER) IS BEGIN ... END calc_tax; -- プロシージャ名を書いて対応を明示
PL/SQLブロックの7種類
「4セクション」は共通ですが、ブロック全体を「何として定義するか」で7種類に分かれます。
①匿名ブロック(Anonymous Block)
-- 保存されない。実行即解放
BEGIN
DBMS_OUTPUT.PUT_LINE('匿名ブロック');
END;
/
-- ツール(SQLcl/SQL Developer)から直接実行
-- 試行錯誤やバッチ実行に使う
②ストアドプロシージャ
CREATE OR REPLACE PROCEDURE update_user_status(
p_id IN NUMBER,
p_status IN VARCHAR2
) IS
BEGIN
UPDATE users SET status = p_status, updated_at = SYSDATE
WHERE id = p_id;
IF SQL%ROWCOUNT = 0 THEN
RAISE_APPLICATION_ERROR(-20001, 'ユーザーが見つかりません');
END IF;
END update_user_status;
/
-- 呼び出し
BEGIN
update_user_status(p_id => 1, p_status => 'active');
END;
/
③ストアドファンクション
CREATE OR REPLACE FUNCTION get_user_count(
p_status IN VARCHAR2
) RETURN NUMBER IS
v_count NUMBER;
BEGIN
SELECT COUNT(*) INTO v_count FROM users WHERE status = p_status;
RETURN v_count;
END get_user_count;
/
-- PL/SQL内でも
DECLARE
v_n NUMBER;
BEGIN
v_n := get_user_count('active');
DBMS_OUTPUT.PUT_LINE('active: ' || v_n);
END;
-- SQL文内でも使える
SELECT get_user_count('active') AS active_count FROM dual;
プロシージャとファンクションの詳細
両者の違い・引数モード(IN/OUT/IN OUT)・戻り値型の設計は【PL/SQL】ストアドプロシージャとファンクションの違いと作り方/【PL/SQL】IN・OUT・IN OUTパラメータの完全ガイドで詳解。
④パッケージ(PACKAGE + PACKAGE BODY)
-- 仕様(インタフェース公開)
CREATE OR REPLACE PACKAGE pkg_user IS
PROCEDURE activate(p_id IN NUMBER);
FUNCTION count_active RETURN NUMBER;
END pkg_user;
/
-- 本体(実装)
CREATE OR REPLACE PACKAGE BODY pkg_user IS
PROCEDURE activate(p_id IN NUMBER) IS
BEGIN
UPDATE users SET status = 'active' WHERE id = p_id;
END activate;
FUNCTION count_active RETURN NUMBER IS
v_n NUMBER;
BEGIN
SELECT COUNT(*) INTO v_n FROM users WHERE status = 'active';
RETURN v_n;
END count_active;
END pkg_user;
/
-- 呼び出し
BEGIN
pkg_user.activate(1);
DBMS_OUTPUT.PUT_LINE(pkg_user.count_active);
END;
⑤トリガー/⑥オブジェクト型メソッド/⑦WITH FUNCTION
詳細は別記事で
- トリガー詳解:【PL/SQL】トリガー完全ガイド
- パッケージ詳解:【PL/SQL】パッケージを使ったコード管理と再利用性向上
- WITH FUNCTION詳解:【PL/SQL】WITH FUNCTION句を使ってSQL内に関数を埋め込む方法
セミコロン(;)とスラッシュ(/)の使い分け
PL/SQL初心者が必ず混乱するのが;と/の使い分けです。役割がまったく違います。
BEGIN
DBMS_OUTPUT.PUT_LINE('A'); -- ここで1文終了 → ;
DBMS_OUTPUT.PUT_LINE('B'); -- こっちも文終了 → ;
END; -- ブロック終了 → ;
/ -- ツールへ「実行しろ」の合図(行頭単独)
よくある間違い:①ENDの後にセミコロンが無い→コンパイルエラー、②END;の同じ行に/を書く→/が識別子扱いされエラー、③/をブロック内に書く→SQL*Plusが早期実行してエラー。/は必ずブロック終了後の次の行頭に単独で書きます。
スラッシュは”ツール向けコマンド”
/はSQL*Plus/SQLcl/SQL Developerが「ここまでをサーバーに送って実行」と解釈するコマンドで、PL/SQL言語そのものの一部ではありません。アプリケーション(JavaやPython)からPL/SQLを呼ぶ時には不要。一方でスクリプトファイル(.sql)で複数のブロックを並べて実行する時は必須です。
コメント2種類とドキュメント
-- 単一行コメント(行末まで)
DECLARE
v_count NUMBER := 0; -- 初期化
BEGIN
/*
複数行コメント
ブロック全体を囲む
*/
v_count := v_count + 1;
/* インラインの /* ネスト */ は許可されない */
-- ↑ネストはサポート無し、上記はコメント途中で終了する
END;
プロシージャのドキュメントコメント
CREATE OR REPLACE PROCEDURE calc_shipping_fee( p_order_id IN NUMBER, p_country IN VARCHAR2, p_fee OUT NUMBER ) IS /* ------------------------------------------------------------------------ Procedure : calc_shipping_fee Purpose : 注文IDと配送国から送料を計算してOUTに返す Parameters : p_order_id : 注文ID(必須) p_country : 配送国(ISO 3166-1 alpha-2) p_fee : 送料(OUT) Errors : -20001 : 注文が見つからない -20002 : 配送先が対応外 Author : team-order / 2026-04-23 ------------------------------------------------------------------------ */ BEGIN -- 実装 NULL; END calc_shipping_fee;
ドキュメントコメントはパラメータ/戻り値/例外/改訂履歴をパッケージ/プロシージャ冒頭に書くのが業界慣習。USER_SOURCEビューで全ソースをgrepすれば、プロジェクト全体のドキュメントとして機能します。
DBMS_OUTPUTの使い方と”表示されない”問題の解決
-- SQL*Plus / SQLcl / SQL Developer で実行前に必須
SET SERVEROUTPUT ON;
SET SERVEROUTPUT ON SIZE UNLIMITED;
SET SERVEROUTPUT ON FORMAT WRAPPED;
-- これ無しだとPUT_LINEの内容は表示されない
-- 基本の出力
BEGIN
DBMS_OUTPUT.PUT_LINE('Hello');
DBMS_OUTPUT.PUT_LINE('Count = ' || 10);
DBMS_OUTPUT.PUT_LINE(SYSTIMESTAMP);
END;
/
-- 改行せず追記(PUT+NEW_LINE)
BEGIN
DBMS_OUTPUT.PUT('A');
DBMS_OUTPUT.PUT('B');
DBMS_OUTPUT.NEW_LINE; -- ここで改行
-- 出力: AB
END;
DBMS_OUTPUT.PUT_LINEは本番ロギングに使わない。バッファに溜まって終了時に吐かれるだけで、途中取得困難。本番ではPRAGMA AUTONOMOUS_TRANSACTION付きのログプロシージャでテーブルに記録する方式が定石。詳細は【PL/SQL】例外処理完全ガイド参照。
コンパイルとエラーメッセージの読み方
-- ①コンパイル後すぐに SHOW ERRORS
CREATE OR REPLACE PROCEDURE my_proc IS
BEGIN
invalid_statement_here; -- 意図的にエラー
END;
/
SHOW ERRORS;
-- Errors for PROCEDURE MY_PROC:
-- LINE/COL ERROR
-- -------- -------------------------------------------------
-- 3/3 PLS-00201: identifier 'INVALID_STATEMENT_HERE' must be declared
-- ② USER_ERRORS ビューで確認
SELECT line, position, text FROM user_errors
WHERE name = 'MY_PROC' AND type = 'PROCEDURE'
ORDER BY sequence;
-- ③ DBMS_UTILITY.FORMAT_ERROR_STACK(実行時用)
BEGIN
my_proc;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_STACK);
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
END;
よくあるコンパイルエラーTOP5
実行環境別の使い方
# インストール(Javaが必要)
# https://www.oracle.com/database/sqldeveloper/ からダウンロード
# 接続
sql user/password@host:port/service
# スクリプト実行
SQL> @my_script.sql
# PL/SQLブロック直接入力
SQL> SET SERVEROUTPUT ON;
SQL> BEGIN
2 DBMS_OUTPUT.PUT_LINE('Hello');
3 END;
4 /
-- Oracle社公式GUI(Javaベース) -- SQLワークシートにPL/SQLを貼って F5(Run Script)または Ctrl+Enter(Run) -- SET SERVEROUTPUT ON; を実行する必要あり -- View → Dbms Output ウィンドウで出力確認
-- 拡張: Database Client (cweijan.vscode-mysql-client2) で Oracle接続 -- .sql ファイルを開いて Ctrl+Alt+E で PL/SQL ブロック実行 -- DBMS_OUTPUTの受信は拡張によって異なる
2026年のおすすめ
CLI好きはSQLcl(標準同梱のオラクルCLI)、GUI好きはSQL Developer(Oracle公式無料)、VS Code好きはDatabase Client拡張。本番のPL/SQL開発者はSQLcl+Gitでのソース管理が主流。SQL Developerのコード補完はOracle専用構文の強みがあり、初学者にはSQL Developer推奨です。
ラベル付きブロックとネスト
<<outer>>
DECLARE
v_x NUMBER := 1;
BEGIN
<<inner>>
DECLARE
v_x NUMBER := 2; -- 外のv_xと同名(内側で隠蔽)
BEGIN
DBMS_OUTPUT.PUT_LINE(v_x); -- 2(内側)
DBMS_OUTPUT.PUT_LINE(outer.v_x); -- 1(外側をラベルで参照)
END inner;
FOR i IN 1..3 LOOP
FOR j IN 1..3 LOOP
EXIT outer WHEN i * j > 5; -- 外ループまで一気に脱出
END LOOP;
END LOOP;
END outer;
ラベルの効用
- 変数名衝突時に
ラベル.変数で外側参照 - ネストループからの一気脱出(
EXIT ラベル名/CONTINUE ラベル名) - 長いブロックの
END ラベル名;で対応明示 - ネストブロックの詳細は【PL/SQL】ネストされたブロックの書き方とスコープの考え方参照
変数・代入・NULLの基礎
DECLARE
v_a NUMBER := 10;
v_b NUMBER;
v_c NUMBER;
BEGIN
-- 代入は := (コロンイコール)
v_b := v_a;
v_c := v_a + v_b;
-- 比較は = (イコール)
IF v_a = v_b THEN
DBMS_OUTPUT.PUT_LINE('等しい');
END IF;
-- NULL比較は IS NULL
IF v_b IS NULL THEN
DBMS_OUTPUT.PUT_LINE('NULLです');
END IF;
-- NULLとの = 比較は常にNULL(FALSEでもTRUEでもない!)
IF v_b = NULL THEN -- この条件は常にFALSE扱いになる
DBMS_OUTPUT.PUT_LINE('到達不能');
END IF;
END;
3値論理の罠:PL/SQLはTRUE/FALSE/NULLの3値論理です。NULL = NULL、NULL != 10はどちらもNULL(TRUEでもFALSEでもない)で、IF文ではELSEに落ちます。NULLを明示的に扱うにはIS NULL/IS NOT NULLを使用。詳細は【PL/SQL】IF文完全ガイド参照。
変数宣言・データ型・定数(CONSTANT)・%TYPE/%ROWTYPEなどの深掘りは【PL/SQL】変数・定数完全ガイドを参照。
PL/SQL学習ロードマップ(16ステップ)
【初級(1〜2週間)】 1. 4セクション構造(本記事) 2. 変数・定数・データ型 3. IF文とCASE文 4. LOOPとFORループ 5. SELECT INTO と例外処理基礎 【中級(2〜4週間)】 6. カーソル(Cursor FOR Loop) 7. %TYPE / %ROWTYPE 8. ストアドプロシージャとファンクション 9. IN/OUT/IN OUTパラメータ 10. 例外処理の完全理解(RAISE_APPLICATION_ERROR) 【上級(1〜3ヶ月)】 11. パッケージ(仕様と本体) 12. トリガー(BEFORE/AFTER/Compound) 13. コレクション(TABLE/VARRAY/RECORD) 14. バルク処理(BULK COLLECT/FORALL) 15. 動的SQL(EXECUTE IMMEDIATE) 16. 自律トランザクション/SAVEPOINT
おすすめ学習記事
- 初級2:変数・定数完全ガイド
- 初級3:IF文完全ガイド
- 初級4:ループ処理完全ガイド
- 初級5:例外処理完全ガイド
- 中級6:カーソル完全ガイド
- 中級8:プロシージャとファンクション
- 中級9:IN/OUT/IN OUT完全ガイド
- 上級11:パッケージ活用
- 上級12:トリガー完全ガイド
- 上級14:BULK COLLECT+FORALL
- 上級15:動的SQL
- 上級16:AUTONOMOUS TRANSACTION
初学者のつまずきポイント10選
①DBMS_OUTPUT.PUT_LINEが表示されない:SET SERVEROUTPUT ON;を忘れているか、ツールの出力ウィンドウが開いていない。
②/の位置で混乱:END;の次の行・行頭・単独でないとエラー。END; /同じ行はNG。
③代入は:=、比較は=:PL/SQL初心者が必ず踏む罠。多くの言語とは逆。
④SELECT INTOで0件エラー:NO_DATA_FOUND例外が発生。必ずEXCEPTIONでハンドリング。
⑤ELSIFの綴り:ELSE IFではなくELSIF(スペース無し)。
⑥CONSTANT変数への代入エラー:PLS-00363。定数は再代入不可。
⑦NULL比較で= NULL:常にNULL評価されTHENに入らない。IS NULLを使用。
⑧予約語を変数名に使ってしまう:date、count、level等。v_プレフィックスで回避。予約語完全ガイド参照。
⑨変数を宣言する場所がわからない:必ずDECLAREセクション(BEGINの前)。BEGIN内で新規変数は定義不可。
⑩コメントアウトの入れ子:/* ... /* */ ... */はネスト不可で最初の*/でコメント終了。--(単一行)を多用する方が安全。
よくある質問
DECLAREを書かずBEGINから始められます。ただしストアドプロシージャ/ファンクション/パッケージ本体ではDECLAREキーワード自体は書かずIS/ASの後に変数宣言が続きます。/(スラッシュ)はいつ必要?DBMS_OUTPUTが表示されないSET SERVEROUTPUT ON;を実行(SQL*Plus/SQLcl)、②SQL Developerなら View → Dbms Outputウィンドウを開き接続を追加、③SET SERVEROUTPUT ON SIZE UNLIMITED;でバッファ拡大。なお本番ロギングには使わない(バッファ制限+終了時一括出力)。DECLARE BEGIN ... END;の1回限り実行型、データベースに保存されない。ストアドプロシージャはCREATE OR REPLACE PROCEDURE ...でDBにコンパイル済み状態で保存、何度でも再利用できる。繰り返し実行するロジックはストアド化、試行錯誤は無名ブロック、と使い分けます。ISとASはどちらを使う?CREATE PROCEDURE ... IS BEGIN ... END;でもCREATE PROCEDURE ... AS BEGIN ... END;でも動きます。Oracleの慣習はIS(プロシージャ/ファンクション)、ASはビュー定義(CREATE VIEW ... AS SELECT)でよく見ます。BEGIN...ENDのストアドプロシージャ構文、PostgreSQL はPL/pgSQL、SQL ServerはT-SQL。基本構造は似ていますが構文は独立しています。;)を書き忘れるとどうなる?END;)」の2箇所必須。特にENDの後の;忘れが多発します。#は使える?--(単一行)//* */(複数行)の2種類のみ。#はエラーになります(PLS-00103)。シェルスクリプトやPythonの癖で#を書くとコンパイルエラーに。BEGIN/IF)、②識別子小文字+スネークケース(v_user_id)、③2スペースインデント、④THEN/LOOPの前で改行、⑤END IF;/END LOOP;/END;を左寄せ、の5点を守ると読みやすい。SELECT get_user_count('active') FROM dual;のように呼び出せます。ただしDETERMINISTIC指定がないとSQL最適化が制限され、関数内でDMLをするとSELECT失敗するなど制約があります。12c+のWITH FUNCTION句でインラインファンクション定義も可能。関連記事
- 【PL/SQL】IF文完全ガイド — 条件分岐と3値論理
- 【PL/SQL】例外処理完全ガイド — EXCEPTIONセクションの深掘り
- 【PL/SQL】ループ処理完全ガイド — LOOP/WHILE/FOR/Cursor FOR Loop
- 【PL/SQL】カーソル完全ガイド — 結果セットの行単位処理
- 【PL/SQL】変数・定数完全ガイド — DECLAREセクションの詳解
- 【PL/SQL】予約語完全ガイド — 変数名に使えないキーワード
- 【PL/SQL】トリガー完全ガイド — 自動実行ブロックの作り方
- 【PL/SQL】ストアドプロシージャとファンクションの違いと作り方 — 名前付きブロックの作成
- 【PL/SQL】バルク処理で高速化!FORALLとBULK COLLECTの使い方 — 大量データの高速処理
- 【PL/SQL】ネストされたブロックの書き方とスコープの考え方 — ブロックの入れ子
- 【PL/SQL】IN・OUT・IN OUTパラメータの完全ガイド — サブプログラムの引数
- 【PL/SQL】動的SQLのセキュアな書き方 — EXECUTE IMMEDIATEの使い方
- 【PL/SQL】パッケージを使ったコード管理と再利用性向上 — 仕様と本体の分離
- 【PL/SQL】AUTONOMOUS TRANSACTIONで独立した処理を行う方法 — 自律トランザクション
まとめ
- PL/SQLはOracle専用の手続き型拡張SQL、ラウンドトリップ削減が最大のメリット
- ブロックの4セクション:DECLARE(省略可)/BEGIN(必須)/EXCEPTION(省略可)/END;(必須)
- ブロック7種類:匿名/プロシージャ/ファンクション/パッケージ/トリガー/型メソッド/WITH FUNCTION
- セミコロン(
;)は文の終了、スラッシュ(/)はツールへの実行合図 - 代入は
:=、比較は=、NULL比較はIS NULL(3値論理) - コメントは
--(単一行)//* */(複数行、ネスト不可) DBMS_OUTPUTはSET SERVEROUTPUT ON;必須、本番ロギングには使わない- コンパイルエラーは
SHOW ERRORS/USER_ERRORSビューで確認 - 主要エラー:PLS-00103(構文)/PLS-00201(未宣言)/PLS-00306(引数)
- 実行環境:SQLcl(CLI)/SQL Developer(GUI)/VS Code拡張
- ラベル付き(
<<name>>)で変数衝突解決・ネストループ一括脱出 - 学習順:4セクション→変数→IF→LOOP→例外→カーソル→プロシージャ→パッケージ→トリガー→バルク処理
- 初学者の罠:
SERVEROUTPUT忘れ//の位置/:=と=/NULL比較/ELSIFの綴り
PL/SQLはSQLに手続き型構文を加えたOracle最強のサーバーサイド言語。本記事の4セクション構造・7種類のブロック・セミコロン/スラッシュ使い分け・エラーメッセージの読み方・学習ロードマップを押さえれば、ゼロから始めて実務のPL/SQL開発に立てるレベルへ着実に進めます。次のステップとして変数・定数→IF文→ループ→例外処理→カーソル→プロシージャ/ファンクションの順で学習を進めましょう。

