所以我有这个任务,我必须创建一个存储过程来搜索 Oracle 数据库中的电影。
搜索字符串遵循以下逻辑:
它在括号Ex中查找电影的年份。(1992)它在括号中查找年份范围,
例如。[1992,2000]它查找包含在标题、国家/地区、实现者、流派、演员或编剧中的单词。
以上任何一种都可以多次组合。
前任。: 指环王伊恩麦克莱恩克里斯托弗李 [1992,2000]
解决这个问题的逻辑是做一个巨大的查询来分组所有需要的数据,然后使用游标循环遍历结果集,用游标检查搜索字符串的每个单词是否有效。
我设法制作了一个按预期工作的过程,但我发现返回结果的唯一方法是使用 DBMS_OUTPUT。现在的问题是,当我插入 Hibernate 时,DBMS_OUTPUT 不会发送到客户端。我已经阅读了一些通过设置 DBMS_OUTPUT.enable 来强制输出的方法,但我觉得这不是正确的方法。
所以这是我的问题:
我的逻辑有问题吗?有没有更简单的方法可以通过单个选择或其他方式来存档它?
有没有办法在游标内动态推送数据并返回它?
我真的应该欺骗 DBMS_OUTPUT 以便将其发送到休眠状态吗?
这是我的代码:
CREATE OR REPLACE PROCEDURE p_SearchFilm(searchString IN VARCHAR2) IS
IsValid BOOLEAN;
y1 INTEGER;
y2 INTEGER;
subStrArray apex_application_global.vc_arr2;
term VARCHAR(100);
CURSOR films IS
Select FilmId, Titre, real.Prenom||' '||real.nom as Realisateur, anneeSortie, ListPays, ListGenres,
ListScenaristes, ListActeurs, langueOrigine
from Film
natural left join
(select FilmId, listagg(p.Nom, ',') within group (Order By p.nom) ListPays from Film
natural join Film_vs_pays
natural join Pays p
Group by FilmId)
natural left join
(select FilmId, listagg(g.Nom, ',') within group (Order By g.nom) ListGenres from Film
natural join Film_vs_Genre
natural join Genre g
Group by FilmId)
natural left join
(select FilmId, listagg(p.Prenom||' '||p.Nom, ',') within group (Order By p.nom) ListScenaristes from Film
natural join Scenariste s
join Personne p on s.personneId = p.personneId
Group by FilmId)
natural left join
(select FilmId, listagg(p.Prenom||' '||p.Nom, ',') within group (Order By p.nom) ListActeurs from Film
natural join Personnage perso
join Personne p on perso.personneId = p.personneId
Group by FilmId)
left join Personne real on real.personneId = realisateurId;
BEGIN
<<FILM_LOOP>>
FOR film IN films LOOP
subStrArray := apex_util.string_to_table(searchString, ' ');
FOR i in 1..subStrArray.count LOOP
IsValid:= FALSE;
term:= subStrArray(i);
IF REGEXP_LIKE(term, '\(\d{4}\)') THEN
IF film.anneeSortie = TO_NUMBER(regexp_substr(term, '\d{4}')) THEN
IsValid:= TRUE;
END IF;
ELSIF REGEXP_LIKE(term, '\[\d{4},\d{4}\]') THEN
y1:= regexp_substr(term, '\d{4}', 1, 1);
y2:= regexp_substr(term, '\d{4}', 1, 2);
IF film.anneeSortie BETWEEN y1 AND y2 THEN
IsValid:= TRUE;
END IF;
ELSE
IF UPPER(film.Titre||film.Realisateur||film.ListActeurs||film.ListScenaristes||film.ListGenres||film.ListPays||film.langueOrigine)
LIKE '%'||UPPER(term)||'%' THEN
IsValid:= TRUE;
END IF;
END IF;
IF NOT IsValid THEN
CONTINUE FILM_LOOP;
END IF;
END LOOP;
DBMS_OUTPUT.put_line(film.FilmId||'|'||film.Titre);
END LOOP;
END;
这里有一个小免责声明:
我看到了一些类似的问题来解决这个问题,但是使用游标的问题是返回一个完整的选择,而不是手动选择的行。
关于 DBMS_OUTPUT 和 Hibernate 的问题表明应该避免。
使用管道行缝合的问题仅适用于函数(更改由过程调用的函数的过程可能是一种有效的解决方法,我想知道在此之前是否还有其他可能)。