Oracle PL\SQL空输入参数,其中包含条件

Oracle PL\SQL空输入参数,其中包含条件,oracle,plsql,Oracle,Plsql,到目前为止,我正在使用IF-ELSE来处理这种情况 IF INPUT_PARAM IS NOT NULL SELECT ... FROM SOMETABLE WHERE COLUMN = INPUT_PARAM ELSE SELECT ... FROM SOMETABLE 有没有更好的方法在单个查询中不使用IF-ELSE循环来实现这一点。随着查询变得越来越复杂,将有更多类似这样的输入参数,如果需要,则所需的IF-ELSE数量将太多。这应该可以工作 SELECT ... FRO

到目前为止,我正在使用IF-ELSE来处理这种情况

IF INPUT_PARAM IS NOT NULL

    SELECT ... FROM SOMETABLE WHERE COLUMN = INPUT_PARAM
ELSE
    SELECT ... FROM SOMETABLE
有没有更好的方法在单个查询中不使用IF-ELSE循环来实现这一点。随着查询变得越来越复杂,将有更多类似这样的输入参数,如果需要,则所需的IF-ELSE数量将太多。

这应该可以工作

SELECT ... FROM SOMETABLE WHERE COLUMN = NVL( INPUT_PARAM, COLUMN )

一种方法是使用

 WHERE column = nvl(var, column)
然而,这里有两个陷阱:

  • 如果该列可为null,则该子句将过滤null值,而在您的问题中,在第二种情况下您不会过滤null值。您可以修改此子句以将null考虑在内,但它会变得丑陋:

        WHERE nvl(column, impossible_value) = nvl(var, impossible_value)
    
    当然,如果插入了
    不可能值
    ,您将遇到其他类型的(有趣的)问题

  • 优化器无法正确理解此类子句。它有时会生成一个包含UNION ALL的计划,但如果有多个
    nvl
    ,则即使存在完全有效的索引,也会得到完整扫描
  • 这就是为什么当有很多参数(例如大表单中的多个搜索字段)时,我喜欢使用动态SQL:

    DECLARE
       l_query VARCHAR2(32767) := 'SELECT ... JOIN ... WHERE 1 = 1';
    BEGIN
       IF param1 IS NOT NULL THEN
          l_query := l_query || ' AND column1 = :p1';
       ELSE 
          l_query := l_query || ' AND :p1 IS NULL';
       END IF;
       /* repeat for each parameter */
       ...
       /* open the cursor dynamically */
       OPEN your_ref_cursor FOR l_query USING param1 /*,param2...*/; 
    END;
    

    您还可以使用
    使用param1对l_结果执行即时l_查询

    谢谢分享这些有用的信息。我很高兴在这种情况下,列不为空。:)请参见此处重复的问题和答案: