我正在尝试学习PL / SQL 我似乎不明白我如何创建一个函数并让它返回一个记录
我正在尝试做这样的事情:
create or replace FUNCTION getMovie(movieID number)
RETURN record IS titleAndYear record(title varchar(100), production_Year number);
BEGIN
if (titleAndYear is null) then
titleAndYear:= MovieTitleAndYear('',0);
end if;
select TITLE ,YEAR into titleAndYear.title ,titleAndYear.production_Year from movie where MOVIE_ID = movieID;
return titleAndYear;
END;
我知道这不起作用,但我不知道为什么?
编辑1: 我也试过这个:
create or replace TYPE MovieTitleAndYear is OBJECT(title varchar(100), production_Year number);
/
create or replace FUNCTION getMovie(movieID number)
RETURN MovieTitleAndYear IS titleAndYear MovieTitleAndYear;
BEGIN
if (titleAndYear is null) then
titleAndYear:= MovieTitleAndYear('',0);
end if;
select TITLE ,YEAR into titleAndYear.title ,titleAndYear.production_Year from movie where MOVIE_ID = movieID;
return titleAndYear;
END;
但是当我运行这句话时的结果是:
select
GETMOVIE(
2540943
) from dual;
变成这个
GETMOVIE(2540943)
1 [DB_036.MOVIETITLEANDYEAR]
而不是两个colums title和productionyear。
答案 0 :(得分:3)
使用记录的第一个例子不会起作用。首先,函数不能返回仅在函数内声明的类型的值。您可以尝试将记录类型声明移动到包中,但即使您获得了编译功能,运行查询select getMovie(2540943) from dual
也会返回ORA-00902 invalid datatype
错误。
所以我建议你改用一种类型。
如果您使用的是类型,那么要分别获取电影和年份,您需要单独访问该类型中的字段,例如:
select getMovie(2540943).title, getMovie(2540943).production_year from dual
或者,如果您想避免两次调用getMovie()
,则可以使用子查询:
select x.movie_info.title, x.movie_info.production_year from (select getMovie(2540943) as movie_info from dual) x;
请注意,我们需要为子查询使用别名。以下内容会出现ORA-00904: "MOVIE_INFO"."PRODUCTION_YEAR": invalid identifier
错误:
select movie_info.title, movie_info.production_year from (select getMovie(2540943) as movie_info from dual);
这里的问题是Oracle在查询中寻找表movie_info
,但它找不到表movie_info
。它没有意识到x
实际上是一个列。如果我们引入别名x.movie_info
,Oracle就会意识到x.movie_info.title
是一列,因此api_helper.rb
是列中某个类型的字段。
答案 1 :(得分:1)
尝试这种方法。我认为你的答案就在这个片段内。让 我知道这是否有帮助。
--Create object type
CREATE OR REPLACE type av_obj_test
IS
object
(
col1 VARCHAR2(100),
col2 VARCHAR2(100) );
--C reate table type
CREATE OR REPLACE type av_ntt_test
IS
TABLE OF av_obj_test;
--Createfunction
CREATE OR REPLACE FUNCTION AV_RECORD RETURN
AV_NTT_TEST
AS
av_record av_ntt_test;
BEGIN
NULL;
SELECT av_obj_test(LEVEL,'av'||LEVEL) BULK COLLECT INTO av_record FROM DUAL
CONNECT BY LEVEL < 10;
RETURN av_record;
END;
--Calling function
SELECT * FROM TABLE(AV_RECORD);
--------------------------------OUTPUT-------------------------------------
COL1 COL2
1 av1
2 av2
3 av3
4 av4
5 av5
6 av6
7 av7
8 av8
9 av9
-------------------------------OUTPUT----------------------------------------