1. 怎么写出来的?踩了哪些坑
因为阿里Java开发手册上面不建议使用存储过程,所以并没有学习过存储过程。因为测试环境需要造数据测试验证,需要大批量插入数据,一条一条造SQL太麻烦了,所以想到了存储过程。
先百度了一个存储过程的模板。
DROP PROCEDURE
IF
EXISTS `insertdata`;
DELIMITER $$
CREATE
PROCEDURE `study`.`insertdata`(IN record INTEGER)
BEGIN
DECLARE number INTEGER ;
SET number=1;
START TRANSACTION;
WHILE number <=record DO
INSERT INTO
study.t_study
(字段)
VALUES(字段值);
SET number =number+1;
END WHILE;
COMMIT;
END$$
DELIMITER ;
将字段,字段值改成自己表对应的要插入的数据。执行了一下,发现一直报错。
使用连接mysql的工具是sqlyog,先百度了一下存储过程怎么插入,怎么执行。
右键选中study库,选择创建,选择存储过程,输入存储过程的名字insertdata,然后在sqlyog的模板中的BEGIN和END中写入对应的sql。
sql写完之后执行execute all queries。如果存储过程没有语法错误,在Stored Procs下面就会生成对应名称的存储过程。
调用存储过程:CALL insertdata(100)
问题是我的存储过程一直报错,执行失败。因为也不懂存储过程的语法,所以先去学习了一下语法。
1.1 新建存储过程的语法
参考:
易百教程
DELIMITER //
CREATE PROCEDURE insertdata()
BEGIN
SELECT * FROM t_study;
END //
DELIMITER ;
DELIMITER //,它与存储过程语法无关。 DELIMITER语句将标准分隔符分号(;)更改为//。更改分隔符可以将存储过程作为一个整体。在END关键字之后,使用分隔符//来指示存储过程的结束。 最后一个命令(DELIMITER;)将分隔符更改回分号(😉。
使用CREATE PROCEDURE语句创建一个新的存储过程。在CREATE PROCEDURE语句之后指定存储过程的名称为insertdata。把括号放在存储过程的名字之后。
BEGIN和END之间的部分称为存储过程的主体。将SQL语句放在主体中以处理业务逻辑。 在这个存储过程中,我们使用一个简单的SELECT语句来查询t_study表中的数据。
1.2 声明变量
DECLARE variable_name datatype(size) DEFAULT default_value;
在DECLARE关键字后面指定变量名。变量名必须遵循MySQL表列名称的命名规则。紧随其后,指定变量的数据类型及其大小。变量可以有任何MySQL数据类型,如INT,VARCHAR等。最后,使用DEFAULT关键字为变量分配默认值。DEFAULT 这部分可省略。
给变量赋值:可以使用SET和SELECT INTO
SET number= 10;
SELECT COUNT(*) INTO number FROM t_study;
此处踩了两个大坑。
其一:声明VARCHAR变量的时候一定要指定长度,否则会报错。
其二:变量全部声明完毕后再赋值,不能声明和赋值互相交叉。
1.3 存储过程参数
MODE param_name param_type(param_size)
在MySQL中,参数有三种模式:IN,OUT或INOUT。如果存储过程有多个参数,则每个参数由逗号(,)分隔。
IN 是默认模式。在存储过程中定义IN参数时,调用程序必须将参数传递给存储过程。 另外,IN参数的值被保护。这意味着即使在存储过程中更改了IN参数的值,在存储过程结束后仍保留其原始值。换句话说,存储过程只使用IN参数的副本。
OUT 可以在存储过程中更改OUT参数的值,并将其更改后新值传递回调用程序。请注意,存储过程在启动时无法访问OUT参数的初始值。
INOUT 参数是IN和OUT参数的组合。这意味着调用程序可以传递参数,并且存储过程可以修改INOUT参数并将新值传递回调用程序。
DELIMITER $$
CREATE
PROCEDURE `study`.`insertdata2`(IN record VARCHAR(32))
BEGIN
SELECT * FROM t_study where imsi = record;
END$$
DELIMITER ;
1.4 WHILE循环
WHILE语句的语法如下:
WHILE expression DO
statements
END WHILE
WHILE循环在每次循环开始时检查表达式。 如果expression为TRUE,MySQL将执行WHILE和END WHILE之间的语句,直到expressione为FALSE。
1.5 写存储过程
执行存储过程前先删除原有的存储过程,如果存在的话。
DROP PROCEDURE
IF
EXISTS `insertdata`;
给number number2 number3赋值
SET number =number+1;
SELECT SUBSTRING(MD5(RAND()+1), 1, 20) INTO number2;
SELECT SUBSTRING(MD5(RAND()+1), 1, 13) INTO number3;
最终脚本
DROP PROCEDURE
IF
EXISTS `insertdata`;
DELIMITER $$
CREATE
PROCEDURE `study`.`insertdata`(IN record INTEGER)
BEGIN
DECLARE number INTEGER ;
DECLARE number2 VARCHAR(64);
DECLARE number3 VARCHAR(64);
SET number=1;
SELECT SUBSTRING(MD5(RAND()+1), 1, 20) INTO number2;
SELECT SUBSTRING(MD5(RAND()+1), 1, 13) INTO number3;
START TRANSACTION;
WHILE number <=record DO
INSERT INTO
study.t_study
(imsi,
iccid,
provider,
status_name,
describe_detail,
access_number,
create_time,
update_time)
VALUES(
'400000000000000',
number2,
'Unicom',
'0',
'详细描述',
number3,
1641279461000,
1641279461000);
SET number =number+1;
SELECT SUBSTRING(MD5(RAND()+1), 1, 20) INTO number2;
SELECT SUBSTRING(MD5(RAND()+1), 1, 13) INTO number3;
END WHILE;
COMMIT;
END$$
DELIMITER ;