热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mySql存储过程游标必须定义在临时表前?调用时发生临时不存在错误,求指导

mySql存储过程游标必须定义在临时表前?编译过了,但是,调用时发生临时不存在错误,求指导。存储过程如下dropPROCEDUREifEXISTSp_InventoryProc;CRE
mySql 存储过程游标必须定义在临时表前?
编译过了,但是,调用时发生临时不存在错误,求指导。存储过程如下

drop PROCEDURE if EXISTS p_InventoryProc;

CREATE PROCEDURE `p_InventoryProc`(in compId VARCHAR(36), in ReportRange INTEGER, in startTime VARCHAR(36), in endTime VARCHAR(36),in productCategoryId VARCHAR(36),in productId VARCHAR(36) )
BEGIN
  DECLARE v_querySqlUnion VARCHAR(5000); # union 所有结果集
  DECLARE v_querySql VARCHAR(500); # union 所有结果集
  DECLARE v_queryFrom VARCHAR(200);
  DECLARE v_queryField VARCHAR(100);
  DECLARE whereCondition VARCHAR(100);
  DECLARE v_rpDate VARCHAR(50);#游标报表日期
  DECLARE v_qryDate VARCHAR(50);#游标查询时间
  DECLARE done INT DEFAULT FALSE;

  #循环取同临时表的时间用于统计    条件 : BillDate <= 当前时间值
  DECLARE c_cursor CURSOR FOR SELECT queryDate,ReportDate from tmp_state;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  #创建时间统计维度临时表
  CREATE TEMPORARY TABLE IF NOT EXISTS tmp_date(queryDate varchar(20) not null, ReportDate VARCHAR(30) not null);

  #将时间维度插入临时表
  CASE ReportRange
  when 2 then  #按每周 7 日查询
     set @var=1;
     SELECT DATE_FORMAT (endTime ,'%Y-%m-%d'); #调整时间为每天结束 23:59:59
     set endTime=CONCAT(endTime,' 23:59:59');
     WHILE @var<7 DO
        set @rpDate=(SELECT DATE_FORMAT (endTime ,'%Y.%m.%d'));
        INSERT INTO tmp_date(queryDate,ReportDate) VALUES( endTime,@rpDate );
        #时间间隔控制
        set @var=@var+1;
        set endTime=(SELECT DATE_SUB(endTime, INTERVAL 1 DAY));
     END WHILE;
  when 3 then  #按每月 4~5 自然周查询 
     
     WHILE endTime>startTime DO 
        #拼接起止时间作为 报表时间字段  2014.12.08~2014.12.14 形式
        set @sDate=(SELECT DATE_FORMAT( (SELECT DATE_ADD(endTime,INTERVAL -WEEKDAY(endTime) day)),'%Y.%m.%d') );
        set @eDate=(SELECT DATE_FORMAT(endTime,'%Y.%m.%d') );
        set @rpDate=CONCAT(@sDate,'~',@eDate);
        
        INSERT INTO tmp_date(queryDate,ReportDate) VALUES( endTime, @rpDate );
        #时间间隔控制
        set endTime=(SELECT DATE_ADD(endTime,INTERVAL -WEEKDAY(endTime)+6 day));#获得此周结束时间间
        set endTime=(SELECT DATE_SUB(endTime,INTERVAL 1 WEEK));#从结束时间递减 一周(7天)直至 小于 开始时
        SELECT CONCAT(endTime,' 23:59:59');
     END WHILE;
  when 4 then  #按每年 12 个自然月查询
     WHILE endTime>startTime DO
        set @rpDate=(SELECT DATE_FORMAT(endTime,'%Y.%m'));
        INSERT INTO tmp_date(queryDate,ReportDate) VALUES(endTime,@rpDate);
        #时间间隔控制, 取得每个月最后一天日期的结束时间 23:59:59
        set endTime=(SELECT DATE_SUB(endTime,INTERVAL 1 MONTH));
        set endTime=(SELECT LAST_DAY(endTime));#确保是当月最后一天, INTERVAL 扣除天数 30,31 的月份不准 
        set endTime=CONCAT(endTime,' 23:59:59');
     END WHILE;
  ELSE #按自由天数查询
     WHILE endTime>startTime DO
        set @rpDate=(SELECT DATE_FORMAT(endTime,'%Y.%m.%d'));
        INSERT INTO tmp_date(queryDate,ReportDate) VALUES(endTime,@rpDate);
        #时间间隔控制
        set endTime=(SELECT DATE_SUB(endTime, INTERVAL 1 DAY));
     END WHILE;
  END CASE;

  #店铺id
  set whereCOndition=CONCAT('and st.CompanyId=', compId);
  #商品分类
  IF productCategoryId is NULL || productCategoryId = '' THEN
     set whereCOndition=CONCAT('and pd.CycleCode like %', productCategoryId,'% ');
  END IF;
  #商品id
  IF productId is NULL || productId = '' THEN
     set whereCOndition=CONCAT('and st.ProductId=', productId);
  END IF;
  
  #开启游标查询数据
  set @cFlag=0;
  OPEN c_cursor;
  REPEAT
    FETCH c_cursor INTO v_qryDate,v_rpDate;  
    SET whereCOndition=CONCAT(' and st.BillDate <=',v_qryDate);
    SET v_queryField=CONCAT('select ',v_rpDate,' as ReportDate, Sum(LastAmount) as TotalAmount, Sum(LastCount) as TotalCount ');
    SET v_queryFrom=CONCAT('from (select * from (select st.LastAmount,st.LastCount,st.ProductId,st.BillDate from kos_stocks_bo st LEFT JOIN kos_product pd on st.ProductId=pd.PD_ID LEFT JOIN kos_product_category pc on pd.ProductCategoryId = pc.PC_ID where 1=1 ',whereCondition,' ORDER BY BillDate desc) Group by ProductId) stock ');
    SET v_querySql=CONCAT(v_queryField,v_queryFrom);
    IF @cFlag>0 THEN
       set v_querySqlUnion=CONCAT(' union all ',v_querySql);
    ELSE
       set v_querySqlUnion=CONCAT(v_querySql);
    END IF;
    set @cFlag= @cFlag+1;
  UNTIL done
  END REPEAT;
  CLOSE c_cursor;
  
  set @v_sql=v_querySqlUnion;
  prepare stmt from @v_sql;  #预处理需要执行的动态SQL,其中stmt是一个变量
  EXECUTE stmt;      #执行SQL语句
  deallocate prepare stmt;
  
  #删除临时表
  DROP TEMPORARY  TABLE  IF EXISTS tmp_date;
