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

相关文章

MySQL的JDBC编程详解

《MySQL的JDBC编程详解》:本文主要介绍MySQL的JDBC编程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、前置知识1. 引入依赖2. 认识 url二、JDBC 操作流程1. JDBC 的写操作2. JDBC 的读操作总结前言本文介绍了mysq

java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

《java.sql.SQLTransientConnectionException连接超时异常原因及解决方案》:本文主要介绍java.sql.SQLTransientConnectionExcep... 目录一、引言二、异常信息分析三、可能的原因3.1 连接池配置不合理3.2 数据库负载过高3.3 连接泄漏

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

oracle 11g导入\导出(expdp impdp)之导入过程

《oracle11g导入导出(expdpimpdp)之导入过程》导出需使用SEC.DMP格式,无分号;建立expdir目录(E:/exp)并确保存在;导入在cmd下执行,需sys用户权限;若需修... 目录准备文件导入(impdp)1、建立directory2、导入语句 3、更改密码总结上一个环节,我们讲了

Python中 try / except / else / finally 异常处理方法详解

《Python中try/except/else/finally异常处理方法详解》:本文主要介绍Python中try/except/else/finally异常处理方法的相关资料,涵... 目录1. 基本结构2. 各部分的作用tryexceptelsefinally3. 执行流程总结4. 常见用法(1)多个e

SpringBoot日志级别与日志分组详解

《SpringBoot日志级别与日志分组详解》文章介绍了日志级别(ALL至OFF)及其作用,说明SpringBoot默认日志级别为INFO,可通过application.properties调整全局或... 目录日志级别1、级别内容2、调整日志级别调整默认日志级别调整指定类的日志级别项目开发过程中,利用日志

Spring 中的切面与事务结合使用完整示例

《Spring中的切面与事务结合使用完整示例》本文给大家介绍Spring中的切面与事务结合使用完整示例,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录 一、前置知识:Spring AOP 与 事务的关系 事务本质上就是一个“切面”二、核心组件三、完

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

MyBatis-plus处理存储json数据过程

《MyBatis-plus处理存储json数据过程》文章介绍MyBatis-Plus3.4.21处理对象与集合的差异:对象可用内置Handler配合autoResultMap,集合需自定义处理器继承F... 目录1、如果是对象2、如果需要转换的是List集合总结对象和集合分两种情况处理,目前我用的MP的版本

深度解析Java @Serial 注解及常见错误案例

《深度解析Java@Serial注解及常见错误案例》Java14引入@Serial注解,用于编译时校验序列化成员,替代传统方式解决运行时错误,适用于Serializable类的方法/字段,需注意签... 目录Java @Serial 注解深度解析1. 注解本质2. 核心作用(1) 主要用途(2) 适用位置3