如何在存储过程Oracle

时间:2017-02-10 04:58:46

标签: oracle stored-procedures plsql

我创建了一个存储过程,用户可以在参数

中插入1个或多个值
create or replace procedure  MyProcerdure
(
title Film.Title%Type,
country Film.country%Type,
language  Film.language%Type,
category  Film.category%Type,
refCursor OUT SYS_REFCURSOR ) 
AS 
begin 
 OPEN refCursor FOR
select Film.Title as FilmTitle,
      Film.language as language
       Film.category

FROM Film 
Where Film.language=language
AND Film.category=category
AND Film.Country=country
//etc...

但我想允许用户不必填写所有内容并在参数中传递它们,这意味着如果用户只输入语言而没有其他任何内容,请返回正确的语言,并让&# 39; s说他输入了国家和语言,所以结果应该得到WHERE语言和国家等于他插入的内容

是否可以使用oracle在存储过程中创建这样的机制?

谢谢

2 个答案:

答案 0 :(得分:3)

您可以在查询中添加一些逻辑来处理参数可以为null的事实:

CREATE OR REPLACE PROCEDURE MyProcerdure(
                                         p_title             Film.Title%TYPE,
                                         p_country           Film.country%TYPE,
                                         p_language          Film.language%TYPE,
                                         p_category          Film.category%TYPE,
                                         po_refCursor    OUT SYS_REFCURSOR
                                        ) AS
BEGIN
    OPEN po_refCursor FOR
        SELECT Film.Title AS FilmTitle, Film.language AS language, Film.category
        FROM Film
        Where ( p_title    is null or Film.title    = p_title   )
          AND ( p_country  is null or Film.country  = p_country )
          AND ( p_language is null or Film.language = p_language )
          AND ( p_category is null or Film.category = p_category );
END;

答案 1 :(得分:2)

实现此目的的最佳方法是使用动态SQL。您可以有条件地连接正确的过滤器。如果没有提供任何值,您还需要连接备用版​​本。

例如,以下内容允许您过滤或放入编译器将忽略但在动态SQL中仍具有正确数量的绑定变量的语句。

CREATE OR REPLACE PROCEDURE MyProcerdure
(
   title     file.title%TYPE,
   country   file.country%TYPE,
   language  file.language%TYPE,
   category  file.category%TYPE,
   refCursor OUT SYS_REFCURSOR
) IS
   l_stmt VARCHAR2(4000);
BEGIN
   l_stmt := 'SELECT f.title AS filetitle,'||
             '       f.language AS language,'||
             '       f.category'||
             '  FROM file f'||
             ' WHERE 1 = 1';

   IF title IS NOT NULL THEN
      l_stmt := l_stmt || ' AND f.title = :title';
   ELSE
      l_stmt := l_stmt || ' AND (1=1 OR :title IS NULL)';
   END IF;

   -- The others would be done similarly

   OPEN refCursor FOR l_stmt USING title, -- The others would go the same order as above
END;
/