我是靠谱客的博主 坚强荷花,最近开发中收集的这篇文章主要介绍MySQL存储过程中的游标使用、循环简单实例,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

 MySQL 5.0 版本开始支持存储过程。

存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。

存储过程是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。

存储过程思想上很简单,就是数据库 SQL 语言层面的代码封装与重用。

 

优点

  • 存储过程可封装,并隐藏复杂的商业逻辑。
  • 存储过程可以回传值,并可以接受参数。
  • 存储过程无法使用 SELECT 指令来运行,因为它是子程序,与查看表,数据表或用户定义函数不同。
  • 存储过程可以用在数据检验,强制实行商业逻辑等。

创建存储过程

CREATE
[DEFINER = { user | CURRENT_USER }]
 PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body
proc_parameter:
[ IN | OUT | INOUT ] param_name type
characteristic:
COMMENT 'string'
| LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
routine_body:
  Valid SQL routine statement
[begin_label:] BEGIN
  [statement_list]
    ……
END [end_label]

 

MYSQL 存储过程中的关键语法

-- 声明语句结束符,可以自定义:
DELIMITER $$
或
DELIMITER //
-- 声明存储过程:
CREATE PROCEDURE demo_in_parameter(IN p_in int)
-- 存储过程开始和结束符号:
BEGIN .... END
-- 变量赋值:
SET @p_in=1
-- 变量定义:
DECLARE l_int int unsigned default 4000000;
-- 创建mysql存储过程、存储函数:
create procedure 存储过程名(参数)
-- 存储过程体:
create function 存储函数名(参数)

 

声明异常处理的语法

-- 声明异常处理的语法结构
DECLARE
{EXIT | CONTINUE}
HANDLER FOR
{error-number | SQLSTATE error-string | condition}
SQL statement


上述定义包括:
Handler Type (CONTINUE,EXIT)//处理类型 继续或退出
Handler condition (SQLSTATE,MYSQL ERROR,CONDITION)//触发条件
Handler actions(错误触发的操作)


注意:
1、exit只退出当前的block。exit 意思是当动作成功提交后,退出所在的复合语句。即declare exit handler for... 所在的复合语句。
2、如果定义了handler action,会在continue或exit之前执行


发生错误的条件有:
1、MYSQL错误代码
2、ANSI-standard SQLSTATE code
3、命名条件。可使用系统内置的SQLEXCEPTION,SQLWARNING和NOT FOUND


命名条件:
declare conditon_name condition for {SQLSTATE sqlstate_code | MYSQL_ERROR_CODE};

附常见错误号对照表

MySQL error code SQLSTATE code Error message

1011 HY000 Error on delete of '%s' (errno: %d)
1021 HY000 Disk full (%s); waiting for someone to free some space . . .
1022 23000 Can't write; duplicate key in table '%s'
1027 HY000 '%s' is locked against change
1036 HY000 Table '%s' is read only
1048 23000 Column '%s' cannot be null
1062 23000 Duplicate entry '%s' for key %d
1099 HY000 Table '%s' was locked with a READ lock and can't be updated
1100 HY000 Table '%s' was not locked with LOCK TABLES
1104 42000 The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is okay
1106 42000 Incorrect parameters to procedure '%s'
1114 HY000 The table '%s' is full
1150 HY000 Delayed insert thread couldn't get requested lock for table %s
1165 HY000 INSERT DELAYED can't be used with table '%s' because it is locked with LOCK TABLES
1242 21000 Subquery returns more than 1 row
1263 22004 Column set to default value; NULL supplied to NOT NULL column '%s' at row %ld
1264 22003 Out of range value adjusted for column '%s' at row %ld
1265 1000 Data truncated for column '%s' at row %ld
1312 0A000 SELECT in a stored program must have INTO
1317 70100 Query execution was interrupted
1319 42000 Undefined CONDITION: %s
1325 24000 Cursor is already open
1326 24000 Cursor is not open
1328 HY000 Incorrect number of FETCH variables
1329 2000 No data to FETCH
1336 42000 USE is not allowed in a stored program
1337 42000 Variable or condition declaration after cursor or handler declaration
1338 42000 Cursor declaration after handler declaration
1339 20000 Case not found for CASE statement
1348 HY000 Column '%s' is not updatable
1357 HY000 Can't drop a %s from within another stored routine
1358 HY000 GOTO is not allowed in a stored program handler
1362 HY000 Updating of %s row is not allowed in %s trigger
1363 HY000 There is no %s row in %s trigger

-- 错误异常处理片段
-- 游标循环变量,遍历数据结束标志,默认false
DECLARE done INT DEFAULT FALSE;
DECLARE cur_account CURSOR FOR SELECT id,`status` FROM adm_users;
-- 当错误代码为1329时将 done 的值设为TRUE,并继续执行当前任务
DECLARE CONTINUE HANDLER FOR 1329 SET done = TRUE;
-- 也可以这么写:使用的条件为ANSI标准错误代码
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = TRUE;
-- 也可以这么写
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

 

实例 

DELIMITER $$
CREATE PROCEDURE cs() -- 创建存储过程
BEGIN -- 开始存储过程
DECLARE vid INT(10) UNSIGNED DEFAULT 0;
-- 自定义变量id
DECLARE vstu TINYINT(1) UNSIGNED DEFAULT 0;
-- 自定义变量id
-- 游标循环变量,遍历数据结束标志,默认false
DECLARE done INT DEFAULT FALSE;
-- 定义游标并输入结果集
DECLARE cur_account CURSOR FOR SELECT id,`status` FROM adm_users;
-- 将结束标志绑定到游标,游标循环结束自动转true
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
-- 打开游标
OPEN
cur_account;
-- 开始循环,read_loop为自定义循环名,结束循环时用到
read_loop: LOOP
-- 取值 将游标当前读取行的数据顺序赋予自定义变量
FETCH cur_account INTO vid,vstu;
-- 判断是否继续循环
IF done THEN
LEAVE read_loop; -- 结束循环
END IF;
-- 你自己想做的操作
-- SELECT vid,vstu;
-- 重新插入一条语句
INSERT INTO `adm_users`(`username`, `password`, `verify_pwd`, `name`, `type`, `gid`, `status`, `add_time`)
SELECT `username`, `password`, `verify_pwd`, `name`, `type`, `gid`, `status`, UNIX_TIMESTAMP() AS `add_time` FROM `adm_users` WHERE id = vid;
SELECT vid,vstu,LAST_INSERT_ID() AS fristin;
-- 结束自定义循环体
END LOOP read_loop;
CLOSE cur_account; -- 关闭游标
END $$ -- 结束存储过程
DELIMITER ;

 

最后

以上就是坚强荷花为你收集整理的MySQL存储过程中的游标使用、循环简单实例的全部内容,希望文章能够帮你解决MySQL存储过程中的游标使用、循环简单实例所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部