【完全ガイド】ORA-06550 line/column: PLS-00320 の原因と解決方法|エラースタック・%TYPE・カスケードエラー 徹底解説

【完全ガイド】ORA-06550 line/column: PLS-00320 の原因と解決方法|エラースタック・%TYPE・カスケードエラー 徹底解説

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-xxxPLS-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 ERRORS vs エラースタック
  • 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 を根本から解決できるようになります。


目次

結論:エラースタックは「最初」が重要

時間がない方向けに、最速の対処を先に示します。

エラーメッセージの構造

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-06550PL/SQL コンパイル/実行時の位置情報
ORA-06512PL/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 公式


まとめ

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-06550PL/SQL コンパイル/実行時位置情報
ORA-06512PL/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)もあわせてご確認ください。