我是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
答案 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风格lpszFoo
和hwndBar
,但匈牙利符号在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
,其中JM
是EP
中的另一列:
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;