【问题标题】:DB2 Conditional WHERE clauseDB2 条件 WHERE 子句
【发布时间】:2012-04-18 17:05:45
【问题描述】:

我正在使用 DB2 v9

我有一个带有参数的存储过程,这些参数可能会作为空字符串传入。这是我正在尝试做的一些伪代码:

WHERE myColumn.name =
     IF param1 = '' THEN
        **disregard this param, all column values are eligible**
     ELSE
        myColumn.name = param1;

如果它是一个空字符串,基本上只是忽略它。如果不是,则将其作为 WHERE 子句中的过滤器应用。这可以在 DB2 中实现吗?

【问题讨论】:

    标签: sql db2


    【解决方案1】:
    SELECT ...
    FROM ...
    WHERE  param1 = '' 
       OR  myColumn.name = param1
       ;
    

    【讨论】:

    • 您的智慧远超我最疯狂的梦想。谢谢!
    • 这个想法是,通常查询生成器/优化器足够聪明,可以检测“循环不变”条件。 (就像WHERE 1=0 OR ...
    • @Ted - 请注意,虽然我做过类似的事情,但 SQL 并不能像大多数编程语言那样真正保证“短路”顺序。 wildplasser 的评论(通常)是实际发生的事情,这可能使其看起来以这种方式行事。
    【解决方案2】:

    wildplasser 提供的answer 是正确的,但还有一些额外的注意事项可能会有所帮助。

    首先,存储过程输入参数可能包含 NULL 而不是 ''。使用 COALESCENULLIF 函数将覆盖 NULL 和任意数量的空白空间:

    SELECT ... FROM ... WHERE COALESCE( param1, '' ) = '' OR myColumn.name = param1 ;
    

    当这种类型的搜索查询被编译到存储过程中时,通常有助于对过程中的语句启用 REOPT ALWAYS。如果您不这样做,则存储过程中的 SQL 语句将始终使用相同的访问计划,而不管在运行时将哪些输入参数传递给存储过程。允许优化器在运行时重新评估过程中的每条语句,将在用户搜索特定列时提供更好的利用正确索引的机会。

    CALL SYSPROC.REBIND_ROUTINE_PACKAGE 
        ('P','YOURPROCSCHEMA.YOURPROCNAME','REOPT ALWAYS') ; 
    

    【讨论】:

      【解决方案3】:

      这里的另一个关键字是“Dynamic SQL”。将您的查询构建为字符串,并使用 EXECUTE IMMEDIATE 它们(用于 UPDATE、INSERT 或 DDL)或使用 PREPARE/OPEN/FETCH(用于 SELECT)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-01-18
        • 1970-01-01
        • 2015-05-15
        • 2014-09-30
        • 1970-01-01
        • 2018-02-06
        • 1970-01-01
        相关资源
        最近更新 更多