mysql 5.6 存储过程+事务+游标+错误异常抛出+日志写入

本文主要是介绍mysql 5.6 存储过程+事务+游标+错误异常抛出+日志写入,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

MySQL的GET DIAGNOSTICS语句在5.6.4以后才有

简单讲GET DIAGNOSTICS作用:

语句信息,例如错误信息号或者语句影响的行数。
错误信息,例如错误号和错误消息。

使用GET DIAGNOSTICS需要注意的是,它或者包含语句信息,或者包含错误信息,但一个GET DIAGNOSTICS不会同时包含语句信息和错误信息,所以需要用两个GET DIAGNOSTICS来获得语句信息和错误信息。
获得语句信息:
GET DIAGNOSTICS @p1 = NUMBER, @p2 = ROW_COUNT;获得错误信息:
GET DIAGNOSTICS CONDITION 1 @p3 = RETURNED_SQLSTATE, @p4 = MESSAGE_TEXT;语句信息条目名称有:
NUMBER 
| ROW_COUNT错误信息条目名称有:
CLASS_ORIGIN 
| SUBCLASS_ORIGIN
| RETURNED_SQLSTATE
| MESSAGE_TEXT
| MYSQL_ERRNO
| CONSTRAINT_CATALOG
| CONSTRAINT_SCHEMA
| CONSTRAINT_NAME
| CATALOG_NAME
| SCHEMA_NAME
| TABLE_NAME
| COLUMN_NAME
| CURSOR_NAME为了确保获得正确的主错误信息,必须使用类似如下的语句:
GET DIAGNOSTICS @cno = NUMBER;
GET DIAGNOSTICS CONDITION @cno @errno = MYSQL_ERRNO;


以下的为转载:
原文地址:http://www.wolonge.com/post/detail/118249

DELIMITER $$


USE `ecstore`$$

DROP PROCEDURE IF EXISTS `proc_add_warranty_card`$$

CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_add_warranty_card`()
BEGIN     
     -- 获取异常信息
     DECLARE v_sql1 VARCHAR(500); 
     DECLARE v_sql2 VARCHAR(500); 
     #定义变量
     DECLARE w_warranty_id BIGINT(20) DEFAULT 1;
     DECLARE w_orderid BIGINT(20);
     DECLARE w_ordertime INT(10);
     DECLARE w_member_id MEDIUMINT(8);
     #定义游标遍历时,作为判断是否遍历完全部记录的标记
     DECLARE done1 INTEGER DEFAULT 0;  
     DECLARE data_err INTEGER DEFAULT 0;  
     DECLARE log_err INTEGER DEFAULT 0;  
     #定义保修卡主表为C_WARRANTY 
     DECLARE C_WARRANTY CURSOR FOR
    SELECT orde.order_id,
           orde.createtime,
           orde.member_id
    FROM `sdb_b2c_orders` AS orde 
    WHERE orde.ship_status='1' AND orde.status IN ('active','finish') AND (orde.warranty_id IS NULL);
     #声明当游标遍历完全部记录后将标志变量置成某个值
     DECLARE CONTINUE HANDLER FOR NOT FOUND SET done1=1;
     DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
     BEGIN
          ROLLBACK;
      GET DIAGNOSTICS CONDITION 1 v_sql1 = RETURNED_SQLSTATE,v_sql2= MESSAGE_TEXT;
      INSERT INTO `sdb_b2c_warranty_log` (`order_id`,`createtime`,`msg_text`)  
      VALUES (w_orderid,UNIX_TIMESTAMP(CURDATE()),CONCAT(v_sql1,':',v_sql2));
      SET log_err=1;
     END;
     #手动提交事务
     SET autocommit=0;
     OPEN C_WARRANTY;
     #取出每条记录并赋值给相关变量,注意顺序
     FETCH C_WARRANTY INTO w_orderid, w_ordertime, w_member_id;
     SET w_warranty_id=CONCAT(DATE_FORMAT(NOW(), '%Y%m%d'),LPAD((w_warranty_id), 5, '0'));        
     #循环语句的关键词   
     REPEAT
         -- 启动事务
         START TRANSACTION; 
         
         #保修卡主表添加
         INSERT INTO `sdb_b2c_warranty` (`warranty_id`,`order_id`,`ordertime`,`member_id`,`warranty_card_status`,`createtime`)  
             VALUES (w_warranty_id,w_orderid,w_ordertime,w_member_id,'1',UNIX_TIMESTAMP(CURDATE())); 
             IF log_err=0 THEN 
             #生成明细
             INSERT INTO `sdb_b2c_warranty_detail`(warranty_id,item_id,order_id,
                  obj_id,product_id,goods_id,type_id,bn,pn,`name`,nums,sendnum,addon,item_type) 
             SELECT w_warranty_id,ite.item_id,ite.`order_id`,ite.obj_id,ite.product_id,
                 ite.goods_id,ite.type_id,ite.bn,pro.store_place,ite.name,ite.nums,
                 ite.sendnum,ite.addon,ite.item_type
            FROM`sdb_b2c_order_items` AS ite
            LEFT JOIN `sdb_b2c_products` AS pro ON pro.product_id=ite.product_id
            WHERE ite.order_id=w_orderid;
        END IF;
        #回写订单表保修卡号
        IF log_err=0 THEN
         UPDATE `sdb_b2c_orders` SET `warranty_id`=w_warranty_id WHERE `order_id`= w_orderid;
        END IF;    
        COMMIT;
        SET log_err=0;   
        SET  done1=0;
     #取出每条记录并赋值给相关变量,注意顺序
     FETCH C_WARRANTY INTO w_orderid, w_ordertime, w_member_id;    
     SET  w_warranty_id =w_warranty_id+1;  
     #循环语句结束
     UNTIL done1  END REPEAT;   
     #关闭游标    
     CLOSE C_WARRANTY;  
     
     BEGIN
     #如果是退货,则把保修卡状态改成无效
     DECLARE card_order_id BIGINT(20);
     -- 获取异常信息
         DECLARE v_sql1 VARCHAR(500); 
         DECLARE v_sql2 VARCHAR(500); 
     DECLARE card_warranty_id BIGINT(20);
     #标记循环结束
     DECLARE done2 INTEGER DEFAULT 0;  
     DECLARE C_UPDATE_CARD_STATUS CURSOR FOR 
             SELECT war.`order_id`,war.`warranty_id` 
             FROM `sdb_b2c_orders`  AS orde
             JOIN `sdb_b2c_warranty` AS war ON orde.`order_id`=war.`order_id`
             WHERE orde.ship_status='4';
     #声明当游标遍历完全部记录后将标志变量置成某个值
     DECLARE CONTINUE HANDLER FOR NOT FOUND SET done2= 1; 
     DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
     BEGIN
        GET DIAGNOSTICS CONDITION 1 v_sql1 = RETURNED_SQLSTATE,v_sql2= MESSAGE_TEXT;
        INSERT INTO `sdb_b2c_warranty_log` (`order_id`,`createtime`,`msg_text`)  
        VALUES (w_orderid,UNIX_TIMESTAMP(CURDATE()),CONCAT(v_sql1,':',v_sql2));
     END;
     #打开明细游标
     OPEN C_UPDATE_CARD_STATUS;
        FETCH C_UPDATE_CARD_STATUS INTO card_order_id,card_warranty_id;
        REPEAT
          UPDATE sdb_b2c_warranty SET warranty_card_status='0',invalid_reason='0' WHERE warranty_card_status='1' AND `order_id`=card_order_id;    
          SET  done2=0;  #取出每条记录并赋值给相关变量,注意顺序
          FETCH C_UPDATE_CARD_STATUS INTO card_order_id,card_warranty_id;           
        #循环语句结束
        UNTIL done2  END REPEAT;
     CLOSE C_UPDATE_CARD_STATUS;
     END;
END$$

DELIMITER ;

这篇关于mysql 5.6 存储过程+事务+游标+错误异常抛出+日志写入的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1033268

相关文章

C++工程编译链接错误汇总VisualStudio

目录 一些小的知识点 make工具 可以使用windows下的事件查看器崩溃的地方 dumpbin工具查看dll是32位还是64位的 _MSC_VER .cc 和.cpp 【VC++目录中的包含目录】 vs 【C/C++常规中的附加包含目录】——头文件所在目录如何怎么添加,添加了以后搜索头文件就会到这些个路径下搜索了 include<> 和 include"" WinMain 和

C/C++的编译和链接过程

目录 从源文件生成可执行文件(书中第2章) 1.Preprocessing预处理——预处理器cpp 2.Compilation编译——编译器cll ps:vs中优化选项设置 3.Assembly汇编——汇编器as ps:vs中汇编输出文件设置 4.Linking链接——链接器ld 符号 模块,库 链接过程——链接器 链接过程 1.简单链接的例子 2.链接过程 3.地址和

mysql索引四(组合索引)

单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引;组合索引,即一个索引包含多个列。 因为有事,下面内容全部转自:https://www.cnblogs.com/farmer-cabbage/p/5793589.html 为了形象地对比单列索引和组合索引,为表添加多个字段:    CREATE TABLE mytable( ID INT NOT NULL, use

mysql索引三(全文索引)

前面分别介绍了mysql索引一(普通索引)、mysql索引二(唯一索引)。 本文学习mysql全文索引。 全文索引(也称全文检索)是目前搜索引擎使用的一种关键技术。它能够利用【分词技术】等多种算法智能分析出文本文字中关键词的频率和重要性,然后按照一定的算法规则智能地筛选出我们想要的搜索结果。 在MySql中,创建全文索引相对比较简单。例如:我们有一个文章表(article),其中有主键ID(

mysql索引二(唯一索引)

前文中介绍了MySQL中普通索引用法,和没有索引的区别。mysql索引一(普通索引) 下面学习一下唯一索引。 创建唯一索引的目的不是为了提高访问速度,而只是为了避免数据出现重复。唯一索引可以有多个但索引列的值必须唯一,索引列的值允许有空值。如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该使用关键字UNIQUE,把它定义为一个唯一索引。 添加数据库唯一索引的几种

mysql索引一(普通索引)

mysql的索引分为两大类,聚簇索引、非聚簇索引。聚簇索引是按照数据存放的物理位置为顺序的,而非聚簇索引则不同。聚簇索引能够提高多行检索的速度、非聚簇索引则对单行检索的速度很快。         在这两大类的索引类型下,还可以降索引分为4个小类型:         1,普通索引:最基本的索引,没有任何限制,是我们经常使用到的索引。         2,唯一索引:与普通索引

【服务器运维】MySQL数据存储至数据盘

查看磁盘及分区 [root@MySQL tmp]# fdisk -lDisk /dev/sda: 21.5 GB, 21474836480 bytes255 heads, 63 sectors/track, 2610 cylindersUnits = cylinders of 16065 * 512 = 8225280 bytesSector size (logical/physical)

SQL Server中,查询数据库中有多少个表,以及数据库其余类型数据统计查询

sqlserver查询数据库中有多少个表 sql server 数表:select count(1) from sysobjects where xtype='U'数视图:select count(1) from sysobjects where xtype='V'数存储过程select count(1) from sysobjects where xtype='P' SE

SQL Server中,always on服务器的相关操作

在SQL Server中,建立了always on服务,可用于数据库的同步备份,当数据库出现问题后,always on服务会自动切换主从服务器。 例如192.168.1.10为主服务器,12为从服务器,当主服务器出现问题后,always on自动将主服务器切换为12,保证数据库正常访问。 对于always on服务器有如下操作: 1、切换主从服务器:假如需要手动切换主从服务器时(如果两个服务

SQL Server中,isnull()函数以及null的用法

SQL Serve中的isnull()函数:          isnull(value1,value2)         1、value1与value2的数据类型必须一致。         2、如果value1的值不为null,结果返回value1。         3、如果value1为null,结果返回vaule2的值。vaule2是你设定的值。        如