微信公众号制作开发 微信小程序定制开发 网站建设制作 手机app软件开发

您的位置:首页 > 技术观点 > 信息详情

phpMyAdmin调用和生成MySQL的存储过程以及CURSOR的应用

来源:山东鸿软信息科技有限公司  阅读量:  时间:2017-07-21 03:07
首先叙述一下我碰到的问题,如果这个讲不清楚,则有可能压根不知道这究竟有什么用,有些事情总是在碰到困难需要解决非用不可的时候印象才会更深刻。

首先叙述一下我碰到的问题,如果这个讲不清楚,则有可能压根不知道这究竟有什么用,有些事情总是在碰到困难需要解决非用不可的时候印象才会更深刻。

 

这是一个转换工程,需要把dvbbs的access数据库转换成phpwind的MySQL形式。

 

phpwind论坛数据库,

表`pws_threads`存放主题(包括标题)

表`pws_posts` 存放着所有除了一楼之外的帖子,

表`pws_tmsgs`存放着主题第一楼的数据。

 

dvbbs的做法是将主题和回帖分开,主题用一个表存储,而所有回帖(包括第一楼)都存在另一个表里,楼层按顺序排列,标记为0的显然就是1楼,然后以此类推,它没有再单独开一个表存放所谓1楼数据。

 

这倒不麻烦,只需要将原表中相同主题ID并且回帖ID最小的抽出来,然后放到phpwind的pws_tmsgs里就行了,然后排除这些1楼的回帖,将余下的全部帖子都放进phpwind的`pws_posts`即可。

 

问题在,由于操作不当。在原数据库还没有排除所谓“1楼”帖子的情况下,又将他们导入了pws_posts,即在`pws_tmsgs里有一个“1楼”在,pws_posts里又出现了一个一模一样的“1楼”,最后每个主题都存在两个一模一样的“1楼”(第二楼内容和第一楼完全一样),这让人抓狂!

 

因为数据量较大,很不情愿再推倒重来一次,那么现在这个局面该怎么办?

1. 总的来说,删除现阶段的第二楼即可达到目的。

2. 如何找到第二楼的回帖序号?

3. 在一个主题序号(tid)下,有很多跟帖,这些跟帖以(pid)形式出现,则查出某tid下最小的pid,则是最老的回帖(即1楼),删除之即可。

4. 单纯用SQL语句已经做不到这一点了,因为tid返回的值是一个记录集,而我们必须再从这个记录集里寻找pid最小值并删除之,也许有SQL高人能靠纯查询做到,但实话说,我不行。

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

重点(全部亲测通过):

1. phpMyadmin中可以创建并执行存储过程。

2. mysql支持CURSOR(即游标)

3. MySQL不支持SELECT * INTO XXX这样的表复制,而需要

CREATE TABLE aaaa(id int) SELECT yyy FROM ttt

这样的变通方法完成。

 

方法:

1. 创建一个表aaaa,获取所有pid(主题号):

CREATE TABLE aaaa(tid int) SELECT tid FROM `pws_posts` group by tid order by tid

2. 创建一个存储过程,

DELIMITER $$   

     DROP PROCEDURE IF EXISTS TEST1$$   

     CREATE PROCEDURE TEST1()   

     BEGIN   

      DECLARE tidv INT;

      DECLARE pidv INT;

      DECLARE fig INT;

      DEClARE cur CURSOR FOR Select tid From `aaaa`;

      DECLARE CONTINUE HANDLER FOR NOT FOUND SET fig=1;

      OPEN cur;

      REPEAT

         FETCH cur INTO tidv;

         INSERT INTO bbbb(tids) select min(pid) from `pws_posts` where `tid` = tidv;

         UNTIL fig=1

      END REPEAT;

      CLOSE cur;

     END$$   

DELIMITER;  

Call TEST1;

解释:临时建立了一个aaaa,表中存放`pws_posts`相同主题号(tid)中最小的回帖号(pid)

 

然后我们还得删除这些数据:

DELIMITER $$    

DROP PROCEDURE IF EXISTS test2$$   

CREATE PROCEDURE test2()   

BEGIN   

DECLARE pidv INT;

DECLARE fig INT;

DEClARE cur CURSOR FOR Select tids From `bbbb`;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET fig=1;

OPEN cur;

REPEAT

FETCH cur INTO pidv;

DELETE FROM `pws_posts` WHERE `pid` = pidv;

UNTIL fig=1

END REPEAT;

CLOSE cur; 

END$$   

DELIMITER ;  

Call test2;

 

至此我的事情到底结束。

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

无废话版

1. 打开phpMyadmin,点SQL,输入代码,即可创建并运行存储过程

2. 给出一个最简单的游标使用,你就照着我这个粘贴进去,然后稍作修改即能为之己用:

DELIMITER

DROPPROCEDUREIFEXISTSTEST

   

CREATE PROCEDURE TEST()   

BEGIN   

DECLARE id INT;

DECLARE fig INT;

DEClARE cur CURSOR FOR Select 字段 From `表`;----> 此处支持所有合乎Select规则的查询以创建记录集

DECLARE CONTINUE HANDLER FOR NOT FOUND SET fig=1;

OPEN cur; --------->打开游标

REPEAT ->>开始循环

FETCH cur INTO id; ---->若是首次进入,则相当于将第一行数据的第一个字段内容存入了变量id,假设你有多个字段,可用逗号隔开,比如id,name,age之类。



(此处可以填写所有合法的SQL语句,此处直接使用变量id,则相当于引用了表中的数据)

 

UNTIL fig=1 ---->数据行到尾了吗?如没有则继续下一行。

END REPEAT;

CLOSE cur; 

END$$   

DELIMITER ;  

Call test2; --->调用刚才这个存储过程,切记哦,因为存储过程不会自动运行。


本文标签:

成为您更加专业的技术合伙人

网站建设 | APP开发 | 产品服务 | 技术观点 | 关于我们      电话:151-6502-2080  客服QQ:1828087588、1421667633  客服电子邮箱:1828087588@qq.com

Copyright © 2018 山东鸿软信息科技有限公司 版权所有 https://www.greatsoft.cn 鲁ICP备16026454号