MySQL 存储过程里使用游标

#定义存储过程,并命名为proc_traceLog 
1
BEGIN 2 #声明临时变量 3 DECLARE planNo VARCHAR(32); 4 DECLARE trainNo VARCHAR(32); 5 DECLARE content VARCHAR(255); 6 DECLARE done int DEFAULT 0 ; 7 8 DECLARE cur_train CURSOR FOR 9 SELECT p.plan_no,p.train_no,g.operate_content 10 FROM nature_order_plan p LEFT JOIN 11 (SELECT c.`no`,c.operate_content 12 FROM common_log c JOIN( SELECT `no`,MAX(id) id FROM common_log GROUP BY `no`) l ON c.id = l.id 13 )g ON p.plan_no = g.`no` 14 WHERE p.`status` = 40 15 AND p.transport_way = '铁运门到站'; 16 17 #设置循环结束标志 18 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; 19 20 #如果临时表已存在,删除临时表 21 DROP TABLE IF EXISTS tmpTable; 22 23 #创建临时表 24 CREATE TABLE tmpTable 25 ( 26 plan_no VARCHAR(32), 27 train_no VARCHAR(32), 28 cabinet_no VARCHAR(32), 29 operate_content VARCHAR(255) 30 ); 31 32 #打开游标 33 OPEN cur_train; 34 35 #遍历游标 36 REPEAT 37 FETCH cur_train INTO planNo,trainNo,content; 38 IF NOT done THEN 39 #有火车号,则将计划单号、火车号、最新日志插入到临时表 40 IF trainNo THEN 41 INSERT INTO tmpTable(plan_no,train_no,operate_content) VALUES(planNo,trainNo,content); 42 #否则插入计划单号、集装箱号、对应的最新日志到临时表 43  ELSE 44 INSERT INTO tmpTable(plan_no,cabinet_no,operate_content) 45 SELECT p.plan_no,c.cabinet_no,l.operate_content 46 FROM nature_order_plan p JOIN nature_order_plan_cabinet c ON p.plan_no = c.plan_no 47 LEFT JOIN(SELECT a.`no` AS plan_no,b.canbinet_no,a.operate_content 48 FROM common_log a JOIN( SELECT `no` AS plan_no,SUBSTR(operate_content FROM 5 FOR 11) AS canbinet_no,MAX(id) AS id 49 FROM common_log 50 WHERE source = '12306' 51 AND module = 2 52 AND type = 0 53 AND `no` = planNo 54 GROUP BY SUBSTR(operate_content FROM 5 FOR 11) 55 ) b ON a.id = b.id 56 )l ON c.plan_no = l.plan_no AND c.cabinet_no = l.canbinet_no 57 WHERE p.plan_no = planNo; 58 END IF; 59 END IF; 60 UNTIL done 61 END REPEAT; #循环结束 62 CLOSE cur_train; 63 END

注意:MySQL定义游标之前不能定义别的操作语句,所以把定义表放在了定义游标的后面

python3调用存储过程如下:

import pymysql.cursors

class CrawlDao():
    def __init__(self):
        self.connect = pymysql.connect(host=getDBHost(), port=getDBPort(), user=getDBUsername(),
                                       passwd=getDBPassword(),
                                       db=getDBDatabase(), charset=getDBCharset())
        self.cursors = self.connect.cursor()
        self.logger = Logger('CrawlDao').getLogger()

    def selectPlanOrderLog(self):
        '''
        调用存储过程proc_traceLog,将状态为服务中,运输方式为铁运的计划单插入到tmpTable表中
        tmpTable表数据分为2部分,一部分是火车号train_no不为空,则不查询集装箱号cabinet_no,最新日志取最新一条
        第二部分是火车号train_no为空,查询集装箱号及对应的最新日志(截取操作日志取集装箱号进行关联)
        :return:计划单号、火车号、集装箱号、最新操作日志
        '''

     #调用存储过程 self.cursors.callproc('proc_traceLog') cmd = 'SELECT plan_no,train_no,cabinet_no,operate_content FROM tmpTable;' try: self.cursors.execute(cmd) result_tuple = self.cursors.fetchall() return result_tuple # 返回数据类型为元祖 except Exception as e: self.logger("查询计划单失败:%s" % e) finally: self.cursors.close() self.connect.close()
原文地址:https://www.cnblogs.com/huhu-xiaomaomi/p/9755459.html