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

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

最佳答案

一种方法是使用

 WHERE column = nvl(var, column)

然而,这里有两个陷阱:
  • 如果该列可以为空,则此子句将过滤空值,而在您的问题中,您不会在第二种情况下过滤空值。您可以修改此子句以考虑空值,但它变得丑陋:
        WHERE nvl(column, impossible_value) = nvl(var, impossible_value)
    

    当然,如果不知何故 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;
    

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

    关于Oracle PL\SQL Null 输入参数 WHERE 条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5014620/

    相关文章:

    oracle - PL/SQL报告文件自动运行并导出结果?

    c# - Oracle ManagedDataAccess.EntityFramework Database.SqlQuery 按位置绑定(bind)参数?

    oracle - ORA-01400 : Strange behavior

    sql - 如何从 Oracle 中获取格式化的 XML

    java - Spring-Hibernate 应用程序中的无效列名异常

    java - 从 Java 代码调用存储函数时的 DateTime 参数

    mysql - Oracle-sql和Mysql通用日期格式函数

    mysql - 以下场景的 SQL

    oracle - Oracle "Instead of"触发器示例

    oracle - 无法弄清楚为什么触发器无效?