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

相关文章

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

SQL中的外键约束

外键约束用于表示两张表中的指标连接关系。外键约束的作用主要有以下三点: 1.确保子表中的某个字段(外键)只能引用父表中的有效记录2.主表中的列被删除时,子表中的关联列也会被删除3.主表中的列更新时,子表中的关联元素也会被更新 子表中的元素指向主表 以下是一个外键约束的实例展示

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

如何去写一手好SQL

MySQL性能 最大数据量 抛开数据量和并发数,谈性能都是耍流氓。MySQL没有限制单表最大记录数,它取决于操作系统对文件大小的限制。 《阿里巴巴Java开发手册》提出单表行数超过500万行或者单表容量超过2GB,才推荐分库分表。性能由综合因素决定,抛开业务复杂度,影响程度依次是硬件配置、MySQL配置、数据表设计、索引优化。500万这个值仅供参考,并非铁律。 博主曾经操作过超过4亿行数据

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

作业提交过程之HDFSMapReduce

作业提交全过程详解 (1)作业提交 第1步:Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。 第2步:Client向RM申请一个作业id。 第3步:RM给Client返回该job资源的提交路径和作业id。 第4步:Client提交jar包、切片信息和配置文件到指定的资源提交路径。 第5步:Client提交完资源后,向RM申请运行MrAp

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

MySQL数据库宕机,启动不起来,教你一招搞定!

作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG、Mongodb数据库运维(如安装迁移,性能优化、故障应急处理等)公众号:老苏畅谈运维欢迎关注本人公众号,更多精彩与您分享。 MySQL数据库宕机,数据页损坏问题,启动不起来,该如何排查和解决,本文将为你说明具体的排查过程。 查看MySQL error日志 查看 MySQL error日志,排查哪个表(表空间