PL / SQL如何从创建或替换函数

时间:2016-02-27 11:23:38

标签: oracle plsql oracle-sqldeveloper

我正在尝试学习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。

2 个答案:

答案 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----------------------------------------