EBS歷史時間庫存報表
公司需要做成EBS的歷史庫存報表,放在釘釘供查詢。先把最終做出的結果圖展示下:
一、解決思路:
由於EBS沒有提供歷史時間庫存表,所以思路就是通過現有量去一步一步地倒推,算出歷史時間庫存表。
現有量可以采用EBS自帶的get_onhand_available_qty函數。
從事務表INV.MTL_MATERIAL_TRANSACTIONS的(TRANSACTION_DATE或者PROGRAM_UPDATE_DATE字段獲取,區別稍後說明)中加加減減,一步一步往回推算。
推算用到的函數為SUM()OVER(),以及LAG()OVER()函數。具體用法請自行百度。
二、代碼如下:
CREATE OR REPLACE VIEW CUX.CUX_ONHAND_OLD_V ( ORGANIZATION_CODE , INVENTORY_ITEM_ID , SEGMENT1 , ELEMENT_VALUE , SUBINVENTORY_CODE , TRANSACTION_DATE , TRANSACTION_QUANTITY , STOCK_IN , STOCK_OUT , TRANSACTION_UOM , ONHAND_QTY , CURRENT_QTY ) AS WITH T AS ( SELECT SUBINVENTORY_CODE --, REVISION -- , TRANSFER_SUBINVENTORY --, SHIP_TO_LOCATION_ID --, COST_GROUP_ID --, TRANSFER_COST_GROUP_ID --, LPN_ID --, CONTENT_LPN_ID --, TRANSFER_LPN_ID --, TRANSFER_ORGANIZATION_ID --, OWNING_ORGANIZATION_ID --, PLANNING_TP_TYPE -- , OWNING_TP_TYPE --, PLANNING_ORGANIZATION_ID , TRUNC (TRANSACTION_DATE) TRANSACTION_DATE , SUM (TRANSACTION_QUANTITY) TRANSACTION_QUANTITY , SUM ( (case when TO_NUMBER (TRANSACTION_QUANTITY) >= 0 then TRANSACTION_QUANTITY else null end)) stock_in , SUM ( (case when TO_NUMBER (TRANSACTION_QUANTITY) < 0 then -1 * TRANSACTION_QUANTITY else null end)) stock_out , TRANSACTION_UOM --, PRIMARY_QUANTITY , APPS.cux_public_pkg.get_onhand_qty ( p_inventory_item_id => inventory_item_id , p_organization_id => organization_id , p_subinv_code => subinventory_code) onhand_qty --, SECONDARY_TRANSACTION_QUANTITY --, SECONDARY_UOM_CODE --, SHIPMENT_NUMBER --, WAYBILL_AIRBILL --, FREIGHT_CODE --, NUMBER_OF_CONTAINERS --, TRANSACTION_REFERENCE --, COSTED_FLAG -- , OPM_COSTED_FLAG -- , PM_COST_COLLECTED --, PM_COST_COLLECTOR_GROUP_ID --, TRANSACTION_GROUP_ID --, VENDOR_LOT_NUMBER -- , SOURCE_CODE -- , SOURCE_LINE_ID -- , TRANSFER_TRANSACTION_ID --, PARENT_TRANSACTION_ID --, LOGICAL_TRANSACTION --, TRANSACTION_SET_ID -- , RCV_TRANSACTION_ID -- , MOVE_TRANSACTION_ID --, COMPLETION_TRANSACTION_ID --, OPERATION_SEQ_NUM --, SOURCE_PROJECT_ID --, SOURCE_TASK_ID --, PROJECT_ID --, TASK_ID --, TO_PROJECT_ID --, TO_TASK_ID --, EXPENDITURE_TYPE --, PA_EXPENDITURE_ORG_ID --, ERROR_CODE --, ERROR_EXPLANATION --, transaction_source_name --, XFR_OWNING_ORGANIZATION_ID --, TRANSFER_OWNING_TP_TYPE --, ATTRIBUTE_CATEGORY -- , ATTRIBUTE1 -- , ATTRIBUTE2 -- , ATTRIBUTE3 -- , ATTRIBUTE4 -- , ATTRIBUTE5 -- , ATTRIBUTE6 -- , ATTRIBUTE7 -- , ATTRIBUTE8 -- , ATTRIBUTE9 -- , ATTRIBUTE10 -- , ATTRIBUTE11 -- , ATTRIBUTE12 -- , ATTRIBUTE13 -- , ATTRIBUTE14 -- , ATTRIBUTE15 --, LAST_UPDATED_BY -- , CREATION_DATE --, CREATED_BY -- , LAST_UPDATE_LOGIN -- , REQUEST_ID --, PROGRAM_APPLICATION_ID --, PROGRAM_ID --, PROGRAM_UPDATE_DATE -- , LAST_UPDATE_DATE , INVENTORY_ITEM_ID , ORGANIZATION_ID --, LOCATOR_ID -- , REASON_ID -- , TRANSFER_LOCATOR_ID -- , TRANSACTION_TYPE_ID -- , TRANSACTION_ACTION_ID -- , TRANSACTION_SOURCE_TYPE_ID -- , TRANSACTION_SOURCE_ID --, EMPLOYEE_CODE --, DEPARTMENT_ID --, MASTER_SCHEDULE_UPDATE_CODE --, RECEIVING_DOCUMENT --, PICK_STRATEGY_ID --, PICK_RULE_ID --, PUT_AWAY_STRATEGY_ID --, PUT_AWAY_RULE_ID --, ORIGINAL_TRANSACTION_TEMP_ID FROM INV.MTL_MATERIAL_TRANSACTIONS WHERE TRANSACTION_ACTION_ID NOT IN (24, 30) -- and (ORGANIZATION_ID = 86) -- and (INVENTORY_ITEM_ID = 5683) and ( LOGICAL_TRANSACTION = 2 OR LOGICAL_TRANSACTION IS NULL) -- and (subinventory_code = ‘101‘) group by organization_id , inventory_item_id , subinventory_code , TRANSACTION_UOM , TRUNC (TRANSACTION_DATE) ORDER BY TRUNC (TRANSACTION_DATE) DESC), T1 AS (SELECT organization_id , inventory_item_id , SUBINVENTORY_CODE , TRANSACTION_DATE , TRANSACTION_QUANTITY , STOCK_IN , STOCK_OUT , TRANSACTION_UOM , ONHAND_QTY , ( ONHAND_QTY - SUM (TRANSACTION_QUANTITY) over (partition by organization_id , subinventory_code , inventory_item_id , TRANSACTION_UOM order by TRANSACTION_DATE desc)) as current_temp_qty FROM t) SELECT DECODE (organization_id, 85, 101, 86, 102, organization_id) organization_code , inventory_item_id , (SELECT SEGMENT1 FROM inv.mtl_system_items_b where inventory_item_id = t1.inventory_item_id and ORGANIZATION_ID = t1.organization_id) SEGMENT1 , (SELECT ELEMENT_VALUE FROM apps.MTL_DESCR_ELEMENT_VALUES_V where inventory_item_id = t1.inventory_item_id and ELEMENT_SEQUENCE = 20) ELEMENT_VALUE , SUBINVENTORY_CODE , TRANSACTION_DATE , TRANSACTION_QUANTITY , stock_in , stock_out , TRANSACTION_UOM , ONHAND_QTY , LAG (current_temp_qty, 1, ONHAND_QTY) over (partition by organization_id , subinventory_code , inventory_item_id , TRANSACTION_UOM order by TRANSACTION_DATE desc) current_qty FROM t1;
三、驗證:TRANSACTION_DATE、PROGRAM_UPDATE_DATE區別
通過報表“事務歷史記錄匯總”去驗證某一天的歷史庫存。這裏的驗證是以TRANSACTION_DATE字段去做驗證的。
但這樣跑出來的結果,在某一天有可能是負數的。因為有些庫存它當天卡在接口上,第二天,甚至過一段時間之後才會從接口上跑過去。
這導致了庫存不準確,甚至庫存為負數。所以我的做法是取PROGRAM_UPDATE_DATE字段。
四、優化:
寫好後的cux.cux_onhand_v視圖,執行時需要30多秒,有點慢。但還是屬於可接受範圍內。
但在手機執行時是需要傳條件過去查詢的,最初寫的代碼如下(5秒執行完畢):
SELECT onhand.ORGANIZATION_CODE as "組織代碼" , onhand.SEGMENT1 as "材料名稱" , onhand.ELEMENT_VALUE as "規格型號" , onhand.SUBINVENTORY_CODE as "庫" , onhand.PROGRAM_UPDATE_DATE as "日期" , onhand.STOCK_IN as "收入數量" , onhand.STOCK_OUT as "發出數量" , onhand.TRANSACTION_UOM as "單位" , onhand.CURRENT_QTY as "結存數量" FROM cux.cux_onhand_v onhand WHERE onhand.segment1 = ‘102005-000256‘ and onhand.ORGANIZATION_code = 102 and onhand.SUBINVENTORY_CODE = ‘101‘
這樣的代碼手機執行花了5秒時間,只能算是勉強接受了。先看下執行計劃(COST成本花了5409)
從執行計劃可以看出,cost從182猛增到4022,是因為我們在訪問INV.MTL_MATERIAL_TRANSACTIONS表時沒有做謂詞推進。
這也是因為cux_onhand_v視圖訪問慢的最主要原因。代碼改成如下:
SELECT onhand.ORGANIZATION_CODE as "組織代碼" , onhand.SEGMENT1 as "材料名稱" , onhand.ELEMENT_VALUE as "規格型號" , onhand.SUBINVENTORY_CODE as "庫" , onhand.PROGRAM_UPDATE_DATE as "日期" , onhand.STOCK_IN as "收入數量" , onhand.STOCK_OUT as "發出數量" , onhand.TRANSACTION_UOM as "單位" , onhand.CURRENT_QTY as "結存數量" FROM cux.cux_onhand_v onhand , (SELECT inventory_item_id FROM inv.mtl_system_items_b WHERE organization_id = 84 AND segment1 = ‘102005-000256‘ AND ROWNUM = 1) b WHERE onhand.inventory_item_id = b.inventory_item_id and onhand.ORGANIZATION_code = 102 and onhand.SUBINVENTORY_CODE = ‘101‘
執行計劃如下所示:(將謂詞inventory_item_id推進入MTL_MATERIAL_TRANSACTIONS表,COST成本從5409立即下降到32)
這樣優化後的代碼,執行時間由5秒立即下降為1秒,也就是說,手機展示數據所花的時間為“秒殺”。
EBS歷史時間庫存報表