业务说明:

  主要用于计算采购加权平均价。入参为年份和月份,首先判断输入的年月是否已经结账,如果已经结账就将所有物料和供应商的采购加权平均价返回。

要点说明:

  1.如何在存储过程中定义临时表

  答:oracle正常是不允许直接在存储过程中直接创建临时表的,所以只能使用动态SQL的方式。创建之前,请先确认执行存储过程的用户拥有create any table 的权限。否则会报错。

  2.如何在存储过程定义动态SQL,并且包含转义符

  答:有2种方式:

    1) 可以在SQL中定义参数,然后执行的时候在传进去。例如:

sql := 'select * from tableA where colA = :1 and colB = 1';
execute immediate sql using 'colA_value'

    2) 使用转义符,2个单引号,例如:

execute immediate 'select * from tableA where colA = ''a'' and colB = 1';

  3. 如何将结果集返回出去。

  答:在存储过程定义中声明一个出参out_return out sys_refcursor,然后在最后open out_return for 'select * from base_data';

全部代码:

create or replace PROCEDURE KD_Po_Weight_Avg_Price(
fyear number,
fmonth number,
out_return out sys_refcursor
)
AS
--定义局部变量
month_diff NUMBER(6,2);
input_date date;
current_period date;
input_year_month number(6);
temp_sql varchar2(1000);
insert_sql varchar2(2000);
result_sql varchar2(200);
table_count number(3); --开始业务处理
BEGIN
--入参日期
input_date := to_date(fyear||'-'||fmonth,'yyyy-mm');
--入参日期(数字)
input_year_month := fyear * 100 + fmonth; --查询当前账期和当前时间相差的月份
select TO_DATE(sy.FVALUE || '-' || sp.FVALUE, 'YYYY-MM') into current_period
from T_BD_ACCOUNTBOOK b
inner join T_BAS_SYSTEMPROFILE sy on b.fbookid = sy.FACCOUNTBOOKID and sy.FKEY = 'CurrentYear' and sy.FCATEGORY = 'GL'
inner join T_BAS_SYSTEMPROFILE sp on b.fbookid = sp.FACCOUNTBOOKID and sp.FKEY = 'CurrentPeriod' and sp.FCATEGORY = 'GL'
where b.fnumber = ''; if months_between(input_date,current_period) >= 1 then
--如果差值小于1证明,当前月份已经结账了.再查询当前表里是否已经有数据了,
DBMS_OUTPUT.PUT_LINE('继续处理,要求的日期已结账,当前账期'||current_period);
else
DBMS_OUTPUT.PUT_LINE('当前账期还未结账');
--如果未结账直接抛异常,程序终止
RAISE_APPLICATION_ERROR(-20001, '当前账期还未结账.请结账后再试');
end if; select count(1) into table_count from user_tables t where upper(t.TABLE_NAME) = upper('base_data');
if table_count >= 1 then
execute immediate 'drop table base_data';
end if; temp_sql := 'create global temporary table base_data(
year_month number(6),
FYear number(4),
FMonth number(4),
KdYear number(4),
FQuarter number(1),
item_number varchar2(50),
supplier_number varchar2(50),
FAmount number(28,10),
FQty number(28,10)
) ON COMMIT PRESERVE ROWS';
execute immediate temp_sql; insert_sql := 'insert into base_data
select t.* from (
select extract(year from i.fdate)*100+extract(month from i.fdate) as year_month,
extract(year from i.fdate) as year, extract(month from i.fdate) as month,
decode(sign(extract(month from i.fdate) - 3), -1, extract(year from i.fdate) - 1, extract(year from i.fdate)) as kdyear,
case when (extract(month from i.fdate) in (1,2,3)) then 4
when (extract(month from i.fdate) in (4,5,6)) then 1
when (extract(month from i.fdate) in (7,8,9)) then 2
when (extract(month from i.fdate) in (10,11,12)) then 3
end as kdquarter,
m.fnumber as itemNumber, s.fnumber as supplierNumber,
nvl(if.FALLAMOUNT,0) as famount,nvl(ie.FREALQTY,0) as fqty
from T_STK_INSTOCK i
inner join T_BAS_BILLTYPE b on i.fbilltypeid = b.fbilltypeid and b.fnumber = ''RKD01_SYS''
inner join T_STK_INSTOCKEntry ie on i.fid = ie.fid
left join T_STK_INSTOCKENTRY_F if on IE.FENTRYID = if.FENTRYID
left join T_BD_SUPPLIER s on i.fsupplierid = s.fsupplierid
inner join T_BD_SUPPLIER_L sl on s.fsupplierid = sl.fsupplierid
left join T_BD_MATERIAL m on ie.FMATERIALID = m.FMATERIALID
inner join T_BD_MATERIAL_L ml on m.FMATERIALID = ml.FMATERIALID
where I.FCANCELSTATUS = ''A''
) t where t.year_month <= :1 ';
execute immediate insert_sql using input_year_month; open out_return for 'select * from base_data';
/*
exception
when too_many_rows then
DBMS_OUTPUT.PUT_LINE('返回值多于1行');
when others then
DBMS_OUTPUT.PUT_LINE('未知异常!');
*/
--结束业务处理
END KD_Po_Weight_Avg_Price;

