MYSQL如果参数为null则设置

时间:2014-03-31 19:16:59

标签: mysql sql stored-procedures

我是MYSQL的新手但对SQL有基本的了解,我想说如果我的参数没有设置(即为null),那么将其设置为JM。

下面的脚本我出错了什么/哪里?

提前致谢

CREATE DEFINER=`james`@`%` PROCEDURE `Project_Status`(IN engineer VARCHAR (5))
BEGIN

SELECT 
    PP.pid_full,
    PP.description_small,
    PP.project_status,
    PP.est_comp_date as 'Est Comp Date',
    EP.engineer
FROM 
    project_pid pp
JOIN
    eng_project_hours EP on PP.pid_full = EP.pid_full

where engineer = ep.engineer;

IF engineer is null then update engineer = jm
set engineer = ep.engineer;
end if;

end

3 个答案:

答案 0 :(得分:4)

我不确定我明白你要做什么。

如果要在输入参数的值为'JM'时使用值NULL而不是NULL,则获得此类行为的一种方法是声明本地程序中的变量。

检查参数的值,并相应地设置局部变量的值;当输入参数为null时,将局部变量设置为文字值'JM',或者当输入参数不为空时,将其设置为输入参数的值。然后在SQL语句中引用局部变量。

这样的事情:

DELIMITER $$

CREATE DEFINER=`james`@`%` PROCEDURE `Project_Status`(IN engineer VARCHAR(5))
BEGIN

   DECLARE ls_engineer VARCHAR(5);
   SET ls_engineer = IFNULL(engineer,'JM');

   SELECT pp.pid_full
        , pp.description_small
        , pp.project_status
        , pp.est_comp_date as 'Est Comp Date'
        , ep.engineer
     FROM project_pid pp
     JOIN eng_project_hours ep
        ON pp.pid_full = ep.pid_full
     WHERE ep.engineer = ls_engineer ;
END$$

请注意:

   SET ls_engineer = IFNULL(engineer,'JM');

是一种易于阅读的简写,相当于:

   IF ( engineer IS NULL ) THEN
      SET ls_engineer = 'JM';
   ELSE
      SET ls_engineer = engineer;
   END IF;

<强>后续

问:比如说,我在哪里&#39; JM&#39;我希望选择所有记录的程序,是否可以在此内完成?

A:是的。例如,假设输入参数具有&#34;特殊值&#34; 'JM'的{​​{1}},您根本不希望对ep.engineer列有任何限制,您可以通过在WHERE子句中添加OR条件来调整查询...

WHERE ep.engineer = ls_engineer
   OR engineer = 'JM'

如果输入参数engineer的值为'JM',则OR之后的谓词将为所有行返回TRUE,因此无论是否重要OR之前的部分返回TRUE,FALSE或NULL,WHERE子句的整体结果对于所有行都将为TRUE。

但我建议NULL'JM'更合适作为特殊&#34;返回所有行&#34;输入参数的值,不需要&#34;默认&#34;输入参数的值,即无需将NULL转换为'JM'。但这实际上取决于您的用例,但您可以考虑完全绕过JM默认值,并在查询中执行以下操作:

WHERE ep.engineer = engineer
   OR engineer IS NULL

问: ls_前缀的原因/含义是什么?

ls_前缀只是我自Oracle PL / SQL日以来一直使用的匈牙利式符号;我刚刚发现它是一种方便的方法来帮助跟踪范围,并使变量名称与其他变量名称或SQL中的列名称不冲突。

在SQL语句中,我可以限定列名以避免歧义,但是没有办法限定变量(除了使用绑定参数)。

我可以定义一个与全局变量具有完全相同名称的局部变量,并且我的局部变量会覆盖(隐藏)全局变量,这通常不是我想要的。

我并不是匈牙利乐谱的粉丝,尤其不是Windows风格lpszFoohwndBar,但匈牙利符号在Oracle PL / SQL中对我来说很方便。

我用第一个字母来标识变量的范围,&#34; l&#34;对于本地的,&#34; g&#34;对于全球,&#34; a&#34;争论。下一个字母是变量数据类型的简写,&#34; s&#34;对于VARCHAR(字符串)类型,&#34; d&#34;对于DATE,&#34; n&#34;为NUMBER。

所以,&#34; as _&#34;是一个参数字符串,&#34; ld _&#34;是为了当地约会等。

跟踪数据类型对于避免SQL中意外的隐式数据转换非常重要,并且进行了一次错误的显式转换&#34;错误&#34;,例如在&#34; date&#34;周围不需要TO_DATE();或数字周围的TO_NUMBER,但需要将字符串转换为数字等

答案 1 :(得分:0)

试试这个:

SELECT 
PP.pid_full,
PP.description_small,
PP.project_status,
PP.est_comp_date as 'Est Comp Date',
EP.engineer
FROM 
 project_pid pp
JOIN
 eng_project_hours EP on PP.pid_full = EP.pid_full
where ep.engineer = coalesce(engineer,"JM");

答案 2 :(得分:0)

您可以使用COALESCE返回null以外的内容:

SELECT 
    PP.pid_full,
    PP.description_small,
    PP.project_status,
    PP.est_comp_date as 'Est Comp Date',
    COALESCE(EP.engineer,'jm')'
FROM 
    project_pid pp
JOIN
    eng_project_hours EP on PP.pid_full = EP.pid_full
WHERE engineer = ep.engineer;

或使用CASE,其中JMEP中的另一列:

SELECT 
    PP.pid_full,
    PP.description_small,
    PP.project_status,
    PP.est_comp_date as 'Est Comp Date',
    CASE WHEN EP.engineer IS NULL THEN EP.jm ELSE EP.engineer END AS engineer
FROM 
    project_pid pp
JOIN
    eng_project_hours EP on PP.pid_full = EP.pid_full
WHERE engineer = ep.engineer;