数据库简单定时器、触发器、存储过程的实现

前言:某高校预统计大量数据,导出一批人的项目、论文、奖励、著作、专利数据(有时间节点),这涉及十一张表的数据:首先是科研人员表,其次是项目信息表、项目成员表等(类推:论文表、论文成员表)。科研人员表与成员表之间关联键为ryid。项目与项目成员表之间关联键为项目id,项目一对多项目成员,类推。

一、注意事项:

1、数据库为学校本地库,不可以随意修改数据;

2、关联十一张表的数据进行查询会导致数据量过大,论文、项目和专利的数据一般都过万了(想一下笛卡尔)。

二、预想:

1、建表:

a)根据提供的职工号,建立一张临时职工信息表export_msg_zgh,导入职工号;

b)设计一张临时表export_result_by_ryid,存储要导出的数据,字段为:人员信息,项目id,项目名称,项目时间,论文id,论文名称,论文时间,奖励id,奖励名称,奖励时间,著作id,著作名称,著作时间,专利id,专利名称,专利时间;(id后面处理数据会用到)。

2、思路:

科研人员表中含有ryid和职工号数据,通过职工号查询科研人员表来更新export_msg_zgh中的ryid,同时触发五种类型的数据的插入,每种类型的数据独占一行,其他数据为空,再通过定时器调用存储过程来对存储好的数据进行处理(主要是将数据尽可能放在一行,也就是数据的上下挪动)。

三、数据处理:

1、创建表

a)export_msg_zgh CREATE TABLE export_msg_zgh (zgh varchar2(32),ryid varchar2(32)); b)export_result_by_ryid CREATE TABLE export_result_by_ryid ( xm varchar2(32), zgh varchar2(32), xmid varchar2(64),xmmc varchar2(256), xmsj date, lwid varchar2(64),lwmc varchar2(256),lwsj varchar2(32), jlid varchar2(64),jlmc varchar2(256), jlsj date, zzid varchar2(64),zzmc varchar2(256), zzsj date, zlid varchar2(64),zlmc varchar2(256), zlsj date, numb integer);

2、创建触发器(写了五个,不一一赘述)

CREATE OR REPLACE TRIGGER export_msg_zgh_tig1AFTER updateON export_msg_zghFOR EACH ROWBEGIN insert into export_result_by_ryid (select kyry.zsxm,:NEW.ryid, xmjbxx.xmid,xmjbxx.xmmc,xmjbxx.xmzqs, ‘’,’’,’’,’’,’’,’’,’’,’’,’’,’’,’’,’’, (rownum+50000+to_number(:OLD.zgh )) from srm_xmcy xmcy left outer join srm_kyry kyry on kyry.ryid=:NEW.ryid left outer join srm_xmjbxx xmjbxx on xmcy.xmid = xmjbxx.xmid and xmjbxx.xmzqs >= to_date(‘2013-1-1’ ,‘YYYY-MM-DD’) and xmjbxx.xmzqs < to_date(‘2018-1-1’ ,‘YYYY-MM-DD’) where xmcy.ryid = :NEW.ryid ); END;

说明:

rownum是用于定位的,便于操作插入表中的数据;:NEW.ryid是插入export_msg_zgh的新的ryid的值;

只要更新了export_msg_zgh中的数据就会触发改触发器,进行数据统计并将数据插入到export_result_by_ryid 表中;

(rownum+50000+to_number(:OLD.zgh ))中的50000是为了区分下标(实测五种类型数据最大的数据量为论文:四万条记录),以致于在下面存储过程中取到的numb不会重复。

3、创建存储过程

