Mic*_*per 8 mysql stored-procedures
我已经在堆栈溢出给出的答案的帮助下纠正了代码.我想循环逗号分隔的ID字符串但不能这样做.下面给出的程序只更新第一条记录而不更新其他记录.需要进行哪些更正,以便我可以循环逗号分隔的字符串.这是我的SP的代码
BEGIN
DECLARE strLen INT DEFAULT 0;
DECLARE SubStrLen INT DEFAULT 0;
IF strIDs IS NULL THEN
SET strIDs = '';
END IF;
do_this:
LOOP
SET strLen = LENGTH(strIDs);
UPDATE TestTable SET status = 'C' WHERE Id = SUBSTRING_INDEX(strIDs, ',', 1);
SET SubStrLen = LENGTH(SUBSTRING_INDEX(strIDs, ',', 1));
SET strIDs = MID(strIDs, SubStrLen, strLen);
IF strIDs = NULL THEN
LEAVE do_this;
END IF;
END LOOP do_this;
END
Run Code Online (Sandbox Code Playgroud)
代码如此帖子的答案中所提供.
我尝试使用find_in_set()函数,但只有当我从开始时传递id并且如果我随机传递ID时不工作它才有效.这是我的表格脚本
CREATE TABLE `testtable` (
Run Code Online (Sandbox Code Playgroud)
Idint(11)DEFAULT NULL,
Statusvarchar(255)COLLATE utf8_unicode_ci DEFAULT NULL)ENGINE = MyISAM DEFAULT CHARSET = utf8 COLLATE = utf8_unicode_ci;
-- ----------------------------
-- Records of testtable
-- ----------------------------
INSERT INTO `testtable` VALUES ('1', 'O');
INSERT INTO `testtable` VALUES ('2', 'O');
INSERT INTO `testtable` VALUES ('3', 'O');
INSERT INTO `testtable` VALUES ('4', 'O');
INSERT INTO `testtable` VALUES ('5', 'O');
Run Code Online (Sandbox Code Playgroud)
这是存储过程BEGIN UPDATE TestTable SET status ='C'WHERE Id = FIND_IN_SET(Id,strIDs); 结束
strIds是varchar类型.
现在试试@ strIDs ='2'
小智 18
也许这篇文章有点太旧了,但我尝试了Devart提供的代码,但它对我不起作用.
几乎没有修改,这个版本适合我:
DELIMITER $$
CREATE PROCEDURE procedure1(IN strIDs VARCHAR(255))
BEGIN
DECLARE strLen INT DEFAULT 0;
DECLARE SubStrLen INT DEFAULT 0;
IF strIDs IS NULL THEN
SET strIDs = '';
END IF;
do_this:
LOOP
SET strLen = CHAR_LENGTH(strIDs);
UPDATE TestTable SET status = 'C' WHERE Id = SUBSTRING_INDEX(strIDs, ',', 1);
SET SubStrLen = CHAR_LENGTH(SUBSTRING_INDEX(strIDs, ',', 1)) + 2;
SET strIDs = MID(strIDs, SubStrLen, strLen);
IF strIDs = '' THEN
LEAVE do_this;
END IF;
END LOOP do_this;
END
$$
DELIMITER ;
Run Code Online (Sandbox Code Playgroud)
说明:
1)为什么"+2"IN SET SubStrLen = CHAR_LENGTH(SUBSTRING_INDEX(strIDs, ',', 1)) + 2;
当您在下一行执行MID函数时,字符串索引从1开始.如果您有以下字符串'4500,2',使用Devart版本,MID看起来像MID('4500,2',4,6)是',2'.
因此,如果在子字符串长度上添加1,则表示您在分隔符上.这不够.所以你添加分隔符的长度.现在很好.
2)为什么IF strIDs = '' THEN在循环条件下?
因为当您执行MID时,即使此字符串为空,也会返回一个字符串.
Devart程序修补了!非常感谢你的回答:)
试试这个(语法错误是固定的,没有CAST功能) -
DELIMITER $$
CREATE PROCEDURE procedure1(IN strIDs VARCHAR(255))
BEGIN
DECLARE strLen INT DEFAULT 0;
DECLARE SubStrLen INT DEFAULT 0;
IF strIDs IS NULL THEN
SET strIDs = '';
END IF;
do_this:
LOOP
SET strLen = LENGTH(strIDs);
UPDATE TestTable SET status = 'C' WHERE Id = SUBSTRING_INDEX(strIDs, ',', 1);
SET SubStrLen = LENGTH(SUBSTRING_INDEX(strIDs, ',', 1));
SET strIDs = MID(strIDs, SubStrLen, strLen);
IF strIDs = NULL THEN
LEAVE do_this;
END IF;
END LOOP do_this;
END
$$
DELIMITER ;
Run Code Online (Sandbox Code Playgroud)
您可以使用Debugger for MySQL调试您的过程.
EDIT2:
我没有程序就这样做.尝试使用FIND_IN_SET函数,例如 -
SET @strIDs = '1,2,3'; -- your id values
UPDATE TestTable SET status = 'C' WHERE FIND_IN_SET(id, @strIDs);
Run Code Online (Sandbox Code Playgroud)
或者创造一个临时.table,用id值填充它并在UPDATE语句中连接这两个表.
我没有找到合适的方法,于是我自己做了。很简单
PROCEDURE db.loop_through_array()
BEGIN
DECLARE strIDs varchar(150) DEFAULT 'one,two,three';
DECLARE element varchar(150);
WHILE strIDs != '' DO
SET element = SUBSTRING_INDEX(strIDs, ',', 1);
UPDATE TestTable SET status = 'C' WHERE Id = element;
IF LOCATE(',', strIDs) > 0 THEN
SET strIDs = SUBSTRING(strIDs, LOCATE(',', strIDs) + 1);
ELSE
SET strIDs = '';
END IF;
END WHILE;
END
Run Code Online (Sandbox Code Playgroud)