oracle存储过程如何取动态字段内容(临时表)并汇总合并输出数据集??

bswendy 2010-11-30 04:12:04
表名:T_cmsScheme
方案编号 方案名称 单位编码 单位名称 历史记录表
Fnumber Fname ForgNumber ForgName FHisTableName
A001 方案1 01.01.02 一分公司_本部_人事部 T_DB_4500
A002 方案2 01.01.02 一分公司_本部_人事部 T_DB_8872
A003 方案3 01.01 一分公司_本部 T_DB_9983

临时表名:T_DB_4501
期间编号 期间名称 应发工资 实发工资
FPeriodNum FPeriodName FYF001 FSF002
201001 201001 1000 1200
201001 201001 1400 1500
201002 201002 2000 2100
201002 201002 3000 3100

临时表名:T_DB_8872
期间编号 期间名称 应发工资 实发工资
FPeriodNum FPeriodName FYF001 FSF002
201002 201002 4000 3000
201002 201002 2800 2500
201003 201003 1000 1200
201004 201004 1200 1300
201005 201005 2000 2200


临时表名:T_DB_9983
期间编号 期间名称 应发工资 实发工资
FPeriodNum FPeriodName FYF001 FSF002
201002 201002 3000 2000
201002 201002 2300 2500


--存储过程输出结果集
--条件:汇总单位编码为01.01.02且薪资期间编号在201001~201002范围内的应发工资及实发工资合计
方案编号 方案名称 单位编码 单位名称 应发工资 实发工资
Fnumber Fname ForgNumber ForgName FYF001 FSF002
A001 方案1 01.01.02 一分公司_本部_人事部 7400 7900
A002 方案2 01.01.02 一分公司_本部_人事部 6800 5500



以上是该存储过程需要涉及到的表结构、测试数据及输出的结果集,要求输入参数为ForgNum和FPrdNumFrom、FPrdNumTo,先根据ForgNum筛选出主表"T_cmsSceme"的方案,再找出这些方案的FHisTableName,根据字段值显示的临时表名去其期间编码在[FPrdNumFrom,FPrdNumTo]范围内的实发工资及应发工资合计值,与方案一起输出一个结果集。
临时表T_DB_4500、T_DB_8872、T_DB_9983 是主表T_cmsScheme的FHisTableName值,再根据这些临时表去汇总对应字段的汇总值,合并到主表中输出。

请各位高手各显神通,帮忙将存储过程写出来,非常感谢了!


...全文
634 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
bswendy 2010-12-08
  • 打赏
  • 举报
回复
谢谢各位,我要结贴了,问题都已经解决!
分给wkc168和gelyon ,两位给我的帮助最大,谢谢!
心中的彩虹 2010-12-01
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 wkc168 的回复:]
SQL code

---过程




----建立临时表
create global temporary table tmp2(fnumber varchar2(5),fname varchar2(10),forgnumber varchar2(10),
forgname varchar2(50),fhistablename varchar2(10),FYFsum1 numbe……
[/Quote]




---推荐使用过程,关键是采用了临时表
--函数

create or replace function fun_sum(v_tb T_cmsScheme.Fhistablename%type,fnofrom number,fnoto number) return varchar2
as
num varchar2(100);
str varchar2(1000);
begin
str:='select sum(FYF001)'||'||'',''||'||'sum(FYF002) from '||v_tb||' where FPeriodName between '||fnofrom||' and '||fnoto;
execute immediate str into num;
return num;
end;


SQL> col FORGNAME format a30
SQL> col f_sum1 format a10
SQL> col f_sum2 format a10
SQL>
SQL> select fnumber,fname,forgnumber,forgname,fhistablename,
2 substr(fun_sum(Fhistablename,201001,201002),1,instr(fun_sum(Fhistablename,201001,201002),',',1)-1) f_sum1,
3 substr(fun_sum(Fhistablename,201001,201002),instr(fun_sum(Fhistablename,201001,201002),',',1)+1) f_sum2
4 from T_cmsScheme
5 where forgnumber='01.01.02'
6 /

FNUMBER FNAME FORGNUMBER FORGNAME FHISTABLENAME F_SUM1 F_SUM2
------- ---------- ---------- ------------------------------ ------------- ---------- ----------
A001 方案1 01.01.02 一分公司_本部_人事部 T_DB_4500 7400 7900
A002 方案2 01.01.02 一分公司_本部_人事部 T_DB_8872 6800 5500











心中的彩虹 2010-12-01
  • 打赏
  • 举报
回复

---过程




----建立临时表
create global temporary table tmp2(fnumber varchar2(5),fname varchar2(10),forgnumber varchar2(10),
forgname varchar2(50),fhistablename varchar2(10),FYFsum1 number,FYFsum2 number) on commit preserve rows;


--过程
create or replace procedure p_result(ForgN varchar2,FPrdNumFrom number,FPrdNumTo number,cur out sys_refcursor)
as
str varchar2(1000);
num number;
begin
for i in(select fhistablename from T_cmsScheme where forgnumber=ForgN) loop
str:='select fnumber,fname,forgnumber,forgname,fhistablename,'||'(select sum(FYF001) FYF001 from '||i.fhistablename||' where FPeriodNum between '||FPrdNumFrom||' and
'||FPrdNumTo||'),(select sum(FYF002) FYF002 from '||i.fhistablename||' where FPeriodNum between '||FPrdNumFrom||' and '||FPrdNumTo||')'||' from T_cmsScheme where
fhistablename='''||i.fhistablename||'''';
dbms_output.put_line(str);
execute immediate 'insert into tmp2 '||str;
commit;
end loop;
open cur for 'select * from tmp2';
end;
SQL> /

