我不相信“ INT(255)
”是有效的数据类型。
我知道 255 只是一个显示宽度属性。INT 数据类型定义值的范围,显示宽度不影响值的范围。但我只是从未见过大于 11 的 INT 上的长度修饰符。(10 表示无符号整数)(?)
作为测试,您可以尝试指定INT(11)
,或仅指定INT
.
更有问题的可能是这个具有数据类型INT
的变量作为第一个参数传递给DATE_FORMAT
函数。但第一个参数DATE_FORMAT
需要是 aDATE
或DATETIME
( TIMESTAMP
iirc)。可能有一些从 INT 到 DATE 的隐式转换,但我认为没有。
我不明白为什么你需要一个函数来从 DATE 中减去几个月。MySQL 具有内置函数和执行此操作的简单表达式。
例如:
dateexpr + INTERVAL -6 个月
返回从 中减去 6 个月的 DATE(或 DATETIME)值dateexpr
。如果您需要“向下舍入”到本月的第一天,或者转换为仅包含 'yyyy-mm' 的字符串,则可以分别执行 aDATE_FORMAT(dateexpr,'%Y-%m-01')
或 a SUBSTRING(dateexpr,1,7)
。
审查
CREATE FUNCTION a_testbed.PrevMonth (
in_date date,
in_mn_count int)
看起来不错,两个输入参数,一个 DATE 和一个 INT。(函数参数始终是 IN 参数。)
RETURNS int
有点奇怪的是,一个名为的函数PrevMonth
接受一个 DATE 参数,但返回一个 INT,而不是一个 DATE,但这不是错误。
BEGIN
/* local variable declaration */
DECLARE v_date INT(255);
255 的显示宽度很奇怪。以前从未在 INT 上看到过这种情况。
DECLARE v_date_format VARCHAR(10);
DECLARE v_date_sub VARCHAR(10);
两根弦,看起来不错。
SET v_date_format := DATE_FORMAT(v_date, '%Y-%m');
^^^^^^
但是v_date
是 INT,而不是 DATE 或 DATETIME。而且它没有初始化,所以它是NULL。如果这不会引发异常,那么我们希望v_date_format
为 NULL。(我怀疑你想在in_date
这里指定代替v_date
。)
SET v_date_sub := DATE_FORMAT(curdate(), '%Y-%m');
这应该得到 7 个字符,例如“2013-07”。所以那里没有问题。
IF (in_date IS NULL) THEN
SET v_date := v_date_sub;
这是in_date
参数的用法。检查它是否为空。如果是,则分配与我们分配给 v_date_sub 相同的 7 个字符。知道了。
ELSEIF (in_mn_count IS NULL OR in_mn_count < 0) THEN
SET in_mn_count := 0;
为 IN 参数赋值是否有效?(这可能是有效的,但很奇怪。通常我们不会为参数赋值,除非它们是 OUT 或 INOUT 参数。我们通常为过程变量(有时是 MySQL 用户变量)赋值。)
为什么这取决于 in_date 是否为空(前面的 IF)。似乎我们都想在任何一种情况下检查这个参数。
ELSE
SET v_date := v_date_sub;
这不是第一个指定的相同操作IF
吗?看起来这里的逻辑是“如果 in_date 不为 null 并且 ifnull(in_mn_count,-1)<0”我们做一件事,否则我们做其他事情。我们要么尝试为 IN 参数分配值,要么将当前的 YYYY-MM 分配给 v_date。
END IF;
到目前为止,in_date 参数的唯一用途是检查它是否为 NULL。in_mn_count 参数的唯一用途是尝试将零分配给它,如果它为空或小于零。
RETURN v_date_format;
我们唯一一次分配任何东西v_date_format
是在函数的开头,当我们从 DATE_FORMAT 函数分配返回值时,传入一个 NULL 值(作为 INT 而不是 DATE。)那么所有其他代码应该是什么正在做?
END
是的,请结束。这个函数有很多错误,它让我很头疼。所以,请,是的,END。让它停下来。