CREATE OR REPLACE PROCEDURE pro_export_result_by_ryid ASCURSOR start_exp is select max(numb) maxb,min(numb) minb,zgh from export_result_by_ryid group by zgh;BEGIN FOR stu IN start_exp LOOP DECLARE x number; BEGIN x := stu.minb; WHILE x < stu.maxb LOOP x := x + 1; ------项目 update export_result_by_ryid set xmmc=( select xmmc from export_result_by_ryid where numb= ( select min(numb) from export_result_by_ryid where zgh=stu.zgh and xmid is not null and numb> ( select min(numb) from export_result_by_ryid where zgh=stu.zgh and xmid is null ) ) ), xmsj=( select xmsj from export_result_by_ryid where numb= ( select min(numb) from export_result_by_ryid where zgh=stu.zgh and xmid is not null and numb> ( select min(numb) from export_result_by_ryid where zgh=stu.zgh and xmid is null ) ) ), xmid=( select xmid from export_result_by_ryid where numb= ( --不为空最小numb select min(numb) from export_result_by_ryid where zgh=stu.zgh and xmid is not null and numb> ( select min(numb) from export_result_by_ryid where zgh=stu.zgh and xmid is null ) ) ) where zgh=stu.zgh and numb =( select min(numb) from export_result_by_ryid where zgh=stu.zgh and xmid is null --为空最小numb ); update export_result_by_ryid set xmmc=’’,xmsj=’’,xmid=’’ where zgh=stu.zgh and numb not in ( select min(numb) from export_result_by_ryid where zgh=stu.zgh and xmid is not null group by xmid ) and xmid is not null; ------论文 ------奖励 ------著作 ------专利 END LOOP; END; --清理无效数据 delete export_result_by_ryid where (xmid is null or xmid=’’) and(lwid is null or lwid=’’ ) and(jlid is null or jlid=’’) and(zzid is null or zzid=’’) and(zlid is null or zlid=’’); END LOOP;COMMIT;END;

说明:存储过程主要是将数据尽可能放在一行,也就是数据的上下挪动:项目部分–查询export_result_by_ryid 表中每个人的项目对应的最大的numb–maxb、最小的numb–minb以及职工号,然后做循环操作,循环从minb到maxb,每次将最小的有数据的项目信息挪到最小的无项目信息的位置,每次移动数据之后清理数据(如上:“清理无效数据”)。

4.创建定时器

5、触发数据存储

update export_msg_zgh set ryid=(select kyry.ryid from srm_kyry kyry where kyry.ygh=zgh) ;

6、数据处理

a)查询导出

select expMsg.xm as “姓名”,expMsg.zgh as “人员id”,expZgh.ygh as “职工号”, expMsg.xmid as “项目id”, nvl(expMsg.xmmc,expMsg.numb) as “项目名称” , expMsg.xmsj as “项目周期始” , expMsg.lwid as “论文id”, nvl(expMsg.lwmc,expMsg.numb) as “论文名称” , expMsg.lwsj as “论文年号” , expMsg.jlid as “奖励id”, nvl(expMsg.jlmc,expMsg.numb) as “获奖成果名称” , expMsg.jlsj as “获奖日期” , expMsg.zzid as “著作id”, nvl(expMsg.zzmc,expMsg.numb) as “著作名称” , expMsg.zzsj as “出版日期” , expMsg.zlid as “专利id”, nvl(expMsg.zlmc,expMsg.numb) as “知识产权名称” , expMsg.zlsj as “申请日期” from export_result_by_ryid expMsgleft outer join srm_kyry expZgh on expMsg.zgh=expZgh.ryid order by expMsg.zgh;

说明:

a.1没有项目名称的行以numb来替代项目名称,是为了方便之后在excel中清理同一个人重复的项目信息;

a.2查询项目id是用来在去重复(a.1)之后,清理以numb来替代项目名称的数据;

a.3论文、著作…类推a.1、a.2。

b)查询到的数据在plsql中全部查询出来select * from export_result_by_ryid order by zgh;,右键查询的数据,选择“复制到Excel…”

c)利用excel处理数据:

第一步:删除重复项

选择人员id、项目名称、项目周期开始来清除重复的项目信息(类推清除其他重复数据)

第二步:清除冗余数据

以项目id排序,清除掉以numb来替代项目名称的数据

四、结语

才疏学浅,只能这么傻瓜式的导数据了;excel用得也是烂,尝试用公式去处理过数据,貌似在本表不行,

不知道是不是有什么限制。

沈阳男科哪里好 http://mobile.shenda120.com/

沈阳最好的男科医院 http://mobile.ytsg120.com/

猜你喜欢

转载自blog.csdn.net/qq_43303236/article/details/82910673