【完全ガイド】ORA-06550 line/column: PLS-00320 の原因と解決方法|エラースタック・%TYPE・カスケードエラー 徹底解説
- 作成日 2026.08.15
- Oracle Database
Oracle PL/SQL 開発者が日常的に遭遇するエラー出力:
ORA-06550: line 6, column 12:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 6, column 12:
PL/SQL: Item ignored
「宣言の型が不完全」という難解なメッセージ。実は極めて重要な特性があります:
ORA-06550は位置情報のみのラッパー(line X, column Y)- 具体的なエラー内容は併記される PLS-xxx(
PLS-00320,PLS-00201,PLS-00302等) - PLS-00320 は多くの場合「カスケードエラー」(前のエラーの結果)
- 最初のエラーが根本原因、その後の PLS-00320 は連鎖
このため、PLS-00320 だけを見て対処しても解決しないケースが多発します:
ORA-06550: line 4, column 14:
PLS-00201: identifier 'MGE.KEYWORD' must be declared ← 根本原因
ORA-06550: line 4, column 14:
PL/SQL: Item ignored
ORA-06550: line 27, column 36:
PLS-00320: the declaration of the type ... ← カスケード
ORA-06550: line 27, column 5:
PL/SQL: SQL Statement ignored
PLS-00201 を解決すれば、PLS-00320 も自動的に消えるというのが Oracle PL/SQL コンパイルエラーの特徴です。
現場では、以下のパターンが典型:
%TYPEで参照するテーブル/列が存在しないカーソル%ROWTYPEのカーソルが不完全REF CURSORの型不整合Object Typeの未定義- スキーマ違いでオブジェクト参照失敗
- INVALID オブジェクトへの参照
- 依存関係の欠損
- バージョンアップでパッケージ変更
多くの日本語記事が「型宣言を確認せよ」で終わりますが、実務では:
ORA-06550は位置情報のみという原理- エラースタックは「上から」読む(最初のエラーが根本)
- PLS-00320 は多くの場合カスケード(原因ではない)
- *併発する PLS- エラー**の意味
SHOW ERRORSvs エラースタック- JDBC / Rails からの受信メッセージの解読
- CI/CD パイプラインでの自動診断
さらに、Oracle PL/SQL エラーメッセージの構造を体系的に理解することが、あらゆる PL/SQL エラー解決の基礎です:
ORA-06550: line X, column Y: ← 位置情報(PL/SQL エラーの共通ラッパー)
PLS-00XXX: <具体的なエラー内容> ← 実際の原因
ORA-06550: line X, column Y: ← 位置情報
PL/SQL: Statement ignored ← 影響範囲
本記事では、ORA-06550 line/column PLS-00320 の完全な原因と解決方法を、リファレンスとして実用的に整理します。エラースタックの読み方、PLS-00320 の本質(カスケードエラー)、10大発生パターン、5つの解決策、Rails/Java/Python 対応、実践シナリオ、FAQまで完全網羅。この1本で ORA-06550 / PLS-00320 を根本から解決できるようになります。
- 1. 結論:エラースタックは「最初」が重要
- 2. ORA-06550 の本質:位置情報 wrapper
- 3. PLS-00320 の本質:多くはカスケード
- 4. 【原因①】%TYPE の対象が存在しない(最頻出)
- 5. 【原因②】カーソル%ROWTYPE のカーソルが不完全
- 6. 【原因③】REF CURSOR 型不整合
- 7. 【原因④】Object Type 未定義
- 8. 【原因⑤】スキーマ違い + シノニム不足
- 9. 【原因⑥】エイリアスの誤用
- 10. 【原因⑦】INVALID オブジェクト
- 11. 【原因⑧】PLS-00201 との併発(超典型)
- 12. 【原因⑨】PLS-00302 との併発
- 13. 【原因⑩】動的 SQL 内の型宣言
- 14. エラースタックの正しい読み方
- 15. 診断ツール完全リファレンス
- 16. 5つの解決策 完全リファレンス
- 17. Rails / Java / Python 対応
- 18. 実践シナリオ
- 19. トラブルシューティング
- 20. よくある質問(FAQ)
- 20.1. Q1. ORA-06550 と ORA-06512 の違い
- 20.2. Q2. PLS-00320 だけ見て対処できない
- 20.3. Q3. エラースタックの読み方
- 20.4. Q4. SHOW ERRORS の使い方
- 20.5. Q5. %TYPE と %ROWTYPE の違い
- 20.6. Q6. Rails での対応
- 20.7. Q7. Java での対応
- 20.8. Q8. Python での対応
- 20.9. Q9. REF CURSOR の推奨
- 20.10. Q10. 再コンパイル
- 20.11. Q11. E-Business Suite でよく発生
- 20.12. Q12. Autonomous DB での挙動
- 21. 参考リンク
- 22. まとめ
結論:エラースタックは「最初」が重要
時間がない方向けに、最速の対処を先に示します。
エラーメッセージの構造
ORA-06550: line X, column Y: ← 位置情報 wrapper
PLS-00XXX: <エラー内容> ← 実際の原因
ORA-06550: line X, column Y:
PL/SQL: <影響> ← 影響範囲
ORA-06550 自体には固有の意味なし、PLS-* / ORA-* が実質的な原因。
エラースタックの読み方
複数エラーがある場合:
1. 最初のエラー = 根本原因
2. 後続のエラー = 多くはカスケード
3. PLS-00320 は特に「カスケードエラー」の傾向
対処: 最初のエラーを解消 → 残りも自動的に消えることが多い
PLS-00320 の意味
PLS-00320: the declaration of the type of this expression
is incomplete or malformed
= 型宣言が不完全または不正
多くの場合、原因は別のエラー(PLS-00201, PLS-00302, PLS-00341 等)。
最速の診断
-- ① SHOW ERRORS で全体像
SHOW ERRORS PACKAGE MY_PKG;
SHOW ERRORS PROCEDURE MY_PROC;
-- ② USER_ERRORS ビュー
SELECT line, position, text
FROM user_errors
WHERE name = 'MY_OBJECT'
ORDER BY sequence;
-- ③ 参照先確認
SELECT * FROM all_objects WHERE object_name = '<REF_OBJECT>';
5つの解決策
| # | 手法 | 使う場面 |
|---|---|---|
| ① | 最初のエラーを解消 | カスケード対策 |
| ② | %TYPE の対象確認 | 型参照エラー |
| ③ | 依存関係修復 | INVALID |
| ④ | カーソル完全定義 | ROWTYPE エラー |
| ⑤ | エイリアス見直し | スキーマ違い |
ORA-06550 の姉妹エラー
| エラー | 意味 |
|---|---|
| ORA-06550 | PL/SQL コンパイル/実行時の位置情報 |
| ORA-06512 | PL/SQL 実行時スタックトレース |
ORA-06550 = コンパイル時、ORA-06512 = ランタイム。
詳細は以下で解説します。
ORA-06550 の本質:位置情報 wrapper
位置情報のみ
ORA-06550 はそれ単独では意味なし:
ORA-06550: line X, column Y:
line X, column Y は PL/SQL ソース内の位置、実際のエラーは併記される PLS-* / ORA-*。
具体的なエラー
ORA-06550: line 5, column 20: ← 位置
PLS-00201: identifier 'X' must be declared ← 実エラー
ORA-06550: line 5, column 20: ← 位置(同じ)
PL/SQL: Item ignored ← 影響
同じ位置情報が繰り返される。1つのエラーで2〜3回 ORA-06550 が出るのが普通。
何のエラーと併記されるか
多くの PLS- エラー*:
- PLS-00201: identifier must be declared
- PLS-00302: component ‘X’ must be declared
- PLS-00306: wrong number or types of arguments
- PLS-00320: declaration of type is incomplete
- PLS-00323: subprogram not declared
- PLS-00341: declaration of cursor is incomplete
- PLS-00905: object is invalid
および SQL エラー:
- ORA-00904: invalid identifier
- ORA-00942: table or view does not exist
- ORA-06508: could not find program unit
PLS-00320 の本質:多くはカスケード
PLS-00320 の意味
PLS-00320: the declaration of the type of this expression
is incomplete or malformed
「型宣言が不完全」というエラー。しかし、実は多くの場合、別のエラーの結果。
カスケードのメカニズム
1. PLS-00201 or PLS-00302 で「あるオブジェクトが見つからない」
2. そのオブジェクトを参照する型宣言(%TYPE, %ROWTYPE)が失敗
3. → PLS-00320(型宣言不完全)
4. その型を使う後続のステートメントも失敗
5. → さらに PLS-00320 が連鎖
**「PLS-00320 だけを見て型を確認しても意味ない」**ケースが多い。
実例
CREATE OR REPLACE PROCEDURE p IS
v_id nonexistent_table.id%TYPE; -- PLS-00201: 'NONEXISTENT_TABLE' must be declared
BEGIN
v_id := 100; -- PLS-00320: v_id の型が不完全
DBMS_OUTPUT.PUT_LINE(v_id); -- PLS-00320: 型不完全のため
END;
/
-- 実際のエラー出力
-- PLS-00201: identifier 'NONEXISTENT_TABLE' must be declared ← 根本
-- PLS-00320: declaration of the type ... incomplete ← カスケード
-- PLS-00320: declaration of the type ... incomplete ← カスケード
根本原因: PLS-00201(テーブル未定義)。これを解決すれば全て消える。
【原因①】%TYPE の対象が存在しない(最頻出)
症状
CREATE PROCEDURE p IS
v_id nonexistent_table.id%TYPE; -- ← テーブル未定義
BEGIN
NULL;
END;
/
-- ORA-06550: PLS-00201: 'NONEXISTENT_TABLE' must be declared
-- ORA-06550: PLS-00320: declaration incomplete
診断
-- 参照先確認
SELECT * FROM all_objects
WHERE object_name = 'NONEXISTENT_TABLE';
-- 結果なし = 存在しない
解決
A. テーブル名確認:
-- スペルミス修正
v_id existing_table.id%TYPE;
B. スキーマ明示:
v_id other_schema.tbl.id%TYPE;
C. シノニム作成:
CREATE SYNONYM tbl FOR other_schema.tbl;
【原因②】カーソル%ROWTYPE のカーソルが不完全
症状
DECLARE
CURSOR cur_data IS
SELECT c_first, c_last, c_dphone FROM customer; -- c_dphone 未存在
-- PLS-00201: 'C_DPHONE' must be declared
row_data cur_data%ROWTYPE;
-- PLS-00341: declaration of cursor 'CUR_DATA' is incomplete
-- PLS-00320: declaration of the type ... incomplete
BEGIN
NULL;
END;
/
解決
カーソルのカラム名を修正:
CURSOR cur_data IS SELECT c_first, c_last, c_phone FROM customer;
【原因③】REF CURSOR 型不整合
症状
DECLARE
TYPE strong_cursor IS REF CURSOR RETURN emp%ROWTYPE;
rc strong_cursor;
BEGIN
OPEN rc FOR SELECT id, name FROM emp; -- 型不一致
-- PLS-00320(REF CURSOR の型不整合)
END;
/
解決
弱型 REF CURSOR:
DECLARE
rc SYS_REFCURSOR;
BEGIN
OPEN rc FOR SELECT id, name FROM emp;
...
END;
/
REF CURSOR の詳細は PLS-00306: wrong number or types of arguments の記事も参照してください。
【原因④】Object Type 未定義
症状
CREATE PROCEDURE p IS
v_addr addr_t; -- addr_t 未定義
BEGIN
v_addr := addr_t('street', 'city');
END;
/
-- PLS-00201: 'ADDR_T' must be declared
-- PLS-00320: declaration incomplete
解決
Object Type 定義:
CREATE TYPE addr_t AS OBJECT (
street VARCHAR2(100),
city VARCHAR2(50)
);
/
CREATE OR REPLACE PROCEDURE p IS
v_addr addr_t;
BEGIN
v_addr := addr_t('street', 'city');
END;
/
【原因⑤】スキーマ違い + シノニム不足
症状
-- APPL ユーザーから COMN.CUSTOMERS 参照
CREATE PROCEDURE p IS
v_id customers.id%TYPE; -- APPL に customers なし
BEGIN
NULL;
END;
/
-- PLS-00201: 'CUSTOMERS' must be declared
-- PLS-00320: declaration incomplete
解決
A. スキーマ明示:
v_id comn.customers.id%TYPE;
B. シノニム:
CREATE SYNONYM customers FOR comn.customers;
C. GRANT + シノニム:
-- COMN 側
GRANT SELECT ON customers TO appl;
-- APPL 側
CREATE SYNONYM customers FOR comn.customers;
権限系は PLS-00201: identifier must be declared の記事も参照してください。
【原因⑥】エイリアスの誤用
症状
-- カーソルでエイリアス使用
CURSOR c IS
SELECT mge.keyword, mge.title
FROM CP_OCSPRD.MAP_GNIS_ELEMENTS mge -- エイリアス mge
WHERE mge.feature_id IS NULL;
-- しかし PL/SQL 内で
c_keyword mge.keyword%TYPE; -- ❌ mge はカーソル外では未定義
-- PLS-00201: 'MGE.KEYWORD' must be declared
-- PLS-00320: declaration incomplete
解決
実テーブル名で参照:
c_keyword CP_OCSPRD.MAP_GNIS_ELEMENTS.keyword%TYPE;
または:
c_keyword c%ROWTYPE; -- カーソル ROWTYPE
【原因⑦】INVALID オブジェクト
症状
SELECT status FROM user_objects WHERE object_name = 'MY_PKG';
-- INVALID
-- 使うと
CREATE PROCEDURE p IS
v_x my_pkg.some_type; -- INVALID なパッケージ
BEGIN
NULL;
END;
/
-- PLS-00320
解決
ALTER PACKAGE my_pkg COMPILE;
-- 再コンパイル
INVALID の詳細は PLS-00905: object is invalid の記事、ORA-04068: existing state of packages の記事も参照してください。
【原因⑧】PLS-00201 との併発(超典型)
症状(実際のエラー)
ORA-06550: line 5, column 20:
PLS-00201: identifier 'SYS.DBMS_SQL' must be declared
ORA-06550: line 5, column 20:
PL/SQL: Item ignored
ORA-06550: line 9, column 5:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 9, column 5:
PL/SQL: Statement ignored
ORA-06550: line 13, column 4:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
診断
最初のエラー(PLS-00201)が根本原因。
解決
-- DBMS_SQL の権限確認
GRANT EXECUTE ON SYS.DBMS_SQL TO app_user;
-- 再コンパイル
ALTER PACKAGE my_pkg COMPILE;
PLS-00320 は自動的に消える。
【原因⑨】PLS-00302 との併発
症状
ORA-06550: line 4, column 21:
PLS-00302: component 'EQPMT_POOL' must be declared
ORA-06550: line 4, column 13:
PL/SQL: Item ignored
ORA-06550: line 15, column 20:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
意味
PLS-00302: パッケージ.コンポーネント のコンポーネントが未定義(例: pkg.nonexistent_proc)。
解決
パッケージ内のプロシージャ/関数確認:
SELECT procedure_name FROM all_procedures
WHERE object_name = 'MY_PKG' AND owner = 'MY_SCHEMA';
【原因⑩】動的 SQL 内の型宣言
症状
DECLARE
v_sql VARCHAR2(1000) :=
'DECLARE v_x nonexistent_tbl.id%TYPE; BEGIN NULL; END;';
BEGIN
EXECUTE IMMEDIATE v_sql;
END;
/
-- ORA-06550 + PLS-00320
解決
動的 SQL 内でも実在するオブジェクトを参照、または動的 SQL の中でハードコーディング型指定:
v_sql := 'DECLARE v_x NUMBER; BEGIN NULL; END;';
エラースタックの正しい読み方
基本原則
1. 上から順に読む
2. 最初の実質エラー(ORA-06550 でない PLS-* or ORA-*)が根本原因
3. 後続のエラーは多くの場合カスケード
4. PLS-00320 は特にカスケードの傾向
5. ORA-06550 は位置情報のみ(無視して具体エラーを見る)
実例
ORA-06550: line 4, column 14: ← 位置1
PLS-00201: identifier 'MGE.KEYWORD' must be declared ← 根本原因!
ORA-06550: line 4, column 14: ← 位置1(重複)
PL/SQL: Item ignored ← 影響
ORA-06550: line 27, column 36: ← 位置2
PLS-00320: the declaration of the type ... incomplete ← カスケード
ORA-06550: line 27, column 5: ← 位置2(重複)
PL/SQL: SQL Statement ignored ← 影響
注目:
PLS-00201が最初 = 根本原因PLS-00320は後 = カスケードPLS-00201を解決すればPLS-00320も自動的に消える
JDBC / アプリからの受信
// Java での受信
try {
stmt.execute("BEGIN my_proc; END;");
} catch (SQLException e) {
System.out.println(e.getMessage());
// 最初のエラー(根本原因)を確認
}
エラースタックは改行で分割して上から読む。
診断ツール完全リファレンス
SHOW ERRORS
CREATE PROCEDURE p IS ... END;
/
-- Warning: Procedure created with compilation errors.
SHOW ERRORS PROCEDURE p;
SHOW ERRORS PACKAGE my_pkg;
SHOW ERRORS PACKAGE BODY my_pkg;
USER_ERRORS ビュー
SELECT line, position, text
FROM user_errors
WHERE name = 'MY_OBJECT'
AND type = 'PROCEDURE'
ORDER BY sequence;
全エラーを sequence 順で表示。最初の sequence が根本原因。
JDBC / oracledb からの受信
try:
cursor.execute("BEGIN my_proc; END;")
except oracledb.DatabaseError as e:
error_obj, = e.args
# error_obj.message に全エラースタック
for line in error_obj.message.split('\n'):
print(line)
DBMS_METADATA でオブジェクト定義取得
SELECT DBMS_METADATA.GET_DDL('PROCEDURE', 'MY_PROC') FROM DUAL;
-- コード全体を確認
5つの解決策 完全リファレンス
解決策① 最初のエラーを解消
PLS-00320 は無視して、それ以前の PLS- / ORA- を解決**:
1. エラースタック取得
2. 最初のエラー特定(PLS-00320 でないもの)
3. その原因対処
4. 再コンパイル
5. PLS-00320 も消える
解決策② %TYPE の対象確認
-- 対象テーブル/列存在確認
SELECT column_name, data_type
FROM user_tab_columns
WHERE table_name = 'MY_TABLE';
-- 参照修正
v_x my_table.column_name%TYPE;
解決策③ 依存関係修復
-- INVALID チェック
SELECT status FROM user_objects WHERE object_name = 'X';
-- 再コンパイル
ALTER PACKAGE x COMPILE;
ALTER PROCEDURE x COMPILE;
-- 一括
EXEC UTL_RECOMP.recomp_parallel(4, USER);
解決策④ カーソル完全定義
DECLARE
CURSOR c IS SELECT id, name FROM emp; -- 完全定義
row_data c%ROWTYPE; -- OK
BEGIN
NULL;
END;
解決策⑤ エイリアス見直し
-- ❌ カーソル外でエイリアス
c_keyword mge.keyword%TYPE;
-- ✅ 実テーブル
c_keyword CP_OCSPRD.MAP_GNIS_ELEMENTS.keyword%TYPE;
Rails / Java / Python 対応
Rails ActiveRecord
エラーハンドリング:
begin
ActiveRecord::Base.connection.execute("BEGIN my_proc; END;")
rescue ActiveRecord::StatementInvalid => e
# エラースタック全体をログ
Rails.logger.error e.message
# 最初のエラーが根本原因
first_error = e.message.split(/\n/).find { |l| l.match(/PLS-|ORA-/) && !l.match(/ORA-06550/) }
Rails.logger.error "根本原因: #{first_error}"
end
Rails 8 系の詳細は Rails 8 アップグレードガイドの記事も参照してください。
Java (JDBC)
try {
stmt.execute("BEGIN my_proc; END;");
} catch (SQLException e) {
// エラースタック全体
logger.error(e.getMessage());
// 最初の実質エラー(06550 以外)を抽出
String[] lines = e.getMessage().split("\n");
for (String line : lines) {
if ((line.contains("PLS-") || line.contains("ORA-"))
&& !line.contains("ORA-06550")) {
logger.error("根本原因: " + line);
break;
}
}
}
Python (oracledb)
import re
try:
cursor.execute("BEGIN my_proc; END;")
except oracledb.DatabaseError as e:
error_obj, = e.args
# 最初の実質エラー抽出
lines = error_obj.message.split('\n')
for line in lines:
if re.search(r'(PLS-|ORA-)', line) and 'ORA-06550' not in line:
print(f"根本原因: {line.strip()}")
break
実践シナリオ
シナリオ1:エラースタック解析の自動化
CREATE OR REPLACE FUNCTION extract_root_error(p_error CLOB)
RETURN VARCHAR2 IS
v_lines VARCHAR2(4000);
BEGIN
-- エラー行を分割
FOR line IN (
SELECT REGEXP_SUBSTR(p_error, '[^' || CHR(10) || ']+', 1, LEVEL) AS text
FROM DUAL
CONNECT BY REGEXP_SUBSTR(p_error, '[^' || CHR(10) || ']+', 1, LEVEL) IS NOT NULL
) LOOP
IF REGEXP_LIKE(line.text, 'PLS-|ORA-')
AND NOT REGEXP_LIKE(line.text, 'ORA-06550') THEN
RETURN line.text;
END IF;
END LOOP;
RETURN 'Unknown';
END;
/
シナリオ2:CI/CD パイプラインでのコンパイル検証
- name: Compile check
run: |
sqlplus -s $DB_USER/$DB_PW <<EOF
WHENEVER SQLERROR EXIT SQL.SQLCODE
ALTER PACKAGE my_pkg COMPILE;
ALTER PACKAGE my_pkg COMPILE BODY;
SHOW ERRORS
EOF
Kamal 2 デプロイの詳細は Kamal 2 デプロイの記事を参照してください。
シナリオ3:本番緊急診断
-- 影響オブジェクト特定
SELECT DISTINCT name, type
FROM user_errors
WHERE ROWNUM <= 20;
-- 根本原因を全対象で
SELECT name, type, MIN(line) AS first_line, text
FROM user_errors
WHERE text NOT LIKE '%PL/SQL%' -- ORA-06550 除外
GROUP BY name, type, text
ORDER BY name, type;
シナリオ4:Rails マイグレーションでの検証
class VerifyPlsqlCompilation < ActiveRecord::Migration[8.0]
def up
invalid_count = execute("
SELECT COUNT(*) AS c FROM user_objects WHERE status = 'INVALID'
").to_a.first['C']
if invalid_count > 0
# 詳細エラー取得
errors = execute("
SELECT name, type, line, text FROM user_errors ORDER BY name, sequence
").to_a
raise "INVALID: #{invalid_count}, errors: #{errors.inspect}"
end
end
end
シナリオ5:REF CURSOR エラー対処
-- ❌ 強型で不一致
DECLARE
TYPE emp_cur IS REF CURSOR RETURN emp%ROWTYPE;
rc emp_cur;
BEGIN
OPEN rc FOR SELECT id, name FROM emp;
END;
-- ✅ 弱型
DECLARE
rc SYS_REFCURSOR;
BEGIN
OPEN rc FOR SELECT id, name FROM emp;
END;
シナリオ6:Docker Oracle でのテスト
docker exec -it oracle-xe sqlplus scott/tiger <<EOF
CREATE PROCEDURE p IS
v_x nonexistent_tbl.id%TYPE;
BEGIN
NULL;
END;
/
SHOW ERRORS
EOF
Docker 関連は docker daemon 接続エラーの記事、Docker no space left on device の記事も参照してください。
シナリオ7:E-Business Suite での対処
-- 権限問題(SYS.DBMS_SQL 等)
SQL> CONN sys/pw AS SYSDBA
SQL> GRANT EXECUTE ON dbms_sql TO apps;
-- 再コンパイル
SQL> ALTER PACKAGE apps.my_pkg COMPILE BODY;
シナリオ8:Java Spring での対処
@Service
public class PlsqlErrorAnalyzer {
public String extractRootCause(String errorMessage) {
return Arrays.stream(errorMessage.split("\n"))
.filter(line -> line.matches(".*(PLS-|ORA-)\\d+.*"))
.filter(line -> !line.contains("ORA-06550"))
.findFirst()
.orElse("Unknown error");
}
}
シナリオ9:Python での自動診断ツール
import oracledb
import re
def diagnose_plsql_error(error_message):
"""PLS/ORA エラースタックから根本原因を抽出"""
lines = error_message.split('\n')
for line in lines:
# ORA-06550 は無視
if 'ORA-06550' in line:
continue
# 最初の実質エラーを返す
if re.search(r'(PLS-|ORA-)\d+', line):
return line.strip()
return None
# 使用
try:
cursor.execute("BEGIN my_proc; END;")
except oracledb.DatabaseError as e:
error_obj, = e.args
root = diagnose_plsql_error(error_obj.message)
print(f"根本原因: {root}")
シナリオ10:Autonomous DB
-- 同じ動作
-- Autonomous DB でも SHOW ERRORS 使える
トラブルシューティング
エラースタックが長すぎる
最初の非-06550 エラーだけ見る、他は無視。
%TYPE で権限問題
-- 参照先の SELECT 権限必要
GRANT SELECT ON other_schema.tbl TO app_user;
カーソル ROWTYPE
DECLARE
CURSOR c IS SELECT * FROM emp;
r c%ROWTYPE; -- OK: カーソル自体が VALID
BEGIN
...
END;
REF CURSOR 型不整合
強型 vs 弱型の混在避ける。弱型 (SYS_REFCURSOR) 推奨。
動的 SQL 内のエラー
動的 SQL は実行時判定、コンパイル時にはチェックされない → 実行時エラー。
PostgreSQL からの移行
PG の TYPE OF は Oracle の %TYPE に置換。ただし機能に差異あり。
よくある質問(FAQ)
Q1. ORA-06550 と ORA-06512 の違い
- 06550: PL/SQL コンパイル/実行時の位置情報
- 06512: PL/SQL 実行時スタックトレース
Q2. PLS-00320 だけ見て対処できない
カスケードエラーの可能性大。最初のエラーを確認。
Q3. エラースタックの読み方
上から順に、最初の PLS- / ORA-**(06550 以外)が根本原因。
Q4. SHOW ERRORS の使い方
SHOW ERRORS <TYPE> <NAME>;
例: SHOW ERRORS PACKAGE BODY MY_PKG;
Q5. %TYPE と %ROWTYPE の違い
%TYPE: 列の型%ROWTYPE: 行全体の型(レコード)
Q6. Rails での対応
エラースタックを分割して最初の実質エラーを抽出。
Q7. Java での対応
正規表現で PLS/ORA を抽出、ORA-06550 除外。
Q8. Python での対応
oracledb DatabaseError をキャッチして message 解析。
Q9. REF CURSOR の推奨
弱型 SYS_REFCURSOR 推奨(型不整合エラー回避)。
Q10. 再コンパイル
ALTER PROCEDURE p COMPILE;
EXEC UTL_RECOMP.recomp_parallel(4);
Q11. E-Business Suite でよく発生
SYS 権限系の PLS-00201 → PLS-00320 カスケードが典型。
Q12. Autonomous DB での挙動
同じ。SYS 権限管理は制限的、代替 API を使う。
参考リンク
Oracle 公式
- Oracle Database Error Messages: ORA-06550
- Oracle Database Error Messages: PLS-00320
- Oracle PL/SQL Language Reference: Compilation
- USER_ERRORS View
まとめ
ORA-06550 line/column PLS-00320 の要点を再整理します。
エラーの本質
ORA-06550: PL/SQL コンパイル/実行時の位置情報 wrapper
単独では意味なし、併記される PLS-* / ORA-* が実際のエラー
PLS-00320: 型宣言不完全(多くはカスケードエラー)
= 前のエラーの結果として発生することが多い
エラーメッセージの構造
ORA-06550: line X, column Y: ← 位置情報 wrapper
PLS-00XXX: <エラー内容> ← 実際の原因
ORA-06550: line X, column Y:
PL/SQL: <影響> ← 影響範囲
エラースタックの読み方
1. 上から順に読む
2. 最初の実質エラー(ORA-06550 でない PLS-* or ORA-*)が根本原因
3. 後続の PLS-00320 は多くの場合カスケード
4. 根本原因を解決 → カスケードも自動的に消える
姉妹エラー
| エラー | 意味 |
|---|---|
| ORA-06550 | PL/SQL コンパイル/実行時位置情報 |
| ORA-06512 | PL/SQL ランタイムスタック |
10大原因
| # | 原因 | 対処 |
|---|---|---|
| ① | %TYPE 対象未存在 | テーブル/列確認 |
| ② | カーソル ROWTYPE 不完全 | カーソル定義修正 |
| ③ | REF CURSOR 型不整合 | 弱型 SYS_REFCURSOR |
| ④ | Object Type 未定義 | CREATE TYPE |
| ⑤ | スキーマ違い | シノニム / プレフィックス |
| ⑥ | エイリアス誤用 | 実テーブル名 |
| ⑦ | INVALID オブジェクト | 再コンパイル |
| ⑧ | PLS-00201 併発 | 権限 / 宣言 |
| ⑨ | PLS-00302 併発 | コンポーネント確認 |
| ⑩ | 動的 SQL | 実行時判定 |
5つの解決策
-- ① 最初のエラーを解消(カスケード対策)
-- PLS-00320 は無視して他の PLS-* を対処
-- ② %TYPE 対象確認
SELECT * FROM user_tab_columns WHERE table_name = 'T';
-- ③ INVALID 対処
ALTER PACKAGE my_pkg COMPILE;
EXEC UTL_RECOMP.recomp_parallel(4);
-- ④ カーソル完全定義
CURSOR c IS SELECT id, name FROM emp;
row_data c%ROWTYPE;
-- ⑤ エイリアス見直し
c_x CP_OCSPRD.MAP_GNIS_ELEMENTS.keyword%TYPE;
エラー抽出の実装
def extract_root_cause(error_message):
for line in error_message.split('\n'):
if 'ORA-06550' in line:
continue
if re.search(r'(PLS-|ORA-)\d+', line):
return line.strip()
return None
予防のポイント
1. エラースタックは上から読む
2. PLS-00320 だけ見ない、その前の PLS-* を見る
3. %TYPE 使用時は対象存在確認
4. カーソルは事前に完全定義
5. REF CURSOR は弱型推奨
6. スキーマ間参照はシノニム
7. INVALID オブジェクトは即再コンパイル
8. CI/CD でコンパイル検証
9. アプリでエラー抽出ロジック実装
10. SHOW ERRORS 積極活用
これらの知識は、Oracle での PL/SQL 開発・デバッグ・DBA 業務・E-Business Suite 運用・Rails / Java / Python アプリ運用・CI/CD パイプライン・本番デプロイなど、あらゆる場面で活用できます。本記事をブックマークしておけば、ORA-06550 / PLS-00320 に出会っても冷静に的確に対処できるようになります。
本記事は2026年6月時点の情報をもとに、Oracle Database 19c〜23ai での動作確認・公式ドキュメントに基づき作成しています。Oracle のバージョンにより挙動が異なる場合があるため、最新の情報は Oracle 公式ドキュメント(docs.oracle.com)もあわせてご確認ください。
-
前の記事
【完全ガイド】PLS-00201: identifier must be declared の原因と解決方法|ロール経由権限の罠・DBMS_LOCK・シノニム 徹底解説 2026.08.12
-
次の記事
【完全ガイド】ORA-01000: maximum open cursors exceeded の原因と解決方法|カーソルリーク・JDBC・SESSION_CACHED_CURSORS 徹底解説 2026.08.17
コメントを書く