设为首页 收藏本站
查看: 765|回复: 0

[经验分享] Oracle 存储过程:游标与动态SQL

[复制链接]

尚未签到

发表于 2016-8-12 06:04:28 | 显示全部楼层 |阅读模式
特此记录下,备以后查阅。
1.创建包+游标
CREATE OR REPLACE PACKAGE RefCursor
IS type t_RefCursor
IS
ref  CURSOR;
END RefCursor;

2.创建存储过程,定义in,out参数。

create or replace
PROCEDURE prc_stock_HistoryDetail(
-- 功能: 查询仓库的进出库记录与每笔结存数量。
--定义参数
p_stockcode IN VARCHAR2, -- 仓库编号
p_stockId   IN VARCHAR2, -- 仓库Id
p_fbegdate  IN VARCHAR2, -- 开始日期
p_fenddate  IN VARCHAR2, -- 截止日期
p_fitemcode IN VARCHAR2, -- 品种
cur_result out sys_refcursor -- 输出游标
)
IS
-- 定义变量
v_stockid   VARCHAR2(32); -- 仓库编号
v_stockName VARCHAR2(32); -- 仓库名称
v_stockCode VARCHAR2(32); -- 仓库名称
v_itemcode  VARCHAR2(32); -- 物资编码
v_instockDate DATE;       -- 出入库日期
v_in_store     NUMBER;        -- 入库数量
v_out_store    NUMBER;        -- 出库数量
v_lost_store   NUMBER;        -- 损耗数量
v_qc_store     NUMBER;        -- 期初数量
v_last_store   NUMBER;        -- 结存数量
v_last_qc_date VARCHAR(32);   -- 最后一次期初日期
-- 临时变量
v_temp_stockid varchar2(32); -- 仓库Id
v_temp_itemcode varchar2(32);-- 物资编码
v_temp_last_store number;    -- 结存

--定义游标
cur_query RefCursor.t_Refcursor;
v_sqlStmt string(10000);
v_sql VARCHAR2(2000);
BEGIN
v_sql :='select t.pk_id from yy_bd_stock t where t.fend =1 order by t.fcode asc';
-- 查询仓库指定日期的 进出库明细记录
v_sqlStmt := '  select tt.fstockid,tt.fcode,tt.fname,tt.fitemcode,tt.finstockdate,sum(tt.in_store) as in_store,sum(tt.out_store) as out_store,sum(tt.lost_store) as lost_store,sum(tt.last_store) as last_store
from (select t.fstockid,a.fcode,a.fname,t.fitemcode,t.finstockdate,decode(t.fiostatus,1,t.fqty,0) as in_store,
decode(t.fiostatus,2,t.fqty,0) as out_store,
decode(t.fiostatus,3,t.fqty,0) as lost_store ,
decode(t.fiostatus,1,t.fqty,0)-decode(t.fiostatus,2,t.fqty,0)-decode(t.fiostatus,3,t.fqty,0)) as last_store
from yy_store_storage t                           
left join yy_bd_stock a on t.fstockid = a.pk_id
where t.fisreset = 0 and t.fitemcode is not null ' ;
-- 仓库编号
if p_stockId is not null then
v_sqlStmt := v_sqlStmt || ' and t.fstockid='''||p_stockId||'''';
end if;
-- 品种
if p_fitemcode is not null then
v_sqlStmt := v_sqlStmt || ' and t.fitemcode='''||p_fitemcode||'''';
end if;  
-- 起始日期
if p_fbegdate is not null then
v_sqlStmt := v_sqlStmt || ' and t.finstockdate >=to_date('''||p_fbegdate||''',''yyyy-MM-dd'')';
end if;
-- 截止日期
if p_fenddate is not null then
v_sqlStmt := v_sqlStmt || ' and t.finstockdate < to_date('''||p_fenddate||''',''yyyy-MM-dd'')';
end if;
v_sqlStmt := v_sqlStmt || ' order by a.fcode asc,t.fitemcode, t.finstockdate asc  
) tt
group by tt.fstockid,tt.fcode,tt.fname,tt.fitemcode,tt.finstockdate
order by tt.fcode asc,tt.fitemcode, tt.finstockdate asc  ';
dbms_output.put_line('=====sqlStmt:'||v_sqlStmt);
-- 打开游标 遍历仓库表。
OPEN cur_query FOR v_sqlStmt;
-- 初始化临时变量
v_temp_stockId := '';
v_temp_itemcode := '';
v_temp_last_store := 0;
LOOP
-- 查询库存表中的进出库记录。获取每笔记录的 进库数量、出库数量、损耗数量、结存数量。然后存入临时表中。
FETCH cur_query
INTO v_stockid,v_stockCode, v_stockName, v_itemcode, v_instockDate, v_in_store, v_out_store, v_lost_store,v_last_store;
dbms_output.put_line('v_stockid:'||v_stockName||',fitemcode:'||v_itemcode||',instockdate:'||v_instockDate);
EXIT WHEN cur_query%notfound;
if (v_stockid is not null ) and  (v_itemcode is not null) then     
-- 遍历记录,如果不是同一仓库与品种.则从新获取对应仓库品种中的期初库存或上日结存数量
if (v_temp_stockid is null or v_temp_stockid!= v_stockid) and (v_temp_itemcode is null or  v_temp_itemcode!= v_itemcode) then
v_temp_stockid := v_stockid;
v_temp_itemcode := v_itemcode;
v_temp_last_store := 0;
-- 调用存储过程,获取结存数量
prc_stock_historystore(v_temp_stockid,p_fbegdate,v_temp_itemcode,v_qc_store);
dbms_output.put_line('期初数量:'||v_qc_store);
v_temp_last_store := nvl(v_qc_store,0)+ nvl(v_last_store,0);
else
v_temp_last_store := v_temp_last_store + nvl(v_last_store,0);
end if;      
-- 通过结存数量,计算每笔的期初数量 -- 结存=期初+入库-出库-损耗      
insert into yy_temp_store_detail (fstockid, fstockcode, finstorkdate, fitemcode, in_store, out_store, lost_store, last_store)
values (v_stockid, '', v_instockDate, v_itemcode, v_in_store, v_out_store, v_lost_store, v_temp_last_store);
end if;   
--dbms_output.put_line('name:'||v_stockName||',itemcode:'||v_itemcode||',date:'||v_instockDate||',in_store:'||v_in_store||',out_store:'||v_out_store);
END LOOP;
CLOSE cur_query;
-- 返回集合
open cur_result for select a.fname,t.finstorkdate,t.fitemcode,t.in_store,t.out_store,t.lost_store,t.last_store
from yy_temp_store_detail t
left join yy_bd_stock a on t.fstockid = a.pk_id
order by a.fcode asc,t.fitemcode, t.finstorkdate asc ;   
END;

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-256331-1-1.html 上篇帖子: 关于oracle的序列调用问题 下篇帖子: ORACLE 数据库释放表空间
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表