过程已创建。

SQL> var cur refcursor
SQL> exec p_result('01.01.02',201001,201002,:cur)

PL/SQL 过程已成功完成。

SQL> print cur

FNUMB FNAME FORGNUMBER FORGNAME FHISTABLEN FYFSUM1 FYFSUM2
----- ---------- ---------- -------------------------------------------------- ---------- ----------
A001 方案1 01.01.02 一分公司_本部_人事部 T_DB_4500 7400 7900
A002 方案2 01.01.02 一分公司_本部_人事部 T_DB_8872 6800 5500





心中的彩虹 2010-12-01
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 bswendy 的回复:]
谢谢楼上高手,但
v_sql := 'select a.Fnumber,a.Fname,a.ForgNumber,a.ForgName,sum(b.FYF001) FYF001,sum(FSF002) FSF002 from T_cmsScheme a,' ||
v_FHisTableName || ' b where b.FPeriodNum=' || FPeriodNum ||
……
[/Quote]

这种事情只能这样做
bswendy 2010-11-30
  • 打赏
  • 举报
回复
谢谢楼上高手,但
v_sql := 'select a.Fnumber,a.Fname,a.ForgNumber,a.ForgName,sum(b.FYF001) FYF001,sum(FSF002) FSF002 from T_cmsScheme a,' ||
v_FHisTableName || ' b where b.FPeriodNum=' || FPeriodNum ||
'and a.ForgNumber=' || ForgNum ||
' group by a.ForgNumber,a.Fnumber';

是不是调整这条语句呢?怎么感觉有点不对呢?
心中的彩虹 2010-11-30
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 wkc168 的回复:]
引用 1 楼 wkc168 的回复:
引用楼主 bswendy 的回复:
表名:T_cmsScheme
方案编号 方案名称 单位编码 单位名称 历史记录表
Fnumber Fname ForgNumber ForgName FHisTableName
A001 方案1 01.01.02 一分公司_本部_人事部 T_DB_4500
A002 方案2 01.01.02 一分公司_本部_人事……
[/Quote]

