因某些原因无法工作的SQL存储过程
我正在尝试基于MySQL数据库系统编写一个简单的存储过程,接受一个字符串作为参数。该过程随后将其拆分成更短的字符串(使用分隔符),使每个字符串都是大于0 的数字。否则,如果子字符串根本不是数字,就会被丢弃。结果需要作为单列表返回。不幸的是,由于某些未知原因,我没有得到预期的结果。能否请人看看代码并帮我修复错误?
存储过程和函数(不需要任何数据库表):
CREATE DEFINER=`root`@`localhost` PROCEDURE `new_procedure`(
IN variants VARCHAR(50)
)
BEGIN
DECLARE counter INT DEFAULT 0;
SET
@validated_params = FALSE,
@params_number = (CHAR_LENGTH(variants) - CHAR_LENGTH(REPLACE(variants, ';', '')) + 1
);
SET
@correct_params = JSON_ARRAY('[3, 1]');
WHILE counter < @params_number DO
SET
counter = counter + 1;
SET
@variant = split_string(@variants, ';', counter);
IF @variant > 0 THEN
SET
@correct_params = JSON_ARRAY_APPEND(@correct_params, '$', @variant);
END IF;
END WHILE;
IF JSON_LENGTH(@correct_params) = @params_number THEN
SET
@validated_params = TRUE;
END IF;
SELECT variant_number FROM JSON_TABLE(@correct_params, '$[*]' COLUMNS (variant_number INT PATH '$')) AS variant_number;
END
CREATE DEFINER=`root`@`localhost` FUNCTION `split_string`(
string_to_split VARCHAR(250),
delimimiter VARCHAR(5),
position INT
) RETURNS int
DETERMINISTIC
BEGIN
SET
@splitted_string = REPLACE(
SUBSTRING(
SUBSTRING_INDEX(string_to_split, delimimiter, position),
CHAR_LENGTH(SUBSTRING_INDEX(string_to_split, delimimiter, position - 1)) + 1
), delimimiter, ''
);
SET
@splitted_number = (
CASE WHEN @splitted_string REGEXP '^[0-9]+$' THEN
CAST(@splitted_string AS UNSIGNED) ELSE -1 END
);
RETURN @splitted_number;
END
在用以下示例参数运行存储过程后,我们应该得到一个形如的表:
CALL new_procedure('2, b7, vb, 9');
| 变体编号 |
|---|
| 3 |
| 1 |
| 2 |
| 9 |
然而,我得到的是一个空表……
解决方案
由于你在使用JSON(json_array_append、json_table),你可以使用这些工具,而不需要实现string_split。
CREATE PROCEDURE `new_procedure6`(
IN variants VARCHAR(50)
)
BEGIN
with src as(
SELECT variant_number,
count(variant_number)over() validated,
count(*)over()-count(variant_number)over() not_validated
FROM JSON_TABLE(concat('["',replace(concat('3,1,',variants),',','","'),'"]')
, '$[*]'
COLUMNS (variant_number INT PATH '$')) AS variant_number
)
select * from src
where variant_number is not null
;
END ;
call new_procedure6('1,v7,vb,9');
输出:
+----------------+-----------+---------------+
| variant_number | validated | not_validated |
+----------------+-----------+---------------+
| 3 | 4 | 2 |
| 1 | 4 | 2 |
| 1 | 4 | 2 |
| 9 | 4 | 2 |
+----------------+-----------+---------------+
示例中的分隔符是 ,。
Fiddle
Upd1
当问题是
“如何把以分隔符分隔的字符串(值的列表)转换成一个值表”
set @variants="2,v7,vb,9";
SELECT rn,variant_number
FROM JSON_TABLE( concat('["',replace(@variants,',','","'),'"]')
, '$[*]'
COLUMNS (
rn FOR ORDINALITY,
variant_number varchar(10) PATH '$'
)
) AS variant_number
输出为
| 行号 | 变体编号 |
|---|---|
| 1 | 2 |
| 2 | v7 |
| 3 | vb |
| 4 | 9 |
例如
SELECT *
FROM myTable t
WHERE t.id IN(
SELECT id
FROM JSON_TABLE( concat('["',replace(@idList,',','","'),'"]'), '$[*]'
COLUMNS ( id int PATH '$')
) AS ids
)
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。