PLS-00306: wrong number or types of arguments in call to 'xxx' は、PL/SQLでプロシージャ、ファンクション、パッケージ内サブプログラムを呼び出した時に、実際に渡した引数が宣言と一致しない場合に発生するコンパイルエラーです。
原因は、引数の個数違い、型違い、順番違い、OUT / IN OUT にリテラルを渡している、名前付き記法のパラメータ名ミス、デフォルト値の誤解、オーバーロード解決の失敗などです。
PLS-00306が出たら、呼び出しているサブプログラム名を確認し、
ALL_ARGUMENTS または USER_ARGUMENTS で宣言側の引数を見ます。そのうえで、呼び出し側の引数の数、型、順番、IN/OUT/IN OUT、名前付き記法の名前、デフォルト値の有無を照合します。ORA-06550 と一緒に出る場合も、直すべき中心は後続のPLS-00306です。PLS-00306とは
Oracle公式の説明では、PLS-00306は、呼び出し先のサブプログラムに対して引数の数または型が合っていない時に発生します。サブプログラム名の綴り、宣言位置、呼び出し方、引数のデータ型が正しいかを確認する必要があります。
PLS-00201が「識別子が見えない」エラーなら、PLS-00306は「呼び出し先は見えているが、渡し方が合っていない」エラーです。識別子解決の問題は PLS-00201の原因と解決方法 も確認してください。
| 表示例 | よくある意味 | 最初に見る場所 |
|---|---|---|
PLS-00306: wrong number or types of arguments in call to 'SYNC_ORDER' |
引数の数または型が違う | ALL_ARGUMENTS |
PLS-00306 + ORA-06550 |
PL/SQLブロック内の呼び出し失敗 | 後続のPLS-00306行 |
| パッケージ内プロシージャで発生 | 仕様部の宣言と呼び出しが不一致 | USER_ARGUMENTS / パッケージ仕様部 |
| アプリからだけ発生 | バインド型やOUT引数の扱いが違う | 実行SQL、ドライバのbind設定 |
まず確認する順番
PLS-00306では、呼び出し側だけ眺めても原因が見えないことがあります。宣言側と呼び出し側を並べて確認するのが近道です。
| 順番 | 確認すること | 使うもの |
|---|---|---|
| 1 | 呼び出し先の名前 | エラー内の call to 'xxx' |
| 2 | 宣言側の引数一覧 | ALL_ARGUMENTS / USER_ARGUMENTS |
| 3 | 呼び出し側の引数数 | 位置指定の個数、名前付き記法の数 |
| 4 | 引数の型 | DATA_TYPE、TYPE_NAME、%TYPE |
| 5 | 引数モード | IN / OUT / IN/OUT |
| 6 | デフォルト値の有無 | DEFAULTED |
| 7 | オーバーロードの有無 | OVERLOAD |
ALL_ARGUMENTSで引数定義を確認する
まず、呼び出し先の引数定義を ALL_ARGUMENTS で確認します。POSITION、ARGUMENT_NAME、DATA_TYPE、IN_OUT、DEFAULTED を見ると、呼び出し側との差分が分かります。
SELECT owner,
package_name,
object_name,
overload,
position,
argument_name,
data_type,
type_owner,
type_name,
in_out,
defaulted
FROM all_arguments
WHERE owner = 'APP_SCHEMA'
AND object_name = 'SYNC_ORDER'
ORDER BY package_name, object_name, overload, sequence;
ALL_ARGUMENTS は、現在のユーザーが参照できるプロシージャ・ファンクションの引数情報を返します。パッケージ内サブプログラムの場合は PACKAGE_NAME も確認してください。
パッケージ内の
PKG_ORDER.SYNC_ORDER を調べる場合、OBJECT_NAME はパッケージ名、PACKAGE_NAME はNULLになる環境やバージョン差を想定して、実データを見ながら条件を調整します。検索で出ない時は、まず対象スキーマの ALL_ARGUMENTS を広めに絞り込んで、列の入り方を確認してください。SELECT owner,
package_name,
object_name,
argument_name,
position,
sequence,
data_type,
in_out
FROM all_arguments
WHERE owner = 'APP_SCHEMA'
AND (package_name = 'PKG_ORDER' OR object_name = 'PKG_ORDER')
ORDER BY package_name, object_name, overload, sequence;
関数の場合、戻り値が POSITION = 0 として表示されることがあります。引数の1つとして数えないようにし、POSITION と ARGUMENT_NAME を見ながら実引数だけを照合します。
引数の数が違うケース
最も単純なのは、宣言より多い、または少ない引数を渡しているケースです。位置指定で呼び出している場合は、引数を1つ増減しただけで以降の意味もずれます。
CREATE OR REPLACE PROCEDURE p_sync_order( p_order_id IN NUMBER, p_status IN VARCHAR2 ) AS BEGIN NULL; END; / -- NG: 第2引数が足りない BEGIN p_sync_order(1001); END; / -- PLS-00306 -- OK BEGIN p_sync_order(1001, 'DONE'); END; /
引数の型が違うケース
引数の数が合っていても、型が合わなければPLS-00306になります。暗黙変換で通ることもありますが、DATE、BOOLEAN、レコード型、コレクション型では意図通りに解決されないことがあります。
CREATE OR REPLACE PROCEDURE p_set_due_date(
p_due_date IN DATE
) AS
BEGIN
NULL;
END;
/
-- NGになりやすい: 文字列を日付として渡している
BEGIN
p_set_due_date('2026-05-14');
END;
/
-- OK: DATEリテラルまたは明示変換
BEGIN
p_set_due_date(DATE '2026-05-14');
END;
/
日付文字列の扱いで別エラーになる場合は、日付変換系の記事もあわせて確認します。PLS-00306では、まず呼び出し先の型と実際に渡している値の型を合わせるのが基本です。
OUT / IN OUT引数にリテラルを渡しているケース
OUT や IN OUT 引数には、結果を書き戻せる変数が必要です。リテラル、式、関数戻り値を渡すと、引数として適切に扱えずPLS-00306や関連エラーになります。
CREATE OR REPLACE PROCEDURE p_get_status( p_order_id IN NUMBER, p_status OUT VARCHAR2 ) AS BEGIN p_status := 'DONE'; END; / -- NG: OUT引数に文字列リテラルは渡せない BEGIN p_get_status(1001, ''); END; / -- OK: 変数を渡す DECLARE v_status VARCHAR2(20); BEGIN p_get_status(1001, v_status); DBMS_OUTPUT.PUT_LINE(v_status); END; /
IN、OUT、IN OUTの違いは PL/SQLのIN・OUT・IN OUTパラメータ でも詳しく整理しています。
位置指定と名前付き記法を間違えているケース
PL/SQLでは、位置指定、名前付き記法、混合記法で引数を渡せます。名前付き記法は順番ミスを減らせますが、パラメータ名を間違えるとPLS-00306につながります。
CREATE OR REPLACE PROCEDURE p_create_user(
p_user_id IN NUMBER,
p_email IN VARCHAR2,
p_status IN VARCHAR2 DEFAULT 'ACTIVE'
) AS
BEGIN
NULL;
END;
/
-- OK: 名前付き記法
BEGIN
p_create_user(
p_user_id => 10,
p_email => 'a@example.com'
);
END;
/
-- NG: パラメータ名が違う
BEGIN
p_create_user(
user_id => 10,
email => 'a@example.com'
);
END;
/
デフォルト値を誤解しているケース
DEFAULT がある引数は省略できますが、すべての引数を自由に省略できるわけではありません。位置指定で途中の引数を飛ばしたい場合は、名前付き記法を使うのが安全です。
CREATE OR REPLACE PROCEDURE p_search_order(
p_customer_id IN NUMBER,
p_status IN VARCHAR2 DEFAULT 'ACTIVE',
p_limit IN NUMBER DEFAULT 100
) AS
BEGIN
NULL;
END;
/
-- OK: 末尾側のデフォルト引数を省略
BEGIN
p_search_order(10);
END;
/
-- OK: 途中を飛ばすなら名前付き記法
BEGIN
p_search_order(
p_customer_id => 10,
p_limit => 50
);
END;
/
オーバーロードで解決できないケース
同じ名前で引数違いのプロシージャやファンクションを複数定義している場合、Oracleは引数からどの定義を使うか解決します。型が曖昧だったり、どの定義にも一致しない場合にPLS-00306になります。
SELECT package_name,
object_name,
overload,
position,
argument_name,
data_type,
in_out
FROM all_arguments
WHERE owner = 'APP_SCHEMA'
AND package_name = 'PKG_ORDER'
AND object_name = 'SYNC_ORDER'
ORDER BY overload, sequence;
OVERLOAD が複数ある場合は、呼び出し側の引数がどの定義に一致するかを1つずつ照合します。文字列リテラルやNULLは型が曖昧になりやすいため、明示的に CAST する方法もあります。
CREATE OR REPLACE PACKAGE pkg_notify AS PROCEDURE send(p_user_id IN NUMBER); PROCEDURE send(p_email IN VARCHAR2); END pkg_notify; / -- NGになりやすい: NULLだけではどちらのsendか決められない BEGIN pkg_notify.send(NULL); END; / -- OK: 呼びたい定義の型を明示する BEGIN pkg_notify.send(CAST(NULL AS VARCHAR2)); END; /
レコード型・コレクション型の引数で発生するケース
レコード型やコレクション型は、見た目の構造が同じでも、別の型として定義されていれば互換とは限りません。パッケージ内で定義した型、SQLオブジェクト型、ローカル型を混同するとPLS-00306になります。
CREATE OR REPLACE PACKAGE pkg_order AS TYPE t_order_ids IS TABLE OF NUMBER; PROCEDURE close_orders(p_ids IN t_order_ids); END pkg_order; / -- OK: パッケージで定義された型を使う DECLARE v_ids pkg_order.t_order_ids := pkg_order.t_order_ids(1, 2, 3); BEGIN pkg_order.close_orders(v_ids); END; /
Oracle公式の ALL_ARGUMENTS 説明では、複合型引数の詳細確認には TYPE_NAME からPL/SQL型関連ビューを確認する流れも示されています。型名が一致しているか、パッケージ名まで含めて確認してください。
呼び出し先のパッケージやプロシージャを変更した直後に発生する場合は、依存オブジェクトの再コンパイル状況も確認します。無効オブジェクトの調査は ORA-04063の原因と解決方法、実行時に呼び出し先を見失う場合は ORA-06508の原因と解決方法 が近い確認先です。
アプリケーションから呼び出す時の注意
Java、C#、PHP、Pythonなどのアプリケーションからストアドプロシージャを呼ぶ場合も、バインド変数の数、型、方向が合っていないとPLS-00306になります。特に OUT 引数の登録漏れ、NUMBERとVARCHAR2の取り違え、DATE/TIMESTAMPの渡し方に注意します。
ストアドプロシージャとファンクションの使い分け自体を整理したい場合は、Oracleのストアドプロシージャとファンクションの違い も参考になります。PL/SQLの基本構文から確認したい場合は PL/SQLの基本 もあわせて確認してください。
| 確認項目 | よくあるミス | 対処 |
|---|---|---|
| バインド数 | プロシージャ引数より少ない/多い | 宣言と同じ数にする |
| バインド型 | NUMBERに文字列、DATEに文字列 | ドライバ側の型指定を合わせる |
| OUT引数 | OUTパラメータを登録していない | 出力パラメータとして登録する |
| 名前付き呼び出し | パラメータ名がDB側と違う | ALL_ARGUMENTS.ARGUMENT_NAME を確認 |
| パッケージ名 | スキーマやパッケージ修飾漏れ | 完全修飾名で呼ぶ |
ORA-06550と一緒に出る場合
PLS-00306は、匿名ブロックやアプリケーション経由の呼び出しで ORA-06550 と一緒に出ることが多いです。この場合、ORA-06550はPL/SQLブロック全体の失敗を示す入口で、後続のPLS-00306を直します。
BEGIN p_sync_order(1001); END; / -- ORA-06550: line 2, column 3: -- PLS-00306: wrong number or types of arguments in call to 'P_SYNC_ORDER' -- ORA-06550: line 2, column 3: -- PL/SQL: Statement ignored
本番障害時の調査SQLセット
本番でPLS-00306が出た場合は、呼び出し先の引数定義をすぐ確認できるSQLを用意しておくと早いです。
DEFINE owner_name = 'APP_SCHEMA'
DEFINE proc_name = 'SYNC_ORDER'
SELECT owner,
package_name,
object_name,
overload,
position,
argument_name,
data_type,
type_owner,
type_name,
in_out,
defaulted
FROM all_arguments
WHERE owner = UPPER('&owner_name')
AND object_name = UPPER('&proc_name')
ORDER BY package_name, object_name, overload, sequence;
よくある原因と対処一覧
| 原因 | 確認すること | 対処 |
|---|---|---|
| 引数の数が違う | POSITION と呼び出し引数数 |
不足/過剰な引数を直す |
| 型が違う | DATA_TYPE / TYPE_NAME |
型を合わせる、明示変換する |
| OUT/IN OUTにリテラルを渡した | IN_OUT |
変数を渡す |
| 名前付き記法の名前ミス | ARGUMENT_NAME |
正式な引数名を使う |
| デフォルト値の誤解 | DEFAULTED |
名前付き記法で省略する |
| オーバーロード不一致 | OVERLOAD |
一致する定義に合わせる |
| NULLで型が曖昧 | 複数の候補に一致するか | CAST(NULL AS ...) で型を明示する |
| 関数戻り値を引数に数えた | POSITION = 0 |
戻り値と実引数を分けて見る |
| 複合型が違う | TYPE_OWNER / TYPE_NAME |
同じ型定義を使う |
PLS-00306と関連エラーの違い
| エラー | 意味 | 見るべき場所 |
|---|---|---|
PLS-00306 |
引数の数または型が合わない | ALL_ARGUMENTS と呼び出し側 |
ORA-06550 |
PL/SQLブロック全体の失敗を示す入口 | 後続の PLS- エラー |
PLS-00201 |
識別子が宣言されていない、または見えない | 名前、権限、スコープ |
PLS-00905 |
参照しているオブジェクトが無効 | USER_ERRORS |
PLS-00323 |
仕様部で宣言したサブプログラムの本体がない | PACKAGE仕様部と本体 |
オブジェクトが無効な場合は PLS-00905の原因と解決方法、呼び出し先が見えない場合は PLS-00201の原因と解決方法 も確認してください。
修正チェックリスト
| 項目 | 確認内容 | OKの状態 |
|---|---|---|
| 呼び出し先 | プロシージャ/関数名が正しいか | 対象が特定できている |
| 引数定義 | ALL_ARGUMENTS を確認したか |
宣言側を把握済み |
| 数 | 引数数が一致しているか | 不足/過剰なし |
| 型 | データ型・TYPE_NAMEが一致しているか | 明示変換または同型 |
| 方向 | OUT/IN OUTに変数を渡しているか | 書き戻し可能な変数 |
| 名前付き記法 | 引数名が正しいか | ARGUMENT_NAMEと一致 |
| デフォルト | 省略可能な引数か | DEFAULTEDを確認済み |
よくある質問
引数の数は合っているのにPLS-00306になります
型、OUT/IN OUT、オーバーロード、レコード型やコレクション型の違いを確認してください。見た目が同じでも別の型なら一致しないことがあります。
名前付き記法なら順番は関係ありませんか?
順番の影響は減りますが、引数名が宣言と一致している必要があります。ALL_ARGUMENTS.ARGUMENT_NAME を確認してください。
OUT引数にNULLを渡してもよいですか?
OUT引数には値を書き戻せる変数を渡します。NULL や文字列リテラルではなく、変数を宣言して渡してください。
アプリから呼ぶ時だけPLS-00306になります
ドライバ側のバインド数、型、OUTパラメータ登録、パッケージ名・スキーマ名を確認してください。DB側の宣言は ALL_ARGUMENTS で確認します。
ORA-06550も一緒に出ています
ORA-06550はPL/SQLブロック全体の失敗を示す入口です。後続のPLS-00306に出ている呼び出し先と引数を直してください。
まとめ
PLS-00306は、PL/SQLのサブプログラム呼び出しで、引数の数または型が宣言と一致しない時に発生します。引数の個数だけでなく、型、順番、OUT/IN OUT、名前付き記法、デフォルト値、オーバーロード、複合型まで確認します。
対応の基本は、ALL_ARGUMENTS で宣言側を確認し、呼び出し側の実引数と1つずつ照合することです。アプリケーション経由で発生する場合は、DB側の宣言だけでなく、ドライバ側のバインド型やOUTパラメータ登録も確認してください。
参考
PLS-00306 – Oracle Database Error Help
ALL_ARGUMENTS – Oracle Database Reference
PL/SQL Subprograms – Oracle Database PL/SQL Language Reference
