【问题标题】:MySQL Stored Pocedures skip WHERE condition if parameter is null如果参数为空,MySQL 存储过程会跳过 WHERE 条件
【发布时间】:2012-12-10 08:54:59
【问题描述】:

我正在编写存储过程,它应该根据几个过程参数搜索记录。 问题是并非总是必须传递所有参数,有时它们可​​能设置为 NULL。

有没有办法写出那样的东西?

CREATE PROCEDURE testProc(IN p_idWorker INTEGER, IN p_idEffect INTEGER)
BEGIN
    SELECT 
        * 
    FROM 
        CallHistory
    WHERE
        idWorker = IFNULL(p_idWorker, ANYTHING)
        AND 
        idEffect = IFNULL(p_idEffect, ANYTHING);
END$$

【问题讨论】:

  • 不是真正的 Sashi - MySQL 中没有像 'ANYTHING' 这样的关键字 ;)

标签: mysql search stored-procedures multiple-columns


【解决方案1】:

像这样:

 ...
 WHERE (p_idWorker IS NULL OR idWorkder = p_idWorker)
   AND (p_idEffect IS NULL OR idEffect = p_idEffect);

或者,就像您所做的那样,但不是 Anything 而是使用列名,如下所示:

   ...
   WHERE
        idWorker = IFNULL(p_idWorker, idWorker )
        AND 
        idEffect = IFNULL(p_idEffect, idEffect );

【讨论】:

  • 第一个不起作用,因为即使我设置 p_idWorker 参数,它也会选择 idWorker 为 NULL 的行。第二个很棒,你是第一个,所以“解决方案”标记给你。谢谢。
  • 不幸的是,经过一些测试,我不得不撤销接受。例如,当列 idWorker 默认为 NULL 时,它将不起作用。查询不会看到该列中所有为 NULL 的行。
【解决方案2】:

你可以使用例如:

    idWorker = IFNULL(p_idWorker, idWorker)

如果p_idWorker is null,那么对于所有行,此条件始终为TRUE。如果不是,那么只有在idWorker = p_idWorker

【讨论】:

  • 这是一个很好的答案,但你是第二名,所以给你解决方案标记是不公平的,而是为你 +1。谢谢。
  • 经过一些测试,这似乎不是一个好的解决方案 - 请参阅我在 Mahmoud Gamal 答案下的第二条评论。
【解决方案3】:

首先感谢 Mahmoud 和 valex 抽出宝贵时间,但两个答案都不是很好。如果例如字段 idWorker 可以为空,它们将不起作用 - 它不会看到字段 idWorker IS NULL 所在的行。

这个问题的最终解决方案看起来很奇怪,但它确实有效:

...
WHERE 
    idWorker = IFNULL(p_idWorker, idWorker)
    AND
    IFNULL(ch.idProjTime, -1) = IFNULL(p_idProjTime, IFNULL(ch.idProjTime, -1))

现在它也会看到NULL 字段。

如果这样做是个坏主意(我可以看到可能的性能影响 - 连续 3 次它会满足 IFNULL 条件) - 请纠正我。

【讨论】:

    猜你喜欢
    • 2012-11-21
    • 2014-03-31
    • 2020-01-09
    • 2020-03-22
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 1970-01-01
    • 2020-08-02
    相关资源
    最近更新 更多