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 boot整合dubbo+zookeeper的详细过程

《Springboot整合dubbo+zookeeper的详细过程》本文讲解SpringBoot整合Dubbo与Zookeeper实现API、Provider、Consumer模式,包含依赖配置、... 目录Spring boot整合dubbo+zookeeper1.创建父工程2.父工程引入依赖3.创建ap

SpringBoot3.X 整合 MinIO 存储原生方案

《SpringBoot3.X整合MinIO存储原生方案》本文详细介绍了SpringBoot3.X整合MinIO的原生方案,从环境搭建到核心功能实现,涵盖了文件上传、下载、删除等常用操作,并补充了... 目录SpringBoot3.X整合MinIO存储原生方案:从环境搭建到实战开发一、前言:为什么选择MinI

SQL server数据库如何下载和安装

《SQLserver数据库如何下载和安装》本文指导如何下载安装SQLServer2022评估版及SSMS工具,涵盖安装配置、连接字符串设置、C#连接数据库方法和安全注意事项,如混合验证、参数化查... 目录第一步:打开官网下载对应文件第二步:程序安装配置第三部:安装工具SQL Server Manageme

C#连接SQL server数据库命令的基本步骤

《C#连接SQLserver数据库命令的基本步骤》文章讲解了连接SQLServer数据库的步骤,包括引入命名空间、构建连接字符串、使用SqlConnection和SqlCommand执行SQL操作,... 目录建议配合使用:如何下载和安装SQL server数据库-CSDN博客1. 引入必要的命名空间2.

Linux下进程的CPU配置与线程绑定过程

《Linux下进程的CPU配置与线程绑定过程》本文介绍Linux系统中基于进程和线程的CPU配置方法,通过taskset命令和pthread库调整亲和力,将进程/线程绑定到特定CPU核心以优化资源分配... 目录1 基于进程的CPU配置1.1 对CPU亲和力的配置1.2 绑定进程到指定CPU核上运行2 基于

全面掌握 SQL 中的 DATEDIFF函数及用法最佳实践

《全面掌握SQL中的DATEDIFF函数及用法最佳实践》本文解析DATEDIFF在不同数据库中的差异,强调其边界计算原理,探讨应用场景及陷阱,推荐根据需求选择TIMESTAMPDIFF或inte... 目录1. 核心概念:DATEDIFF 究竟在计算什么?2. 主流数据库中的 DATEDIFF 实现2.1

MySQL 多列 IN 查询之语法、性能与实战技巧(最新整理)

《MySQL多列IN查询之语法、性能与实战技巧(最新整理)》本文详解MySQL多列IN查询,对比传统OR写法,强调其简洁高效,适合批量匹配复合键,通过联合索引、分批次优化提升性能,兼容多种数据库... 目录一、基础语法:多列 IN 的两种写法1. 直接值列表2. 子查询二、对比传统 OR 的写法三、性能分析

MySQL中的LENGTH()函数用法详解与实例分析

《MySQL中的LENGTH()函数用法详解与实例分析》MySQLLENGTH()函数用于计算字符串的字节长度,区别于CHAR_LENGTH()的字符长度,适用于多字节字符集(如UTF-8)的数据验证... 目录1. LENGTH()函数的基本语法2. LENGTH()函数的返回值2.1 示例1:计算字符串

浅谈mysql的not exists走不走索引

《浅谈mysql的notexists走不走索引》在MySQL中,​NOTEXISTS子句是否使用索引取决于子查询中关联字段是否建立了合适的索引,下面就来介绍一下mysql的notexists走不走索... 在mysql中,​NOT EXISTS子句是否使用索引取决于子查询中关联字段是否建立了合适的索引。以下

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys