ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
パッケージとは
パッケージ (PACKAGE) は Oracle 独自の PL/SQL オブジェクトで、関連するプロシージャ・ファンクション・変数・型・カーソル・例外を 1 つの単位にまとめたものです。Java のクラスや C# のクラス、モジュールに近い概念。
業務システムでは「顧客処理パッケージ」「受注処理パッケージ」のように業務単位でまとめるのが定石で、肥大化したスタンドアロンプロシージャを整理する強力な手段になります。
パッケージの構成 — 2 段構成
| 区分 | 役割 |
|---|---|
| パッケージ仕様部 (PACKAGE) | 外部に公開するインターフェース。関数シグネチャ、定数、型を宣言 |
| パッケージ本体 (PACKAGE BODY) | 仕様部で宣言したプロシージャ / ファンクションの実装と、プライベートメンバー |
基本構文 — 仕様部
CREATE OR REPLACE PACKAGE pkg_customer AS
-- 公開定数
c_default_status CONSTANT VARCHAR2(10) := 'ACTIVE';
-- 公開型
TYPE customer_rec IS RECORD (
customer_id NUMBER,
customer_name VARCHAR2(100),
email VARCHAR2(255)
);
-- 公開プロシージャ / ファンクション
PROCEDURE register_customer(
p_name IN VARCHAR2,
p_email IN VARCHAR2,
p_id OUT NUMBER
);
FUNCTION find_customer(p_id IN NUMBER) RETURN customer_rec;
FUNCTION count_active_customers RETURN NUMBER;
END pkg_customer;
/
基本構文 — 本体 (PACKAGE BODY)
CREATE OR REPLACE PACKAGE BODY pkg_customer AS
-- プライベート変数 (仕様部に宣言なし -> 外部から見えない)
g_last_inserted_id NUMBER;
-- プライベートプロシージャ (内部ヘルパー)
PROCEDURE log_action(p_action VARCHAR2) IS
BEGIN
INSERT INTO action_log(action, log_time)
VALUES (p_action, SYSDATE);
END log_action;
-- 公開プロシージャの実装
PROCEDURE register_customer(
p_name IN VARCHAR2,
p_email IN VARCHAR2,
p_id OUT NUMBER
) IS
BEGIN
INSERT INTO customers(name, email, status)
VALUES (p_name, p_email, c_default_status)
RETURNING customer_id INTO p_id;
g_last_inserted_id := p_id;
log_action('REGISTER: ' || p_name);
END register_customer;
FUNCTION find_customer(p_id IN NUMBER) RETURN customer_rec IS
v_rec customer_rec;
BEGIN
SELECT customer_id, name, email
INTO v_rec
FROM customers
WHERE customer_id = p_id;
RETURN v_rec;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN NULL;
END find_customer;
FUNCTION count_active_customers RETURN NUMBER IS
v_count NUMBER;
BEGIN
SELECT COUNT(*) INTO v_count
FROM customers WHERE status = c_default_status;
RETURN v_count;
END count_active_customers;
-- パッケージ初期化ブロック (セッション内で初回参照時に 1 度だけ実行)
BEGIN
g_last_inserted_id := 0;
log_action('PACKAGE INITIALIZED');
END pkg_customer;
/
パッケージの呼び出し
-- 名前空間付きで呼び出し
DECLARE
v_id NUMBER;
v_cnt NUMBER;
v_rec pkg_customer.customer_rec;
BEGIN
pkg_customer.register_customer('山田太郎', 'yamada@example.com', v_id);
DBMS_OUTPUT.PUT_LINE('登録 ID: ' || v_id);
v_cnt := pkg_customer.count_active_customers;
DBMS_OUTPUT.PUT_LINE('アクティブ件数: ' || v_cnt);
v_rec := pkg_customer.find_customer(v_id);
DBMS_OUTPUT.PUT_LINE('名前: ' || v_rec.customer_name);
END;
/
パッケージのメリット
| メリット | 詳細 |
|---|---|
| カプセル化 | 本体の実装変更が仕様部に影響しないなら、呼び出し側の再コンパイル不要 |
| 名前空間 | pkg_customer.find と pkg_order.find のように同名関数を共存させられる |
| セッション変数 | パッケージのグローバル変数はセッション内で値を保持 (擬似的なクラス変数) |
| パフォーマンス | 初回参照時にパッケージ全体がメモリにロードされる — 関連処理の連続実行が高速 |
| オーバーロード | 同名で引数の異なる関数を複数定義可 |
| 権限管理が楽 | パッケージ単位で EXECUTE 権限を付与 |
パッケージのプライベートとパブリック
| 宣言場所 | 公開範囲 |
|---|---|
| 仕様部に宣言 + 本体に実装 | パブリック (外部から呼べる) |
| 本体のみに宣言 + 実装 | プライベート (パッケージ内部のみ) |
パッケージ初期化ブロック
パッケージ本体の末尾に BEGIN ... END; を書くと、そのパッケージがセッション内で初めて参照されたときに 1 回だけ実行されます。設定読み込みや初期データ取得に便利。
CREATE OR REPLACE PACKAGE BODY pkg_config AS
g_app_name VARCHAR2(100);
g_environment VARCHAR2(20);
FUNCTION app_name RETURN VARCHAR2 IS
BEGIN RETURN g_app_name; END;
FUNCTION environment RETURN VARCHAR2 IS
BEGIN RETURN g_environment; END;
BEGIN
-- セッション開始後、最初に pkg_config が参照されたタイミングで実行
SELECT name, env INTO g_app_name, g_environment
FROM app_config WHERE active = 'Y' AND ROWNUM = 1;
END pkg_config;
/
オーバーロード
CREATE OR REPLACE PACKAGE pkg_util AS
FUNCTION fmt(p_num IN NUMBER) RETURN VARCHAR2;
FUNCTION fmt(p_date IN DATE) RETURN VARCHAR2;
FUNCTION fmt(p_text IN VARCHAR2) RETURN VARCHAR2;
END pkg_util;
/
CREATE OR REPLACE PACKAGE BODY pkg_util AS
FUNCTION fmt(p_num IN NUMBER) RETURN VARCHAR2 IS
BEGIN RETURN TO_CHAR(p_num, 'FM999,999,990.00'); END;
FUNCTION fmt(p_date IN DATE) RETURN VARCHAR2 IS
BEGIN RETURN TO_CHAR(p_date, 'YYYY-MM-DD HH24:MI:SS'); END;
FUNCTION fmt(p_text IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN RETURN '[' || p_text || ']'; END;
END pkg_util;
/
パッケージの管理
-- パッケージ一覧
SELECT object_name, status
FROM user_objects
WHERE object_type IN ('PACKAGE','PACKAGE BODY');
-- 仕様部 / 本体のソース取得
SELECT text
FROM user_source
WHERE name = 'PKG_CUSTOMER' AND type = 'PACKAGE'
ORDER BY line;
-- パッケージ削除
DROP PACKAGE pkg_customer; -- 仕様部 + 本体 ともに削除
DROP PACKAGE BODY pkg_customer; -- 本体のみ
設計のコツ
- 業務単位でパッケージを切る (顧客 / 受注 / 在庫など)
- 仕様部は安定させる — 本体だけ変更すれば呼び出し側の再コンパイル不要
- セッション変数は濫用しない — 接続プール環境ではセッション再利用で状態が漏れる
- プライベートヘルパーは積極的に活用 — 仕様部を肥大化させない
- 定数 (CONSTANT) を仕様部に集約してマジックナンバーを排除
FAQ
Q: パッケージとプロシージャ単独はどちらを使うべき?
A: パッケージ推奨。名前空間、初期化、グローバル変数、依存関係解決の安定性などメリットが大きい。スタンドアロンプロシージャは依存先の変更でステータスが INVALID になりやすい。
Q: パッケージのグローバル変数はトランザクション単位?
A: いいえ、セッション単位で保持される。COMMIT / ROLLBACK では消えない。DBMS_SESSION.RESET_PACKAGE で明示的にリセット可。
Q: 本体だけ変更したのに呼び出し側がエラーになる
A: 仕様部のタイムスタンプが変わると呼び出し側が INVALID になる仕様。ALTER ... COMPILE で再コンパイルするか、シグネチャ依存性を使う設定にしておく。
関連
- マテリアライズド・ビュー — Oracle のもうひとつの強力な機能
- プロシージャ / ファンクション — 単体の PL/SQL オブジェクト
- カーソル / 例外処理 — PL/SQL の基本構文
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- IPv6とは|128bitアドレス・コロン16進表記/::省略・リンクローカル・SLAAC・デュアルスタック NEW 2026-06-22 12:34:44
- VPNとは|暗号トンネル・サイト間/リモートアクセス・IPsec/SSL-VPN/WireGuardを解説 NEW 2026-06-22 12:19:10
- MAC アドレスフィルタリングの仕組みと限界 | ネットワーク入門 NEW 2026-06-22 12:19:10
- WebRTC とは ブラウザ間 P2P の音声・映像・データ通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- gRPC とは HTTP/2 + Protocol Buffers の高速 RPC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/3 (QUIC) とは UDP ベースの低遅延 Web 通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/2 とは 多重化・HPACK・バイナリフレーム | ネットワーク入門 NEW 2026-06-22 12:17:25
- Web通信プロトコル入門 HTTP/2・HTTP/3・WebSocket・gRPC・WebRTC | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebSocket とは 全二重リアルタイム通信 ws/wss | ネットワーク入門 NEW 2026-06-22 12:17:25
- ファイアウォールとは|パケットフィルタ・ステートフル・DMZ・次世代FW(L4/L7)を解説 NEW 2026-06-22 12:17:24
- iptables/nftablesとは|テーブル・チェーン・ルール例・永続化をLinux視点で解説 NEW 2026-06-22 12:17:24
- HAProxy とは frontend/backend と設定例 | ネットワーク入門 NEW 2026-06-22 12:17:24
- 証明書と認証局(CA)とは|X.509・信頼チェーン・DV/OV/EV・失効(CRL/OCSP)を解説 NEW 2026-06-22 12:17:24
- CDN とは エッジキャッシュ・TTL・Cloudflare/CloudFront | ネットワーク入門 NEW 2026-06-22 12:17:24
- TLS/SSLの仕組み|ハンドシェイク・暗号スイート・前方秘匿性・証明書検証をわかりやすく解説 NEW 2026-06-22 12:17:24
コメントを削除してもよろしいでしょうか?