Oracle 集合使用

*------IFS系统-
这是用户需要将半成品的需求情况计算出来,根据下达所车间订单状况,取剩余未完成数量,根据制造BOM逐层分解出半成品计算
其中对于半成品的库存使用嵌套表类型,使用字符型索引可以使用物品代码直接查询其中的储存的值
用 .exists() 可以查找是否含有此项的值
select * from table(V_MANUF_STRUCTURE) where STRUCTURE_ID=M_ROW_NO_;
下面是具体的代码部分
其中有遗憾的是还不知道如何对集合批量插入,还有这些类型一定要先创建出来,不可以在包中声明后再用。
 


*/
create or replace --创建对像
type MANUF_STRUCTURE_OBJ AS OBJECT(
STRUCTURE_ID INTEGER, --结构序号
PART_NO VARCHAR2(25 CHAR), --父项,
COMPONENT_PART VARCHAR2(25 CHAR), --子项 ,
QTY_PER_ASSEMBLY number --装配数

);

create or replace
TYPE T_MANUF_STRUCTURE is table of MANUF_STRUCTURE_OBJ ; --存储分解后的BOM集合

CREATE OR REPLACE PACKAGE NS_DAYSTORAGE_PRINT_RECORD AS
TYPE RESULT_CURSOR IS REF CURSOR;

--返回半成品在库
Function Get_Stock(PartNo varchar2) RETURN integer;
--半成品在库推移计算
procedure Semi_DayStorage( R_Key OUT NUMBER);

END NS_DAYSTORAGE_PRINT_RECORD;
/


CREATE OR REPLACE PACKAGE BODY NS_DAYSTORAGE_PRINT_RECORD AS

TYPE Stock IS TABLE OF NUMBER INDEX BY VARCHAR(15);
V_Stock Stock;
V_Stock_ Stock;
TYPE MANUF IS TABLE OF NUMBER INDEX BY VARCHAR(15);
V_Manuf MANUF;
MAX_ROW_NO NUMBER := 0;

--TYPE T_MANUF_STRUCTURE is table of MANUF_STRUCTURE_OBJ ; --存储分解后的BOM集合
V_MANUF_STRUCTURE T_MANUF_STRUCTURE := T_MANUF_STRUCTURE(); --进行初始化


/*--获取成品BOM保存的序列号--*/
Function Get_Manuf(PartNo varchar2) RETURN NUMBER
IS
CURSOR Get_MANUF_STRUCTURE IS
SELECT M.PART_NO, --父项,
M.COMPONENT_PART, --子项 ,
M.QTY_PER_ASSEMBLY --装配数
--M.ENG_CHG_LEVEL --版本号
FROM MANUF_STRUCTURE_TAB M
JOIN INVENTORY_PART_TAB I ON M.COMPONENT_PART = I.PART_NO AND M.CONTRACT = I.CONTRACT
where I.ACCOUNTING_GROUP = 2 --只取半成品
START WITH M.PART_NO = PartNo AND M.CONTRACT= 'DGNS'
CONNECT BY PRIOR M.COMPONENT_PART= M.PART_NO ;
BEGIN
IF Not V_Manuf.exists(PartNo) then
MAX_ROW_NO := MAX_ROW_NO +1;
For C_MS IN Get_MANUF_STRUCTURE Loop
V_MANUF_STRUCTURE.Extend; --将数据插入至数据集中 如何批量插入?
V_MANUF_STRUCTURE(V_MANUF_STRUCTURE.count):=MANUF_STRUCTURE_OBJ(MAX_ROW_NO,C_MS.PART_NO,C_MS.COMPONENT_PART,C_MS.QTY_PER_ASSEMBLY);
END Loop;

V_Manuf(PartNo):=MAX_ROW_NO;
END IF;
RETURN V_Manuf(PartNo);
END Get_Manuf;

/*--获取半成品库存----*/
Function Get_Stock(PartNo varchar2) RETURN integer
IS
QtyOnhand INVENTORY_PART_IN_STOCK.qty_onhand%type;
StockQty integer;
begin
IF Not V_Stock.exists(PartNo) then --查找元素是否存在
select nvl(sum(qty_onhand),0) qty_onhand INTO QTYONHAND
from INVENTORY_PART_IN_STOCK I
where I.PART_NO = PartNo
and NVL(I.AVAILABILITY_CONTROL_ID,'0') <>'NG' and NVL(I.AVAILABILITY_CONTROL_ID,'0') <>'NG1'
and I.CONTRACT = 'DGNS';
V_Stock(PartNo) := QTYONHAND;
V_Stock_(PartNo) := QTYONHAND; --保留库存最初值
END IF;
StockQty :=v_Stock(PartNo);
RETURN StockQty;
end Get_Stock;