END;

3 个解决方案

#1


学习了!~求答案

#2


这个没有办法,这是MYSQL的特性。
一种解决方法就是不要用临时表,而使用普通表。可以在普通表中添加一列标志,作为SESSION的标记不,当处理完记录后,则删除表中所有这个SESSIONID的记录。

#3


换了一种写法,不使用游标访问,直接取临时表数据,绕过游标声明问题:代码如下
BEGIN
  DECLARE v_querySqlUnion VARCHAR(50000); # union 所有结果集
  DECLARE v_querySql VARCHAR(1000); # union 所有结果集
  DECLARE v_queryFrom VARCHAR(500);
  DECLARE v_queryField VARCHAR(300);
  DECLARE whereCondition VARCHAR(300);
  DECLARE v_rpDate VARCHAR(50);#游标报表日期
  DECLARE v_qryDate VARCHAR(50);#游标查询时间
  DECLARE done INT DEFAULT FALSE;

  DECLARE v_minId INTEGER;
  DECLARE v_maxId INTEGER;

  #删除临时表
  DROP TEMPORARY  TABLE  IF EXISTS tmp_date;

  #创建时间统计维度临时表
  CREATE TEMPORARY TABLE IF NOT EXISTS tmp_date(
     tmp_id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, 
     queryDate varchar(20) not null,
     ReportDate VARCHAR(30) not null
  );

  #将时间维度插入临时表
  CASE ReportRange
  when 0 then #按自由时间间隔天数查询
     WHILE endTime>startTime DO
        set @rpDate=(SELECT DATE_FORMAT (endTime ,'%Y.%m.%d'));
        INSERT INTO tmp_date(queryDate,ReportDate) VALUES( endTime, @rpDate );
        set endTime=(SELECT DATE_SUB(endTime, INTERVAL 1 DAY));
     END WHILE;

  when 1 then #按 单天 查询
     set @rpDate=(SELECT DATE_FORMAT (endTime ,'%Y.%m.%d'));
     INSERT INTO tmp_date(queryDate,ReportDate) VALUES( endTime, @rpDate );

  when 2 then  #按每周 7 日查询
     set @var=1;
     set endTime=(SELECT DATE_FORMAT (endTime ,'%Y-%m-%d')); #调整时间为每天结束 23:59:59
     set endTime=CONCAT(endTime,' 23:59:59');
     WHILE @var<7 DO
        set @rpDate=(SELECT DATE_FORMAT (endTime ,'%Y.%m.%d'));
        INSERT INTO tmp_date(queryDate,ReportDate) VALUES( endTime,@rpDate );
        #时间间隔控制
        set @var=@var+1;
        set endTime=(SELECT DATE_SUB(endTime, INTERVAL 1 DAY));
     END WHILE;
  when 3 then  #按每月 4~5 自然周查询 
     
     WHILE endTime>startTime DO 
        #拼接起止时间作为 报表时间字段  2014.12.08~2014.12.14 形式
        set @sDate=(SELECT DATE_FORMAT( (SELECT DATE_ADD(endTime,INTERVAL -WEEKDAY(endTime) day)),'%Y.%m.%d') );
        set @eDate=(SELECT DATE_FORMAT(endTime,'%Y.%m.%d') );
        set @rpDate=CONCAT(@sDate,'~',@eDate);
        
        INSERT INTO tmp_date(queryDate,ReportDate) VALUES( endTime, @rpDate );
        #时间间隔控制
        set endTime=(SELECT DATE_ADD(endTime,INTERVAL -WEEKDAY(endTime)+6 day));#获得此周结束时间间
        set endTime=(SELECT DATE_SUB(endTime,INTERVAL 1 WEEK));#从结束时间递减 一周(7天)直至 小于 开始时
        SELECT CONCAT(endTime,' 23:59:59');
     END WHILE;
  when 4 then  #按每年 12 个自然月查询
     WHILE endTime>startTime DO
        set @rpDate=(SELECT DATE_FORMAT(endTime,'%Y.%m'));
        INSERT INTO tmp_date(queryDate,ReportDate) VALUES(endTime,@rpDate);
        #时间间隔控制, 取得每个月最后一天日期的结束时间 23:59:59
        set endTime=(SELECT DATE_SUB(endTime,INTERVAL 1 MONTH));
        set endTime=(SELECT LAST_DAY(endTime));#确保是当月最后一天, INTERVAL 扣除天数 30,31 的月份不准 
        set endTime=CONCAT(endTime,' 23:59:59');
     END WHILE;
  ELSE #按自由天数查询
      WHILE endTime>startTime DO
        set @rpDate=(SELECT DATE_FORMAT (endTime ,'%Y.%m.%d'));
        INSERT INTO tmp_date(queryDate,ReportDate) VALUES( endTime, @rpDate );
        set endTime=(SELECT DATE_SUB(endTime, INTERVAL 1 DAY));
     END WHILE;
  END CASE;
  
  #循环取报表时间
  SELECT MIN(tmp_id) INTO v_minId FROM tmp_date; 
  SELECT MAX(tmp_id) INTO v_maxId FROM tmp_date; 
  
  WHILE v_minId <= v_maxId DO  
    set v_querySql='';
    
    SELECT queryDate,ReportDate INTO v_qryDate,v_rpDate from tmp_date where tmp_id=v_minId;

    #店铺id
