Navicat中如何调试存储过程

存储过程调试方法

参考

https://www.cnblogs.com/firebata/p/4585978.htmlhtml

https://www.cnblogs.com/kungfupanda/p/5645553.html框架

调试很是麻烦

如何在存储过程当中注释?

在存储过程编辑中没法注释,因此须要先将代码拷贝到普通查询页,在查询页注释好,而后再将代码拷贝回存储过程当中,保存。oop

变量定义

定义varchar变量必须指明大小

如varchar(10),不然会报错测试

游标须要定义在全部其余变量以后,不然会报 1337 错误

ERROR 1337 (42000): Variable or condition declaration after cursorfetch

变量的定义不要和你的select的列的键同名!否则,fetch into 会失败!

这个没试,可是名字最好不要和列名同名,这样也更易读。spa

语法方面

存储过程当中必定要记得在语句后面加上分号“;”,不然会报看起来莫名其妙的错误

调试技巧:可使用 SELECT @a 查看打印的变量,可是注意 @a看到的是最终的变量,中间变量是没法看到的

使用 SELECT @a看到的结果中的 @a 值是最终值,中间变量是没法看到的,因此说调试很是麻烦,没法打印变量在运行中间的值.net

★调试的技巧

也是定位错误的方法(由于根据提示的错误很难定位到错误的语句位置):删除无关的语句,排除的方法。设计

边开发边测试:(1)设计好总体思路;(2)将思路框架写出来,先不要填充细节部分,好比有的复杂的实现,能够先空着或者简单的打印一些变量,边写边测,及时发现各类问题;(3)思路框架写出来后,若是测试没有问题,再补充细节代码,最好写一部分就测试一下。由于调试太麻烦的缘由,这样比较稳妥。调试

游标的使用

参考

https://www.cnblogs.com/trying/p/3296793.htmlhtm

使用

游标须要定义在全部其余变量以后,不然会报 1337 错误

如何循环?

如何结束?

如何调试?调试很是麻烦

游标使用示例存储过程1

背景说明

将表t中的数据拷贝至表t1

建表语句

-- ----------------------------

-- Table structure for t

-- ----------------------------

DROP TABLE IF EXISTS `t`;

CREATE TABLE `t` (

  `i` int(11) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

-- ----------------------------

-- Records of t

-- ----------------------------

INSERT INTO `t` VALUES ('1');

INSERT INTO `t` VALUES ('2');

 

-- ----------------------------

-- Table structure for t1

-- ----------------------------

DROP TABLE IF EXISTS `t1`;

CREATE TABLE `t1` (

  `i` int(11) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

存储过程testCopy

-- ----------------------------

-- Procedure structure for testCopy

-- ----------------------------

DROP PROCEDURE IF EXISTS `testCopy`;

DELIMITER ;;

CREATE DEFINER=`root`@`localhost` PROCEDURE `testCopy`()

BEGIN

-- 须要定义接收游标数据的变量

  DECLARE a CHAR(16);

  

  -- 遍历数据结束标志

  DECLARE done INT DEFAULT FALSE;

-- 游标,游标须要定义在全部其余变量以后,不然会报 1337 错误

  DECLARE cur CURSOR FOR SELECT i FROM t;

  -- 将结束标志绑定到游标

  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

 

  -- 打开游标

  OPEN cur;

  

  -- 开始循环

  read_loop: LOOP

    -- 提取游标里的数据,这里只有一个,多个的话也同样;

    FETCH cur INTO a;

    -- 声明结束的时候

    IF done THEN

      LEAVE read_loop;

    END IF;

    -- 这里作你想作的循环的事件

 

    INSERT INTO t1 VALUES (a);

 

  END LOOP;

  -- 关闭游标

  CLOSE cur;

 

END

;;

DELIMITER ;

游标使用示例存储过程2

建表语句

-- ----------------------------

-- Table structure for current

-- ----------------------------

DROP TABLE IF EXISTS `current`;

CREATE TABLE `current` (

  `player` varchar(11) DEFAULT NULL,

  `market` varchar(11) DEFAULT NULL,

  `money` int(11) DEFAULT NULL,

  `dateno` int(11) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

-- ----------------------------

-- Records of current

-- ----------------------------

INSERT INTO `current` VALUES ('小明', '永辉', '100', '20190807');

INSERT INTO `current` VALUES ('小明', '物美', '200', '20190807');

INSERT INTO `current` VALUES ('小刚', '家乐福', '230', '20190807');

 

-- ----------------------------

-- Table structure for history

-- ----------------------------

DROP TABLE IF EXISTS `history`;

CREATE TABLE `history` (

  `player` varchar(11) DEFAULT NULL,

  `market` varchar(11) DEFAULT NULL,

  `money` int(11) DEFAULT NULL,

  `dateno` int(11) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

-- ----------------------------

-- Records of history

-- ----------------------------

背景说明

表current,表history

结构一致,均为

player 送货员

market 超市

money 送货钱数

dateno 日期序号

想象一个送货员能够帮多家超市(永辉、物美、家乐福等)送货,每次送货都会是必定的金额(从几十元到几百上千元)。

current记录的是今天某个送货员给给家送货的金额状况。

history记录的今天以前的累计状况。

那么存储过程testMerge就是执行这么个操做:将current表中的数据累计到history表中,而后删除累计过的数据。

思路:(1)选取current表中符合条件的记录到游标;(2)操做游标,看是往history表中插入记录,仍是更新history表中的记录;(3)操做完毕关闭游标。

往history表中插入记录,仍是更新history表中的记录的判断条件:使用【送货员,超市】联合键判断,history中存在【送货员,超市】联合键,则将current中的送货钱数累加到以前的记录;history中不存在【送货员,超市】联合键,则向history中新增一条记录。

暂时只是测试例子,实际可继续完善。

存储过程testMerge

-- ----------------------------

-- Procedure structure for testMerge

-- ----------------------------

DROP PROCEDURE IF EXISTS `testMerge`;

DELIMITER ;;

CREATE DEFINER=`root`@`localhost` PROCEDURE `testMerge`()

BEGIN

-- 须要定义接收游标数据的变量

  DECLARE player_param VARCHAR(10);

DECLARE market_param VARCHAR(10);

DECLARE money_param INT;

 

DECLARE exist_record INT;

  

  -- 遍历数据结束标志

  DECLARE done INT DEFAULT FALSE;

-- 游标,游标须要定义在全部其余变量以后,不然会报 1337 错误

  DECLARE record_list CURSOR FOR

SELECT

player,

market,

money

FROM

current

WHERE

dateno < 20190808;

  -- 将结束标志绑定到游标

  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

 

  -- 打开游标

  OPEN record_list;

  

  -- 开始循环

  read_loop: LOOP

    -- 提取游标里的数据,这里只有一个,多个的话也同样;

    FETCH record_list INTO player_param,market_param,money_param;

    -- 声明结束的时候

    IF done THEN

      LEAVE read_loop;

    END IF;

 

SELECT COUNT(*) INTO @exist_record FROM history WHERE player = player_param AND market = market_param;

 

IF @exist_record = 0 THEN

    -- 这里作你想作的循环的事件

INSERT INTO history VALUES (player_param,market_param,money_param,0);

END IF;

 

IF @exist_record > 0 THEN

UPDATE history SET money = money + money_param WHERE player = player_param AND market = market_param;

END IF;

 

DELETE FROM current WHERE dateno = 20190807;

 

  END LOOP;

  -- 关闭游标

  CLOSE record_list;

 

END

;;

DELIMITER ;

相关文章
相关标签/搜索