Oracle PL \ SQL Null输入参数WHERE条件

时间:2011-02-16 09:23:23

标签: 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数量太多。

2 个答案:

答案 0 :(得分:9)

一种方法是使用

的变体
 WHERE column = nvl(var, column)

然而,这里有两个陷阱:

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

        WHERE nvl(column, impossible_value) = nvl(var, impossible_value)
    

    当然,如果以某种方式插入impossible_value,你会遇到其他一些(有趣的)问题。

  2. 优化器无法正确理解此类子句。它有时会生成一个带有UNION ALL的计划,但如果有多个nvl,即使存在完全有效的索引,您也将获得完整扫描。
  3. 这就是为什么当有很多参数(例如大型搜索字段)时,我喜欢使用动态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;
    

    您也可以使用EXECUTE IMMEDIATE l_query INTO l_result USING param1;

答案 1 :(得分:3)

这应该有效

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