Oracle PL / sql如果输入varchar param为空,如何返回所有记录?

时间:2015-09-03 19:41:55

标签: oracle stored-procedures plsql

我有以下查询。如果输入参数不为null并传递了值,则它将返回该URL的所有匹配记录。 如果Input参数为空,则应返回所有记录。如何修复更新条件?

CREATE OR REPLACE PROCEDURE GetDatesList (
p_URL               IN varchar2,
P_RECORDSET         OUT SYS_REFCURSOR 
)
as

begin

OPEN P_RECORDSET FOR
select 
      PCBS.KeyId as Key, PCBS.PublishDate
from (select 
      Serlog.*, PS.ServerType, row_number() over (partition by Serlog.KeyId order by Serlog.PublishDate desc) as RowNu
      from PConfigByServerLog Serlog 
      join PServer PS on PS.ServerName = Serlog.ServerName 
      and Serlog.URL = PS.URL
      where Serlog.URL = p_URL
      --Here if we pass a value f p_podURL, we get those matching records back. If it is empty, then it should bring all the records back 
      ) PCBS 
where PCBS.RowNu = 1 and PCBS.IsActive = 'T';

end;

3 个答案:

答案 0 :(得分:3)

 where Serlog.URL = p_URL OR p_URL is null

 where Serlog.URL = nvl(p_URL, Serlog.URL)

关于性能的说明

其他一个答案警告性能。

如果Serlog.URL被编入索引,那么如果p_URL不为空,Oracle将足够聪明地使用它。

考虑这样的SQL:

SELECT * FROM sys.obj$
where obj# = nvl(:b1, obj# )

计划如下:

7 SELECT STATEMENT
    6 CONCATENATION  
        2 FILTER  
            1 TABLE ACCESS FULL SYS.OBJ$
        5 FILTER  
            4 TABLE ACCESS BY INDEX ROWID SYS.OBJ$
                3 INDEX RANGE SCAN SYS.I_OBJ1

两个过滤操作(#2和#5)分别为:b1 is null:b1 is not null。因此,Oracle将只执行计划中的任何一个分支,具体取决于是否已给出参数。

答案 1 :(得分:2)

只需写下

     where (Serlog.URL = p_URL) OR p_URL is null

而不是

       where Serlog.URL = p_URL

请记住,这会给您次优的执行计划:如果url参数已编入索引,则可能不会使用该索引。

如果需要关注性能,你最好用两种不同的游标分别处理这两种情况

答案 2 :(得分:0)

如果合适,您还可以在过程定义中为p_URL设置默认值:

CREATE OR REPLACE PROCEDURE GetDatesList (
p_URL               IN varchar2 DEFAULT '//svr1/dir1/folder2/etc',
P_RECORDSET         OUT SYS_REFCURSOR 
)
as

因此,如果传递NULL,则将使用此值。