Oracle查询对象表时如何无需枚举所有列直接返回对应类型对象
问题场景
基于自定义对象类型a_obj创建对象表a,定义代码如下:
CREATE TYPE a_obj IS OBJECT ( a1 INTEGER, a2 integer ); CREATE TABLE a OF a_obj ( CONSTRAINT a__a1__pk PRIMARY KEY (a1) );
以下两类查询可正常执行:
- 通配符查询表所有列:
select a.* from a -- 执行正常
- 显式枚举字段构造
a_obj对象返回:
select a_obj(a.a1,a.a2) from a; -- 执行正常
当对象包含大量字段时,枚举字段的写法繁琐易漏,尝试用通配符直接传参构造对象:
select a_obj(a.*) from a;
执行抛出报错:
ORA-01747: invalid user.table.column, table.column, or column specification
另外在PL/SQL块中尝试将通配符查询结果直接存入a_obj类型变量也执行失败,代码如下:
declare ret a_obj; begin select a.* into ret from a; end;
解决方案
不需要枚举所有列,直接查询对象表的行对象本身即可。
对象表的建表语法是CREATE TABLE 表名 OF 对象类型,这意味着表中每一行本身就是对应对象类型的一个实例,直接引用表(或表别名)就能拿到完整的对象,不需要手动拆列、也不需要手动调用构造函数传参:
-- SQL场景直接返回a_obj类型对象,无需枚举字段 select a from a;
PL/SQL赋值场景也用同样逻辑即可:
declare ret a_obj; begin -- 直接取行对象赋值,无需通配符拆列 select a into ret from a; end; /
如果给对象表设置了自定义别名,比如from a t,直接引用别名t就能拿到完整对象,不受别名影响。
之前写法报错的原因是:a.*的语义是将对象拆解为多个独立的标量列输出,不会被解析为按顺序给对象构造函数传参,因此会被判定为非法列引用抛出错误。
内容的提问来源于stack exchange,提问作者Pierre-olivier Gendraud
相关产品推荐
相关产品推荐

