Oracle创建自定义表类型时TABLE OF子句报错原因咨询
从你给出的代码来看,报错出现在创建custos_sin_table类型的TABLE OF Custos_SIN部分,大概率是以下几个常见原因之一:
对象类型
Custos_SIN未成功创建
你写的第一个CREATE OR REPLACE TYPE Custos_SIN AS OBJECT语句语法本身没问题,但如果这条语句执行失败(比如权限不足、字段定义有隐性问题,或者你没先执行这条就直接跑第二条语句),那么当创建嵌套表类型时,Oracle找不到Custos_SIN这个对象类型,就会在TABLE OF处触发报错。
建议先单独执行第一条语句,确认它能成功创建对象类型——如果第一条报错,优先解决那个问题(比如检查是否拥有CREATE TYPE权限,或者字段类型是否符合Oracle规范)。大小写敏感问题(可能性较低,但值得排查)
Oracle默认对标识符大小写不敏感,但如果你的数据库开启了大小写区分,或者创建对象类型时用双引号包裹了名称,那引用时必须严格匹配大小写。不过你给出的代码里没有双引号,所以这个情况概率不高,但可以验证:如果第一条语句成功执行,通过SELECT * FROM USER_TYPES WHERE TYPE_NAME = 'CUSTOS_SIN'(注意大写,Oracle默认会把未加引号的标识符转成大写)确认对象类型存在。模式(Schema)匹配问题
如果你的对象类型Custos_SIN是在特定模式下创建的,而当前会话的默认模式不是该模式,那么创建嵌套表类型时需要显式指定模式名,比如写成TABLE OF your_schema.Custos_SIN,否则Oracle会在当前模式下查找不存在的对象类型,导致报错。
快速排查步骤
- 单独执行第一条
CREATE OR REPLACE TYPE Custos_SIN AS OBJECT (...)语句,检查是否有报错。 - 若第一条执行成功,执行查询语句
SELECT * FROM USER_TYPES WHERE TYPE_NAME = 'CUSTOS_SIN',确认对象类型已存在于数据字典中。 - 再次执行创建嵌套表类型的语句,此时应该能正常执行。
内容的提问来源于stack exchange,提问作者Guilherme Canteiro

