PLS-00103错误因误用IDENTIFIER关键字导致,该词仅为SQL通用术语(指表名、列名等),非PL/SQL合法声明符;正确做法是使用%TYPE或%ROWTYPE继承已有对象类型,或动态场景下以VARCHAR2变量存储名称并配合EXECUTE IMMEDIATE。

IDENTIFIER 不是 Oracle 12c PL/SQL 中的合法声明关键字,也不在任何官方文档或语法规范中存在。试图使用 IDENTIFIER 作为类型、变量名或声明符,会导致编译错误 PLS-00103: Encountered the symbol "IDENTIFIER"。
为什么你搜到“IDENTIFIER”可能有误导
常见混淆来源有三类:
- 把 SQL 标准中的通用术语 identifier(标识符,指表名、列名、变量名等)误当成 PL/SQL 的保留字或类型名
- 某些 IDE 或语法高亮插件错误地将
identifier当作关键字着色 - 把
DBMS_SQL.DESCRIPTOR或DBMS_SQL.VARCHAR2_TABLE等动态 SQL 包中返回的字段名(如col_name、col_type)误解为声明语法
真正可声明的“标识符相关”类型只有 %TYPE 和 %ROWTYPE
Oracle 提供的是基于已有对象推导类型的机制,而非抽象的 IDENTIFIER 类型:
-
v_empno emp.empno%TYPE:继承列定义,自动适配长度、精度、NULL 性 -
r_emp emp%ROWTYPE:整行结构映射,字段顺序和类型与表一致 - 二者都解决硬编码类型带来的维护风险——比如
emp.empno从NUMBER(4)改成NUMBER(6),所有用%TYPE声明的变量无需修改
替代 IDENTIFIER 的实际需求场景
如果你本意是想动态处理名称(如表名、列名),那属于运行时行为,不能靠声明解决:
- 静态场景(编译期已知):直接写死对象名,用
%TYPE/%ROWTYPE保一致性 - 动态场景(运行期才确定):必须用
DBMS_SQL或EXECUTE IMMEDIATE拼接字符串,此时名称只是VARCHAR2值,不是声明成分 - 别名或中间变量:用普通变量名即可,例如
l_table_name VARCHAR2(30) := 'EMP';,然后参与动态 SQL 构造
真正要警惕的是把“标识符”当作可声明类型来用——它从来就不是语言成分,只是语法概念。所有所谓 IDENTIFIER 声明,最终都会卡在解析阶段,连包体都编译不过。


