Oracle 存储过程笔记.的更多相关文章

  1. ORACLE存储过程笔记3

    ORACLE存储过程笔记3 流程控制 1.条件   if expression thenpl/sql or sqlend if;   if expression thenpl/sql or sqlel ...

  2. ORACLE存储过程笔记2

    ORACLE存储过程笔记2 运算符和表达式     关系运算 =等于<>,!=不等于<小于>大于<=小于等于>=大于等于       一般运算   +加-减*乘/除 ...

  3. ORACLE存储过程笔记1

    ORACLE存储过程笔记1 一.基本语法(以及与informix的比较)   create [or replace] procedure procedure_name (varible {IN|OUT ...

  4. 转:ORACLE存储过程笔记1----基本语法(以及与informix的比较)

    一.基本语法(以及与informix的比较)   create [or replace] procedure procedure_name (varible {IN|OUT|IN OUT} type) ...

  5. 转: ORACLE存储过程笔记3----流程控制

    流程控制 1.条件   if expression thenpl/sql or sqlend if;   if expression thenpl/sql or sqlelsif expression ...

  6. 转: ORACLE存储过程笔记2----运算符和表达式

    运算符和表达式     关系运算 =等于<>,!=不等于<小于>大于<=小于等于>=大于等于       一般运算   +加-减*乘/除:=赋值号=>关系号. ...

  7. Oracle 存储过程学习笔记

    1.存储过程简单实例 CREATE OR REPLACE PROCEDURE 存储过程名称 (参数in,参数out) AS -- 变量声明,每个声明用分号结束.可以在声明的同时初始化 name ); ...

  8. Oracle学习笔记三 SQL命令

    SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)  

  9. Oracle存储过程学习备忘

    之前的项目使用存储过程很少,但在实际的项目中,存储过程的使用是必不可少的. 存储过程是一组为了完成特定功能的SQL 语句 集,经编译后存储在数据库中:存储过程创建后,一次编译在程序中可以多次调用,对安 ...

随机推荐

  1. 关于eclipse创建web工程没有生成webapp文件夹的解决方案

    先看工程建立的是不是配置的打成War包,然后按下图所示

  2. (整理)REHL6.5_Yum安装Reids

    1.yum添加epel源 yum install epel-release 默认安装,遇到“确定吗?”输入Y 2.yum安装Redis yum install redis  默认安装,遇到“确定吗?” ...

  3. php sleep函数延迟执行

    PHP sleep函数一般用于定时执行任务中,表示延迟多少秒在执行程序.这里主机吧主要给大家讲一下sleep函数的语法和应用实例. sleep函数语法: sleep(seconds); //secon ...

  4. DataStrom框架深造

    根据前一版DataStrom的使用,继续进行了改造和升级;前一版框架只是对服务按照名称注册和调用固化接口 最近研究后台框架,接触了ZBUS框架,我很喜欢ZBUS的前一版,该作者继续升级,已经在向AMQ ...

  5. 微信公众号openid处理的一些笔记

    每个用户对每个公众号的OpenID是唯一的.对于不同公众号,同一用户的openid不同.如果公司有多个公众号,可以通过开放平台关联,这样同一用户,对同一个微信开放平台下的不同应用,unionid是相同 ...

  6. matlab-画个拱桥和倒影?

    matlab可用于各行各业的应用中,现在我们就简单画一个拱桥试一试. r=input('请输入半径: '); z=input('请输入弧度: '); figure() %r=4; %画拱洞,用李萨如图 ...

  7. Tomcat版本对照表

    导入程序前环境要先配好,环境要想配的正确,版本信息一定要了解. Tomcat版本   6.0 7.0 8.0 8.5 9.0 JDK ≥5.0   ≥6.0       ≥7.0     ≥7.0   ...

  8. mysql登录1045错误时 修改登录密码

    1.进入 mysql 的 bin 目录下,打开 cmd ,关闭 mysql 数据库. 2.输入 mysqld --skip-grant-tables 回车. 保持窗口不要更改不要关闭 (--skip- ...

  9. python3 十六进制字符串进行分割并累加

    最近忘性大,记录一下 需求: ‘80 11 F1 01 1A’字符串需要把每一个十六进制字符加起来,即80+11+F1+01+1A=? 很简单,不解释,直接上 hex(sum([int(i,16) f ...

  10. GDI+ 或 GdiPlus 在VC6下的使用方法

    1.在你的app类头文件中假如以下代码(红字显示) #if !defined(AFX_WALKLTDEMO_H__826A807C_C01D_4FF0_9248_A6BD0369F3A8__INCLU ...