SQL没有游标的存储过程输出的多行

时间:2014-04-30 11:07:49

标签: sql oracle stored-procedures cursor

我要做的是在不使用游标的情况下从存储过程查询输出几行(如果有方法)。 我的数据库是关于视频租赁商店的,我需要做的是根据给定电影的类型显示类似电影的列表。 该过程将输入电影名称和我必须打印的内容输出具有相同类型的电影列表。

表格FILM是这样的:

Genre VARCHAR2(50);
Title VARCHAR2(50);
releaseDate DATE;
duration INT;

我已经使用游标完成了它并且它可以工作,但我必须在没有PL / SQL的情况下完成它,只需使用"纯sql"。

我想正确的查询是:

SELECT title,genre FROM FILM WHERE genre = (
              SELECT genre FROM FILM WHERE title='Pulp Fiction');

如果我遇到数据库,此查询是否有效,但如何使用此过程中的查询获得相同的结果? 我可能需要使用INTO进行SELECT,然后我就无法获取电影列表


我注意到它根本不清楚,我为此道歉。 我已经制作了一部特定电影的租借程序。 我首先检查所请求的电影是否可用。如果不是,我想打印(通过DBMS_OUTPUT.PUT_LINE ...)所选电影的同一类型的电影列表。

我使用游标制作了这个,但现在我想做的就是在没有游标的情况下做同样的事情。 我写下了用游标做的代码:

-- DECLARATION
CURSOR CU IS
SELECT title,genre
FROM FILM;

-- LOOP ..
SELECT genre INTO genre_sugg
FROM FILM
WHERE upper(title) = upper(film); -- film is the input name of the movie

FOR row_sugg IN CU LOOP
  IF(row_sugg.genre = genre_sugg AND row_sugg <> film ) THEN
    DBMS_OUTPUT.PUT_LINE('Film: ' || row_sugg.title);
  END IF;
END LOOP;

2 个答案:

答案 0 :(得分:4)

我认为这就是你想要的:

CREATE OR REPLACE PROCEDURE get_movie(p_movie_name VARCHAR2)
AS

BEGIN
   FOR movie IN (SELECT title,genre FROM FILM WHERE genre = (
                          SELECT genre FROM FILM WHERE title=p_movie_name))
      LOOP
         dbms_output.put_line(movie.title||' '||movie.genre);
      END LOOP;                          
END;

答案 1 :(得分:1)

你必须使用循环,除非你将所有标题聚合成一个字符串并只打印该单个值;但是你可以避免使用表类型和bulk collect的显式或隐式游标:

create or replace procedure genre_match(p_title in film.title%type) is
type film_tab is table of film%rowtype;
films film_tab;
begin
  select *
  bulk collect into films
  from film
  where genre = (select genre from film where upper(title) = upper(p_title))
  and upper(title) != upper(p_title);

  for i in 1..films.count loop
     dbms_output.put_line('Film: ' || films(i).title || ' ' || films(i).genre);
  end loop;
end;
/

这声明了一个类型,它是一个电影集合,一个变量films,它是该类型的一个实例。 bulk collect将查询的整个结果放入该集合中。然后,您可以迭代集合,而不是光标。

使用一些简单的补充数据:

create table film (genre varchar2(30), title varchar2(30));

insert into film values ('Crime fiction', 'Pulp Fiction');
insert into film values ('Crime fiction', 'Ocean''s 11');
insert into film values ('Crime fiction', 'The Italian Job');
insert into film values ('Science fiction', 'Alien');

程序显示:

set serveroutput on
exec genre_match('pulp fiction');

anonymous block completed
Film: Ocean's 11 Crime fiction
Film: The Italian Job Crime fiction

(从技术上讲,Oracle仍然使用某种类型的游标将行检索到集合中,就像任何查询一样 - 在普通的SQL中也是如此;但这是不可避免的,而且超出了范围问题......)