/*--设置半成品库存--*/
procedure Set_Stock(PartNo varchar2,StockQty number)
IS
BEGIN
V_Stock(PartNo) := StockQty;
END Set_Stock;


procedure Semi_DayStorage(R_Key OUT NUMBER)
is
RESULT_KEY_ NUMBER;
--M_RESULT_KEY_ NUMBER;
M_Row_no_ integer;
row_no_ INFO_SERVICES_RPT.ROW_NO%TYPE;
CURSOR ShopOrd is /*--统计未完成的成品订单--*/
SELECT S.PART_NO,S.NEED_DATE,
SHOP_ORDER_INT_API.GET_REMAINING_QTY(S.ORDER_NO,S.RELEASE_NO,S.SEQUENCE_NO,S.PART_NO,S.ORDER_CODE) AS QTY
FROM SHOP_ORD S
LEFT JOIN IFSAPP.INVENTORY_PART_TAB I ON S.PART_NO = I.PART_NO AND S.CONTRACT = I.CONTRACT
WHERE S.STATE <> 'Closed' --状态 不能为关闭的
-- AND S.part_no = 'MD0375001NRKK00'
AND S.CONTRACT='DGNS'
AND SHOP_ORDER_INT_API.GET_REMAINING_QTY(S.ORDER_NO,S.RELEASE_NO,S.SEQUENCE_NO,S.PART_NO,S.ORDER_CODE)>0
-- 剩余数要大于0
AND I.ACCOUNTING_GROUP = 1 -- 会计分组为1 即成品
AND S.ORDER_CODE_DB = 'M' -- 只取制造类型的
ORDER BY s.need_date;

PartNo MANUF_STRUCTURE_TAB.PART_NO%type; --成品品番
StockQty INVENTORY_PART_IN_STOCK.QTY_ONHAND%type; --库存数
F_NeedQty SHOP_ORD.REVISED_QTY_DUE%type; --父需求数量
NeedQty SHOP_ORD.REVISED_QTY_DUE%type; --需求数量
NeedDate SHOP_ORD.NEED_DATE%type; --需要日期


CURSOR CURMANUF is
select * from table(V_MANUF_STRUCTURE) where STRUCTURE_ID=M_ROW_NO_;


TYPE PartNeedQty IS TABLE OF NUMBER INDEX BY VARCHAR(15);
T_NeedQty PartNeedQty;
T_Empty PartNeedQty;

BEGIN
REPORT_SYS.GET_RESULT_KEY__( RESULT_KEY_ ); --获取流水
-- REPORT_SYS.GET_RESULT_KEY__( M_RESULT_KEY_ ); --获取流水 BOM的
row_no_ := 1;
For C_ShopOrd in ShopOrd loop
PartNo := C_shopOrd.Part_no;
T_NeedQty(PartNo):=C_shopOrd.Qty; --获得父部品的需求量
M_ROW_NO_ := Get_Manuf(PartNo);
For C_Manuf in CURMANUF Loop

StockQty:=Get_Stock(C_Manuf.COMPONENT_PART); ----取得子部品库存
-- 需求数=父部品需求数 x 子部品装配量 - 子部品在库
F_NeedQty :=T_NeedQty(C_Manuf.Part_No)*C_Manuf.QTY_PER_ASSEMBLY;
NeedQty:=F_NeedQty-StockQty;
IF NeedQty >= 0 THEN --说明此部品库存不够需求
Set_Stock(C_Manuf.COMPONENT_PART,0); --将半成品库存更改为零
T_NeedQty(C_Manuf.COMPONENT_PART):=NeedQty; --设置子部品剩余需求
Else --说明此部品库存足够,需求需要清除
Set_Stock(C_Manuf.COMPONENT_PART,ABS(NeedQty)); --设置半成品库存
T_NeedQty(C_Manuf.COMPONENT_PART):=0; --清除子部品剩余需求
End IF;
--保存结果
row_no_:= row_no_ +1;

insert into IFSAPP.info_services_rpt(result_key,row_no,parent_row_no,s1,n1,n2,n3,n4,d1)
VALUES(RESULT_KEY_,row_no_,0,C_Manuf.COMPONENT_PART,F_NeedQty,StockQty,T_NeedQty(C_Manuf.COMPONENT_PART),V_Stock_(C_Manuf.COMPONENT_PART),C_ShopOrd.NEED_DATE);

end loop;
T_NeedQty:= T_Empty; --初始化需求交量
end loop;
R_Key := RESULT_KEY_;
END Semi_DayStorage;

END NS_DAYSTORAGE_PRINT_RECORD;
/

猜你喜欢

转载自blog.csdn.net/xhfbx/article/details/83378895