2015-10-05 35 views
0

我有一個關於Oracle過程的問題,希望你們幫助我,我有這3個表:步驟檢查費用產品。甲骨文

成分: Ingredient_Number PK Ingredient_Name, Quantity_On_Hand , Reorder_Point, Current_Cost,

MENU_ITEM
Menu_Item_Number PK Menu_Item_Name, CURRENT_PRICE, Production_Cost,

Menu_Item_Ingredient
Menu_Item_Number PK/FK, Ingredient_Number PK/FK, Quantity_Needed,

我試圖創建更新Production_Cost上MENU_ITEM表的過程,如果Production_Cost < Quantity_Needed * Current_cost * 0.75 and I ended with these code:

Create or Replace Procedure PR_Check_Cost 
(P_Menu_Item_Number Number, P_Ingredient Number) 
authid current_user 
IS 
V_Productiton_Cost Number (6,2); 
V_Current_Cost 
V_Quantity_Needed Number (5,2); 

CURSOR C_Cost 
IS 
Select Production_Cost 
INTO V_Production_Cost 
From Menu_Item 
Where Menu_Item_Number= P_Menu_Item_Number; 


Begin 
Open C_Cost; 

Select Quantity_Needed 
Into V_Quantity_Needed 
FROM Menu_Item_Ingredient 
WHERE Ingredient_Number = P_Ingredient_Number 
AND Menu_Item_Number = P_Menu_Item_Number; 

Select Current_Cost 
INTO V_CurrentCost 
From Ingredient 
Where Ingredient_Number = P_Ingredient_Number; 

Fetch C_Product_Cost INTO V_Current_Cost, V_Quantity_Needed 
While C_Product_Cost%FOUND LOOP 


If (V_Quantity_Needed * V_Current_Cost * 0.75) > V_Production_Cost 
{ 
    UPDATE Menu_Item 
    SET Production_Cost = V_Quantity_Needed * V_Current_Cost * 0.75 
    Where Menu_Item_Number = P_Menu_Item_Number 
    AND Ingredient-Number = P_Ingredient_Number; 
} 


End PR_Check_Cost;/ 
SHOW ERRORS;  

反正有沒有改變我的程序自動檢查和更新Production_Cost每當用戶更新Current_Cost和Quantity_Needed列,而不進入輸入數據Menu_Item_Number(PK)和Ingredient_Number(PK)

回答

1

這裏是一個解決方案只會查詢您需要更新的內容,然後使用批量更新它們。它會表現得非常好,作爲額外的獎勵。

CREATE OR REPLACE update_pr_costs 
AS 
DECLARE 

    menu_item_tab IS TABLE OF ROWTYPE%MENU_ITEM 
     INDEX BY PLS_INTEGER; 

    menu_items menu_item_tab; 

Begin 

Select 
    mi.Menu_Item_Number, 
    mi.Menu_Item_Name, 
    mi.Current_Price, 
    (mii.Quantity_Needed * ig.Current_Cost * 0.75) Production_Cost 
BULK COLLECT INTO menu_items 
FROM Menu_Item_Ingredient mii 
JOIN Ingredient ig 
ON mii.Ingredient_Number = ig.Ingredient_Number 
LEFT JOIN Menu_Item mi 
ON mi.Ingredient_Number = ig.Ingredient_Number 
AND mii.Menu_Item_Number = mi.Menu_Item_Number 
WHERE (ig.Current_Cost * mii.Quantity_Needed * 0.75) > mi.Production_Cost; 

FORALL i in menu_items.FIRST .. menu_items.LAST 
    UPDATE Menu_Item 
    SET Production_Cost = menu_items(i).Production_Cost 
    where Menu_Item_Number = menu_items(i).Menu_Item_Number 
    AND Ingredient_Number = menu_items(i).Ingredient_Number; 


End PR_Check_Cost;/ 
SHOW ERRORS; 

可用於啓動程序的觸發器。

CREATE OR REPLACE TRIGGER ingredient_after_update 
AFTER UPDATE 
    ON Ingredient 
BEGIN 
    update_pr_costs; 
END; 

CREATE OR REPLACE TRIGGER menu_item_ing_after_update 
AFTER UPDATE 
    ON Menu_Item_Ingredient 
BEGIN 
    update_pr_costs; 
END; 
+0

感謝您的幫助,但我可以只用過程和光標嗎? – Kranatos

+0

是的。你的其他選擇是使用AFTER UPDATE創建兩個觸發器。那些觸發器會在沒有輸入的情況下調用這個過程,只更新需要的記錄。我會用一個例子來更新我的答案。 – KDoyle

+0

我的意思是我可以只用過程,光標和連接表完成它? – Kranatos