Sql 是否可以编写一个查询,从通过调用Oracle中的函数获得的对象返回多个字段?
我想知道,如果给定通过调用函数获得的对象,是否可以编写一个查询,列出该对象的许多字段 例如,如果我有此模式:Sql 是否可以编写一个查询,从通过调用Oracle中的函数获得的对象返回多个字段?,sql,oracle,function,types,plsql,Sql,Oracle,Function,Types,Plsql,我想知道,如果给定通过调用函数获得的对象,是否可以编写一个查询,列出该对象的许多字段 例如,如果我有此模式: CREATE OR REPLACE TYPE T1 as OBJECT ( col1 varchar2(10), col2 varchar2(10), col3 varchar2(10), CONSTRUCTOR FUNCTION T1(input varchar ) RETURN SELF AS RESULT ) CREATE OR REPLACE TYPE BODY T1 IS C
CREATE OR REPLACE TYPE T1 as OBJECT (
col1 varchar2(10),
col2 varchar2(10),
col3 varchar2(10),
CONSTRUCTOR FUNCTION T1(input varchar ) RETURN SELF AS RESULT
)
CREATE OR REPLACE TYPE BODY T1 IS
CONSTRUCTOR FUNCTION T1(input varchar ) RETURN SELF AS RESULT IS
random_String varchar(5);
BEGIN
random_String:=dbms_random.string(opt => '',len=>'5');
self.col1:='1'||input||random_String;
self.col2:='2'||input||random_String;
self.col3:='3'||input||random_String;
RETURN;
end;
end;
create or replace function GET_T1(input varchar) return T1 is
object_created T1;
BEGIN
RETURN T1(input);
end;
如果我运行此查询:
select * from (
select
get_t1('1').col1 c1,get_t1('1').col2 c2,get_t1('1').col3
from dual
)
我看到get_t1被调用了三次,而我想写一个“直观地”工作的查询,如下所示:
select obj.col1,obj.col2,obj.col3 from (
select get_t1('1') obj from dual
)
不幸的是,它没有解析,并给出ORA 00904-无效标识符(Oracle不认为obj.colx
有意义)
请注意,我不想找到解决此特定情况的方法,也不想创建其他类型或修改函数,我想知道我想要的是否可能,如果可能,如何实现
还请注意,我希望返回对象的函数只执行一次。您需要提供一个表别名,然后在引用对象时使用该别名,以满足以下要求: 没有这个表别名,它就不知道
obj
指的是什么。没有名为obj
的表或别名,因此它会查找名为obj
的其他对象/模式/同义词等,而不是从内联视图中将其识别为列
这实际上包含在《对象关系开发人员指南》中的以下部分中:
为了避免内部捕获和解决引用的类似问题,Oracle数据库要求您使用表别名来限定对子程序或对象属性的任何点符号引用
我还向内联视图添加了
其中rownum=1
,这似乎阻止了它多次调用函数。我不太清楚为什么;我想知道是否与fast dual
有关,但您也需要一个真正的单行表。使用CTE和/或未记录的物化提示也不会停止多个调用;不使函数具有确定性(这可能无论如何都不合适)。到目前为止,这是我发现的唯一一个有效的方法——尽管你发现它也有效。不过,这可能值得提出自己的问题。您需要提供一个表别名,然后在引用对象时使用该别名,以满足以下要求:
没有这个表别名,它就不知道obj
指的是什么。没有名为obj
的表或别名,因此它会查找名为obj
的其他对象/模式/同义词等,而不是从内联视图中将其识别为列
这实际上包含在《对象关系开发人员指南》中的以下部分中:
为了避免内部捕获和解决引用的类似问题,Oracle数据库要求您使用表别名来限定对子程序或对象属性的任何点符号引用
我还向内联视图添加了其中rownum=1
,这似乎阻止了它多次调用函数。我不太清楚为什么;我想知道是否与fast dual
有关,但您也需要一个真正的单行表。使用CTE和/或未记录的物化提示也不会停止多个调用;不使函数具有确定性(这可能无论如何都不合适)。到目前为止,这是我发现的唯一一个有效的方法——尽管你发现它也有效。不过,这可能值得提出自己的问题。应该可以通过使用表函数来实现,请参见感谢您提供的链接,是的,可以使用表函数,但为此,我需要修改该函数并创建一个定义为表函数的附加类型。如果您想在select
语句中使用它,恐怕您无法避免这种情况。如果可以使用表函数,请参阅链接“谢谢”。是的,可以使用表函数,但为此,我需要修改该函数并创建一个定义为表的附加类型。如果您想在select
语句中使用它,恐怕您无法避免这种情况。谢谢您的回答,有一件事仍然让我感到困惑,似乎函数被调用了三次?select t.obj.col1,t.obj.col2,t.obj.col3 from((select/*+RESULT\u CACHE*/*from)(select get_t1('1')obj from dual)))t以这种方式调用函数一次(但使用提示)@mic.sca-使用rownum
也可以,但我不知道为什么。使用rownum的好技巧!我意识到我提出了一个有点愚蠢的问题,这反过来又引出了一个更好的问题和一个冷静的答案:)这是巨大的意外发现!谢谢你的回答,有一件事仍然让我困惑,似乎函数被调用了三次?选择t.obj.col1,t.obj.col2,t.obj.col3 from((select/*+RESULT\u CACHE*/*from(select get_t1('1')obj from dual)),以这种方式它调用函数一次(但使用提示)@mic.sca-使用rownum
也可以工作,但我不知道为什么。使用rownum的好技巧!我意识到我提出了一个有点愚蠢的问题,这反过来又引出了一个更好的问题和一个冷静的答案:)这是巨大的意外发现!
select t.obj.col1,t.obj.col2,t.obj.col3
from (
select get_t1('1') obj
from dual
where rownum = 1
) t;
OBJ.COL1 OBJ.COL2 OBJ.COL3
---------- ---------- ----------
11IQGCV 21IQGCV 31IQGCV