2013-10-16 22 views
1

我正在Oracle上编写一个过程。我需要使用它进行搜索。 表单搜索有8个参数,每个参数可以包含很多值。 例如,您可以添加两个电影标题(您可以选择不键入整个标题)。 你也可以tyoe一年,而不是标题..Oracle可选参数的过程和多值参数

我不知道我是否可以有我的参数多值?

我只想建立在sql查询上,但它有可能吗?因为我的where子句包含8个参数..我迷失了这个搜索!

我有这个程序(不工作)

create or replace procedure listerFilms (
unTitreFilm Film.titre%TYPE DEFAULT NULL, 
uneAnneeMin Film.annee%TYPE DEFAULT NULL, 
uneAnneeMax Film.annee%TYPE DEFAULT NULL, 
uneVoFilm Film.langue%TYPE DEFAULT NULL, 
unPaysProd Pays.pays%TYPE DEFAULT NULL, 
unGenreFilm Genre.genre%TYPE DEFAULT NULL, 
unNomRea Equipe_Tournage.nomComplet%TYPE DEFAULT NULL, 
unNomActeur Equipe_Tournage.nomComplet%TYPE DEFAULT NULL) 
is 
titreFilm Film.titre%TYPE; 
anneeFilm Film.annee%TYPE; 

cursor lignesFilm(leTitreFilm Film.titre%TYPE, laAnneeMin Film.annee%TYPE, laAnneeMax Film.annee%TYPE, laVoFilm Film.langue%TYPE, lePaysProd Pays.pays%TYPE, leGenreFilm Genre.genre%TYPE, leNomRea Equipe_Tournage.nomComplet%TYPE, leNomActeur Equipe_Tournage.nomComplet%TYPE) is 
    select distinct 
     f.titre, f.annee 
    from 
     Film f, Pays p, Genre g, Equipe_Tournage rea, Equipe_Tournage act 
    where 
     f.titre like '%'||leTitreFilm||'%' and f.annee >= laAnneeMin and f.annee <= laAnneeMax 
     and f.langue like '%'||laVoFilm||'%' and p.pays like '%'||lePaysProd||'%' 
     and g.genre like '%'||leGenreFilm||'%' and rea.nomComplet like '%'||leNomRea||'%' 
     and act.nomComplet like '%'||leNomActeur||'%'; 

begin 
open lignesFilm(unTitreFilm,uneAnneeMin, uneAnneeMax, uneVoFilm, unPaysProd, unGenreFilm, unNomRea, unNomActeur); 
DBMS_OUTPUT.PUT_LINE('---------------------'); 
DBMS_OUTPUT.PUT_LINE('-- Liste des Films --'); 
DBMS_OUTPUT.PUT_LINE('---------------------'); 

EXCEPTION 
WHEN NO_DATA_FOUND THEN 
    DBMS_OUTPUT.PUT_LINE('Aucun film ne correpond au(x) critere(s) de recherche'); 
WHEN OTHERS THEN 
    RAISE_APPLICATION_ERROR(-20001,'Exception levée par la procédure'); 

loop 
    fetch lignesFilm into titreFilm, anneeFilm; 
    -- fetch retoune la ligne suivante 

    EXIT WHEN lignesFilm%NOTFOUND; 
    -- quit lorsque cursor fini 

    DBMS_OUTPUT.PUT_LINE(titreFilm || ' (' || anneeFilm || ')'); 
end loop; 
close lignesFilm; 


end; 
/

请帮我

+0

你到目前为止尝试过什么?请检查:http://stackoverflow.com/help/on-topic –

+0

我编辑,我必须做的程序,但我没有成功做到这一点:/ –

回答

0

如果你使用一点点PL/SQL魔术这是可能的。下面是一个例子,您可以搜索多个标题(只需添加您需要的其他参数)。

首先,您需要一个表格类型作为参数来保存多个标题 - 这就是t_str_tab类型。

其次,您可以使用该表参数上的TABLE函数来查询它,并使用伪列COLUMN_VALUE访问它的值。

第三,您使用子查询来检查当前处理的行是否具有与表参数中提供的任何标题匹配的标题。

CREATE TABLE movies (id NUMBER, title VARCHAR2(20), release_year NUMBER); 

CREATE TYPE t_str_tab IS TABLE OF VARCHAR2(20); 
CREATE TYPE t_num_tab IS TABLE OF NUMBER; 

INSERT INTO movies VALUES (1, 'First movie', 2010); 
INSERT INTO movies VALUES (2, 'Second movie', 2010); 
INSERT INTO movies VALUES (3, 'Third movie', 2010); 

COMMIT; 

CREATE OR REPLACE PROCEDURE search_proc(p_titles IN t_str_tab, p_years IN t_num_tab DEFAULT NULL) AS 
    CURSOR c_movies IS 
    SELECT m.id, m.title, m.release_year 
     FROM movies m 
    WHERE 
     ((SELECT COUNT(1) FROM TABLE(p_titles)) = 0 
     OR EXISTS (
      SELECT 1 
      FROM TABLE(p_titles) -- magic 
      WHERE upper(m.title) LIKE '%' || UPPER(column_value) || '%') 
    ) 
     AND 
     ((SELECT COUNT(1) FROM TABLE(p_years)) = 0 
     OR EXISTS (
      SELECT 1 
      FROM TABLE(p_years) 
      WHERE m.release_year = column_value) 
    ) 
    ; 
BEGIN 
    FOR v_movie IN c_movies 
    LOOP 
    dbms_output.put_line(
     'Id: ' || v_movie.id || 
     ', title: ' || v_movie.title || 
     ', release year: ' || v_movie.release_year); 
    END LOOP; 
END; 
/

BEGIN 
    dbms_output.put_line('First search:'); 
    search_proc(t_str_tab('d')); 

    dbms_output.put_line('Second search:'); 
    search_proc(t_str_tab('st', 'nd')); 
END; 

输出:

First search: 
Id: 2, title: Second movie, release year: 2010 
Id: 3, title: Third movie, release year: 2010 
Second search: 
Id: 1, title: First movie, release year: 2010 
Id: 2, title: Second movie, release year: 2010

编辑:改变了代码以允许可选参数。

+0

好吧,我真的很感谢你,我理解它是如何工作的!但我仍然有一个问题,我有2个参数,可选,LIKE不起作用:/ –

+0

@BaptisteLemarcis如果考虑到空阵列的可能性,它会工作 - 我编辑了代码,告诉你什么我的意思是。 –

+0

现在我不明白代码,为什么你把= 0? –