create or replace procedure p_result(ForgN varchar2,FPrdNumFrom number,FPrdNumTo number,cur out sys_refcursor)
as
str varchar2(1000);
begin
str:='select Fnumber,Fname,ForgNumber,ForgName,'||'(select sum(FYF001) FYF001,sum(FYF002) FYF002 sum from '||'FHisTableName
where FPeriodNum between '||FPrdNumFrom||' and '||FPrdNumTo||')'||
' from T_cmsScheme where ForgNumber='''||ForgN||'''';
open cur for str;
end;






gelyon 2010-11-30
  • 打赏
  • 举报
回复


--你这个可以不用那么复杂,只需要创建两个函数来分别获取合计的应发金额和合计的实发金额就可以了
--下面是我的测试过程,请参考:
--1、创建函数get_sum_FYF001 获取合计的应发金额
CREATE OR REPLACE FUNCTION get_sum_FYF001(table_name IN VARCHAR2,FPeriodNum1 IN VARCHAR2 ,FPeriodNum2 IN VARCHAR2 )
RETURN NUMBER
IS
result NUMBER;
sql_str VARCHAR2(2000);
BEGIN
sql_str:='SELECT Sum(FYF001) FROM '||table_name||' where FPeriodNum between '||FPeriodNum1||' and '||FPeriodNum2;
EXECUTE IMMEDIATE sql_str INTO result;
RETURN result;
END;

--2、创建函数get_sum_FSF002获取合计的实发金额
CREATE OR REPLACE FUNCTION get_sum_FSF002(table_name IN VARCHAR2,FPeriodNum1 IN VARCHAR2 ,FPeriodNum2 IN VARCHAR2 )
RETURN NUMBER
IS
result NUMBER;
sql_str VARCHAR2(2000);
BEGIN
sql_str:='SELECT Sum(FSF002) FROM '||table_name||' where FPeriodNum between '||FPeriodNum1||' and '||FPeriodNum2;
EXECUTE IMMEDIATE sql_str INTO result;
RETURN result;
END;

--测试:
SELECT FNUMBER,FNAME,FORGNUMBER,FORGNAME,
get_sum_FYF001(FHISTABLENAME,'201001','201002') FYF001,
get_sum_FSF002(FHISTABLENAME,'201001','201002') FSF002
FROM T_cmsScheme
WHERE FORGNUMBER='01.01.02';

--结果:
FNUMBER FNAME FORGNUMBER FORGNAME FYF001 FSF002
-------------------------------------------------------------------------------
A001 方案1 01.01.02 一分公司_本部_人事部 7400 7900
A002 方案2 01.01.02 一分公司_本部_人事部 6800 5500
YY_MM_DD 2010-11-30
  • 打赏
  • 举报
回复

-----你编译下试下看呢..可能要调整下那条语句。
create or replace procedure helpBswendy(ForgNum number,
FPeriodNum number,
resultSet out sys_refcursor o_ret number,
o_msg varchar2) as
v_FHisTableName varchar2(200);
v_sql varchar2(2000);
begin
select FHisTableName
into v_FHisTableName
from T_cmsScheme
where ForgNumber := ForgNum;
v_sql := 'select a.Fnumber,a.Fname,a.ForgNumber,a.ForgName,sum(b.FYF001) FYF001,sum(FSF002) FSF002 from T_cmsScheme a,' ||
v_FHisTableName || ' b where b.FPeriodNum=' || FPeriodNum ||
'and a.ForgNumber=' || ForgNum ||
' group by a.ForgNumber,a.Fnumber';
open for resultSet;
exception
when others then
o_ret := sqlcode;
o_msg := sqlerrm(sqlcode);
end;
bswendy 2010-11-30
  • 打赏
  • 举报
回复
谢谢楼上高手,我没有发图权限,也不能贴表格,所以只能一字一字的排,抱歉哩
心中的彩虹 2010-11-30
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wkc168 的回复:]
引用楼主 bswendy 的回复:
表名:T_cmsScheme
方案编号 方案名称 单位编码 单位名称 历史记录表
Fnumber Fname ForgNumber ForgName FHisTableName
A001 方案1 01.01.02 一分公司_本部_人事部 T_DB_4500
A002 方案2 01.01.02 一分公司_本部_人事部 T_DB_8872
A003 方案……
[/Quote]】
等下
心中的彩虹 2010-11-30
  • 打赏
  • 举报
回复
[Quote=引用楼主 bswendy 的回复:]
表名:T_cmsScheme
方案编号 方案名称 单位编码 单位名称 历史记录表
Fnumber Fname ForgNumber ForgName FHisTableName
A001 方案1 01.01.02 一分公司_本部_人事部 T_DB_4500
A002 方案2 01.01.02 一分公司_本部_人事部 T_DB_8872
A003 方案3 01.01 一分公司_本部 T_……
[/Quote]
说实话这样的帖子的内容 看的真费劲

17,086

社区成员

发帖
与我相关
我的任务
社区描述
Oracle开发相关技术讨论
社区管理员
  • 开发
  • Lucifer三思而后行
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