Mysql 函数未返回预期结果
Mysql function not returning the expected result
正如我在下面的问题标题中提到的 Mysql function returns null always :
CREATE DEFINER=`root`@`localhost` FUNCTION `nextCode`(tbl_name VARCHAR(30), prv_code VARCHAR(30)) RETURNS varchar(30) CHARSET utf8
READS SQL DATA
BEGIN
DECLARE nxtCode VARCHAR(30);
SELECT ds.prefix, ds.suffix, ds.is_used, ds.next_number, CHAR_LENGTH(ds.pattern)
INTO @prefix, @suffix, @isUsed, @nxtNum, @pLength
FROM ths_inventory.doc_sequnce ds WHERE ds.`table_name` = tbl_name;
SET nxtCode = CONCAT(@prefix, LPAD((CASE WHEN @isUsed
THEN
(ExtractNumber(prv_code) + 1)
ELSE
(@nxtNum)
END
), @pLength,'0'), @suffix);
RETURN nxtCode;
END
但是一旦我更改了以下行:
CONCAT(@prefix, LPAD((CASE WHEN @isUsed
THEN
(ExtractNumber(prv_code) + 1)
ELSE
(@nxtNum)
END
), @pLength,'0'), @suffix)
一些静态值如下:
CONCAT('PR', LPAD((CASE WHEN true
THEN
(ExtractNumber(prv_code) + 1)
ELSE
(5)
END
), 6,'0'), '')
函数开始相应地返回值。
下面是我调用函数的方式:
nextCode('item','PR000002');
更新:
我定义了这个函数来获取项目 table 的下一个可能代码:
根据我的要求,下一个可能的代码应该是PR000000005
。
但是我总是得到空结果而不是得到它。
SELECT nextCode('item',(SELECT `code` FROM item ORDER BY id DESC LIMIT 1)) AS next_code;
任何帮助都将不胜感激。
运行一个使用该函数的查询,然后...
SELECT @prefix, @suffix, @isUsed, @nxtNum, @pLength;
...检查值。 @
前缀表示这些是用户定义的变量,因此它们具有会话作用域,而不是程序作用域,并且在函数执行后仍将保留它们的值。
这应该有助于查明您的问题。
但是,您还有另外两个问题需要解决。
SELECT ... INTO
不会在没有行匹配查询时设置目标变量,所以一旦你解决了你的问题,如果你传入你会得到非常错误的结果不匹配任何参数。
要解决此问题,函数需要在 SELECT ... INTO
查询之前将所有这些变量设置为 null。
SET @prefix = NULL, @suffix = NULL, @isUsed = NULL, @nxtNum = NULL, @pLength = NULL;
见https://dba.stackexchange.com/a/35207/11651。
另外,你的函数不处理并发,所以两个线程试图同时为同一个 table 找到 "next" 值,将产生相同的答案,所以你需要确保您的代码使用唯一约束和事务或其他适当的锁正确处理此问题。
正如我在下面的问题标题中提到的 Mysql function returns null always :
CREATE DEFINER=`root`@`localhost` FUNCTION `nextCode`(tbl_name VARCHAR(30), prv_code VARCHAR(30)) RETURNS varchar(30) CHARSET utf8
READS SQL DATA
BEGIN
DECLARE nxtCode VARCHAR(30);
SELECT ds.prefix, ds.suffix, ds.is_used, ds.next_number, CHAR_LENGTH(ds.pattern)
INTO @prefix, @suffix, @isUsed, @nxtNum, @pLength
FROM ths_inventory.doc_sequnce ds WHERE ds.`table_name` = tbl_name;
SET nxtCode = CONCAT(@prefix, LPAD((CASE WHEN @isUsed
THEN
(ExtractNumber(prv_code) + 1)
ELSE
(@nxtNum)
END
), @pLength,'0'), @suffix);
RETURN nxtCode;
END
但是一旦我更改了以下行:
CONCAT(@prefix, LPAD((CASE WHEN @isUsed
THEN
(ExtractNumber(prv_code) + 1)
ELSE
(@nxtNum)
END
), @pLength,'0'), @suffix)
一些静态值如下:
CONCAT('PR', LPAD((CASE WHEN true
THEN
(ExtractNumber(prv_code) + 1)
ELSE
(5)
END
), 6,'0'), '')
函数开始相应地返回值。
下面是我调用函数的方式:
nextCode('item','PR000002');
更新:
我定义了这个函数来获取项目 table 的下一个可能代码:
根据我的要求,下一个可能的代码应该是PR000000005
。
但是我总是得到空结果而不是得到它。
SELECT nextCode('item',(SELECT `code` FROM item ORDER BY id DESC LIMIT 1)) AS next_code;
任何帮助都将不胜感激。
运行一个使用该函数的查询,然后...
SELECT @prefix, @suffix, @isUsed, @nxtNum, @pLength;
...检查值。 @
前缀表示这些是用户定义的变量,因此它们具有会话作用域,而不是程序作用域,并且在函数执行后仍将保留它们的值。
这应该有助于查明您的问题。
但是,您还有另外两个问题需要解决。
SELECT ... INTO
不会在没有行匹配查询时设置目标变量,所以一旦你解决了你的问题,如果你传入你会得到非常错误的结果不匹配任何参数。
要解决此问题,函数需要在 SELECT ... INTO
查询之前将所有这些变量设置为 null。
SET @prefix = NULL, @suffix = NULL, @isUsed = NULL, @nxtNum = NULL, @pLength = NULL;
见https://dba.stackexchange.com/a/35207/11651。
另外,你的函数不处理并发,所以两个线程试图同时为同一个 table 找到 "next" 值,将产生相同的答案,所以你需要确保您的代码使用唯一约束和事务或其他适当的锁正确处理此问题。