set whereCOndition=CONCAT(" and st.CompanyId='", compId,"' ");
#商品分类
IF productCategoryId is NOT NULL && productCategoryId <> '' THEN
 set whereCOndition=CONCAT(whereCondition," and pd.CycleCode like %", productCategoryId,"% ");
END IF;
#商品id
IF productId is NOT NULL && productId <> '' THEN
 set whereCOndition=CONCAT(whereCondition," and st.ProductId='", productId,"'");
END IF;
    #时间维度
    SET whereCOndition=CONCAT(whereCondition," and st.BillDate <='",v_qryDate,"'");
    #统计字段
    SET v_queryField=CONCAT("select '",v_rpDate,"' as ReportDate, coalesce(Sum(LastAmount),0) as TotalAmount, coalesce(Sum(LastCount),0) as TotalCount ");
    #查询表与内嵌
    SET v_queryFrom=CONCAT(" from (select * from (select st.LastAmount,st.LastCount,st.ProductId,st.BillDate from kos_stocks_bo st LEFT JOIN kos_product pd on st.ProductId=pd.PD_ID LEFT JOIN kos_product_category pc on pd.ProductCategoryId = pc.PC_ID where 1=1 ",whereCondition," ORDER BY BillDate desc) stock1  Group by ProductId) stock ");
    #单条查询语句
    SET v_querySql=CONCAT(v_queryField,v_queryFrom);
    #合并查询sql,得到一个结果集
    IF v_minId>1 THEN
       set v_querySqlUnion=CONCAT(v_querySqlUnion," union all ",v_querySql);
    ELSE
       set v_querySqlUnion=CONCAT(v_querySql);
    END IF;
    set v_minId= v_minId+1;
  END WHILE;
  
  set @v_sql=v_querySqlUnion;
  prepare stmt from @v_sql;  #预处理需要执行的动态SQL,其中stmt是一个变量
  EXECUTE stmt;      #执行SQL语句
  deallocate prepare stmt;
  
  #删除临时表
  DROP TEMPORARY  TABLE  IF EXISTS tmp_date;
END



此外, thinkphp 3.2 框架,调用存储过程有点问题,不能得到结果。解决方法如下:
http://blog.csdn.net/cyd1919/article/details/8859898 

或者不改框架,在调用存储程时加个空格如: $pInventory="  call p_InventoryProc([parmas])",如下:
http://www.thinkphp.cn/bug/2600.html


推荐阅读
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 本文介绍了如何在MySQL中将零值替换为先前的非零值的方法,包括使用内联查询和更新查询。同时还提供了选择正确值的方法。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文介绍了在MySQL8.0中如何查看性能并解析SQL执行顺序。首先介绍了查询性能工具的开启方法,然后详细解析了SQL执行顺序中的每个步骤,包括from、on、join、where、group by、having、select distinct、union、order by和limit。同时还介绍了虚拟表的概念和生成过程。通过本文的解析,读者可以更好地理解MySQL8.0中的性能查看和SQL执行顺序。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
author-avatar
深圳中诚环球发展有限公司
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有