mysql存储过程如何利用临时表返回结果集
作者:你好龙卷风!!! 发布时间:2024-01-13 07:39:05
标签:mysql,存储过程,临时表,结果集
首先要声明的是
1,游标的方法会很慢在mysql中,在oracle数据库中还可以,除非没有别的方法,一般不建议在mysql中使用游标,
2,不建议在mysql中拼接sql,会使存储过程显得很臃肿,可以使用or来动态判别传入的参数是否为空
and ( TTB.office_id=输入参数 or 输入参数 is null or 输入参数 = '')
and ( TTB.office_id=IN_Office_id or IN_Office_id is null or IN_Office_id = '')
3,不建议使用临时表来存储多用户下经常查询的内容,比如报表
4,返回结果集更好的方法是直接链接多个表返回结果集即可,下面的示例虽然给以得到正确结果,
但代码臃肿,速度异常的慢,可以当个反面教材
5,优化后的存储过程:https://www.jb51.net/article/263729.htm
测试示例
BEGIN
#创建一个临时表
DROP TABLE if exists user_temporary;
create temporary table if not exists user_temporary
(
idVARCHAR(64) primary key,#id
user_name VARCHAR(20) #姓名
) ;
begin
#定义 变量 接收id和姓名
declare a VARCHAR(64);
declare b VARCHAR(20);
#这个用于处理游标到达最后一行的情况
DECLARE s int default 0;
#声明游标cursor_name(cursor_name是个多行结果集)
DECLARE cursor_name CURSOR FOR select id ,name from user ;
#设置一个终止标记
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET s=1;
#打开游标
OPEN cursor_name;
#获取游标当前指针的记录,读取一行数据并传给变量a,b
fetch cursor_name into a,b;
#开始循环,判断是否游标已经到达了最后作为循环条件
while s <> 1 do
insert into user_temporary(id,user_name) values(a,b);
#读取下一行的数据
fetch cursor_name into a,b;
end while;
#关闭游标
CLOSE cursor_name ;
#从临时表中拿到结果集
SELECT * from user_temporary;
#语句执行结束
end;
END
注意类型 为存储过程 procedure 不是存储函数function
运行结果:
真实需求,查找出所有用建单情况
BEGIN
DROP TABLE if exists user_temporary;
create temporary table if not exists user_temporary
(
idVARCHAR(64) primary key,id
user_name VARCHAR(20) ,#姓名
company_name VARCHAR(20) ,#所属公司
worksheet_num INTEGER,#机会点总数
sign_worksheet_num INTEGER ,#签单数量
exchange_num INTEGER ,#填写交流记录次数
sales_volume double(20,2) #销售额
) ;
begin
#定义 变量
declare a_id VARCHAR(64);
declare b_user_name VARCHAR(20);
declare c_company_name VARCHAR(20);
declare d_worksheet_num int ;
declare e_sign_worksheet_num int ;
declare f_exchange_num int ;
declare g_sales_volume double(20,2) ;
#这个用于处理游标到达最后一行的情况
DECLARE s int default 0;
#声明游标cursor_name(cursor_name是个多行结果集)
DECLARE cursor_name CURSOR FOR
select a.id ,a.name ,o.name AS company_name from sys_user a LEFT JOIN sys_office o on a.company_id =o.id;
#设置一个终止标记
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET s=1;
#打开游标
OPEN cursor_name;
#获取游标当前指针的记录,读取一行数据并传给变量a,b
fetch cursor_name into a_id,b_user_name ,c_company_name;
#开始循环,判断是否游标已经到达了最后作为循环条件
while s <> 1 do
#读取下一行的数据
#声明输入变量,以便在sql串中拼接
set @userId=a_id;
set @beginDate=begin_date;
set @endDate=end_date;
#收集总机会点 有if判断用拼接sql,然后再解析执行sql,
set @exesqlAll =CONCAT('SELECT count(1) into @handle_num FROM crm_worksheet
where create_by=@userId and del_flag=0 ');
IF begin_date is not null and begin_date !='' THEN
set@exesqlAll =CONCAT(@exesqlAll,' AND TO_DAYS(create_date) >=TO_DAYS(@beginDate)');
END IF;
IF end_date is not null and end_date !='' THEN
set@exesqlAll =CONCAT(@exesqlAll,' AND TO_DAYS(create_date) <=TO_DAYS(@endDate)');
END IF;
prepare allWorksheet from @exesqlAll;#解析sql
execute allWorksheet;#执行sql
DEALLOCATE prepare allWorksheet;#释放sql
SET d_worksheet_num = @handle_num;#变量赋值
IF d_worksheet_num > 0 THEN
set @exesqlSign =CONCAT('SELECT count(1) into @sign_num FROM crm_worksheet
where create_by=@userId and del_flag=0 and important_degree=''sys_basic_qian_shu_he_tong'' ');
IF begin_date is not null and begin_date !='' THEN
set@exesqlSign =CONCAT(@exesqlSign,' AND TO_DAYS(create_date) >=TO_DAYS(@beginDate)');
END IF;
IF end_date is not null and end_date !='' THEN
set@exesqlSign =CONCAT(@exesqlSign,' AND TO_DAYS(create_date) <=TO_DAYS(@endDate)');
END IF;
prepare signWorksheet from @exesqlSign;
execute signWorksheet;
DEALLOCATE prepare signWorksheet;
SET e_sign_worksheet_num = @sign_num;
#收集交流次数
set @exesqlExchange =CONCAT('SELECT COUNT(1) into @exchange_num from crm_wkst_exchange_record e LEFT JOIN
crm_worksheet w on e.worksheet_no= w.worksheet_no where w.create_by=@userId and w.del_flag=0');
IF begin_date is not null and begin_date !='' THEN
set@exesqlExchange =CONCAT(@exesqlExchange,' AND TO_DAYS(w.create_date) >=TO_DAYS(@beginDate)');
END IF;
IF end_date is not null and end_date !='' THEN
set@exesqlExchange =CONCAT(@exesqlExchange,' AND TO_DAYS(w.create_date) <=TO_DAYS(@endDate)');
END IF;
prepare exchangeWorksheet from @exesqlExchange;
execute exchangeWorksheet;
DEALLOCATE prepare exchangeWorksheet;
SET f_exchange_num = @exchange_num;
#收集销售额
set @exesqlSales =CONCAT('SELECT (@sumSalary := @sumSalary + solution) AS count into @sales_num FROM crm_worksheet cw , (SELECT @sumSalary := 0) b
WHERE cw.create_by=@userId and important_degree=''sys_basic_qian_shu_he_tong'' and cw.del_flag=0 ORDER BY count desc limit 1 ');
IF begin_date is not null and begin_date !='' THEN
set@exesqlExchange =CONCAT(@exesqlExchange,' AND TO_DAYS(cw.create_date) >=TO_DAYS(@beginDate)');
END IF;
IF end_date is not null and end_date !='' THEN
set@exesqlExchange =CONCAT(@exesqlExchange,' AND TO_DAYS(cw.create_date) <=TO_DAYS(@endDate)');
END IF;
prepare salesWorksheet from @exesqlSales;
execute salesWorksheet;
DEALLOCATE prepare salesWorksheet;
SET g_sales_volume = @sales_num;
ELSE
SET e_sign_worksheet_num=0; SET f_exchange_num=0; SET g_sales_volume=0;
END IF;
insert into user_temporary(id,user_name,company_name,sign_worksheet_num,exchange_num,worksheet_num,sales_volume)
values(a_id,b_user_name,c_company_name,e_sign_worksheet_num,f_exchange_num,d_worksheet_num,g_sales_volume); #插入临时表
fetch cursor_name into a_id,b_user_name ,c_company_name;
end while;
#关闭游标
CLOSE cursor_name ;
#从临时表中查出结果集
set @userIdInput=user_id;
set @exesqlResult =CONCAT('SELECT user_name,company_name,sign_worksheet_num,exchange_num,worksheet_num,sales_volume from user_temporary');
IF user_id is not null and user_id !='' THEN
set@exesqlResult =CONCAT(@exesqlResult,' where id = @userIdInput');
END IF;
prepare resultUser from @exesqlResult;
execute resultUser;
DEALLOCATE prepare resultUser;
#语句执行结束
end;
END
运行结果
来源:https://blog.csdn.net/zhaofuqiangmycomm/article/details/88651446


猜你喜欢
- 微信小程序图片上传,供大家参考,具体内容如下先来看一下微信小程序的api来看一下页面效果查看大图wxml文件代码:<view clas
- 前言MySQL 服务器正确安装以后,可以通过命令行管理工具或者图形化的管理工具来操作 MySQL 数据库。MySQL 图形化管理工具极大地方
- 数据库响应慢问题最多的就是查询了。现在大部分数据库都提供了性能分析的帮助手段。例如Oracle中会帮你直接找出慢的语句,并且提供优化方案。在
- Hello大家好,今天说一下python的socket编程,基于python的socket通信的文本框网络聊天首先,实验环境:一个云服务器(
- osc的rss不是全文输出的,不开心,所以就有了python抓取osc最新博客生成Rss# -*- coding: utf-8 -*-fro
- 有些 MySQL 数据表中可能存在重复的记录,有些情况我们允许重复数据的存在,但有时候我们也需要删除这些重复的数据。本章节我们将为大家介绍如
- 本文实例为大家分享了python绘制箱型图的具体代码,供大家参考,具体内容如下import numpy as npimport pandas
- Java Java 是由 Sun 公司开发而成的一种编程语言,利用 Jave 写成的小程序叫做 Java
- 现在小编已经学习语言程序良久,但是在了解以后,如果让小编再去学习语言要入手入口,一定是先从掌握函数开始了解,原因很简单,任何一个代码串都是有
- 类是面向对象程序设计的一部分。面向对象程序设计或者简称为 OOP 致力于创建可重用代码块称之为类。当你想在你的程序中使用类时,你会从类中创建
- mint19.2 本来pip 和 pip2 对应 python2.7 pip3对应pytho
- 引言事情是这样的,最近在做开源软件供应链安全相关的项目,之前没了解这方面知识的时候感觉服务器被黑,数据库被删,网站被攻,这些东西都离我们太遥
- 博主做过比较多项目的archive脚本编写,对于这种删除数据的脚本开发,肯定是一开始的话用最简单的一个delete语句,然后由于部分表数据量
- 1. 计算给出两个时间之间的时间差import datetime as dt# current timecur_time = dt.date
- 在上一篇文章《Python教程—模拟网页点击爬虫定位系统》讲解怎么通过模拟点击方式爬取车辆定位数据,本次介绍怎么以模拟点击方式进入交管121
- 一、yield运行方式我们定义一个如下的生成器:def put_on(name): print("Hi {}, 货物来了,准备搬到
- 递归和尾递归简单的说,递归就是函数自己调用自己,它做为一种算法在程序设计语言中广泛应用。其核心思想是把一个大型复杂的问题层层转化为一个与原问
- 前言在SQL Server中,我们知道一个SELECT语句执行过程中只会申请一些意向共享锁(IS) 与共享锁(S), 例如我使用SQL Pr
- import cv2import numpy as npimport matplotlib.pyplot as plt# Grayscale
- 前言序锦在编程中,经常要用到字符串的相互转换,现在在这里记录一下Python里面的字符串和整数以及浮点型数之间是如何进行相互转换的。int(