2017-07-31 122 views
0

在這裏,我有兩個表命名爲Product表和銷售表使用觸發器顯示錯誤meassage:如何在SAP HANA

Product table  Sales table 
P_ID|QTY |  |O_ID|QTY | 
1 |10 |  |1 |5  | 
2 |15 |   

現在,我試圖創建每當我插入的概念觸發在銷售表中的產品表應該更新新的記錄是基於銷售表的「量」 代碼「清單」:

/*---------------------------------------------------------*/ 
create trigger "KABIL_PRACTICE"."SALES_TRIGGER" 
after insert on "KABIL_PRACTICE"."SALES" REFERENCING NEW ROW AS newrow for each row 
begin 
update "KABIL_PRACTICE"."Inventory" set "Inventory" = "Inventory" - :newrow.QTY 
where "P_ID" = :newrow.P_ID ; 
end; 
/*-----------------------------------------------------------*/ 

,並收到預期output.when我插入一條記錄與P中的銷售表-ID 1,數量爲5

updated Product table   Sales table 
P_ID|QTY |     |O_ID|QTY | 
1 |-1 |     |1 |5  | 
2 |15 |     |1 |6  | 

但在這裏我有一個另一個問題..如果我有P_ID 1再插入一條記錄到銷售表再次quantity 6即銷售表數量超過可用的庫存量意味着它進入負值...

我只想親密的銷售訂單數量值大於可用庫存量較高,它不應該去負值...有什麼辦法這個...

我想這代碼:

create trigger "KABIL_PRACTICE"."SALES_UPDATE_TRIGGER" 
before insert on "KABIL_PRACTICE"."SALES" REFERENCING NEW ROW AS newrow for each row 
begin 

if("Inventory" > :newrow.QTY) 
Then 
update "KABIL_PRACTICE"."Inventory" set "Inventory" = "Inventory" - :newrow.QTY 
where "P_ID" = :newrow.P_ID ; 
elseif ("Inventory" < :newrow.QTY) 
Then NULL; 

delete "KABIL_PRACTICE"."SALES" where "QTY" = 0; 
end; 

回答

0

您在這裏遇到的問題是一個經典問題。通常兩個業務流程「銷售」和「訂單履行」是分開的,因此銷售商品的行爲不會立即影響庫存水平。相反,訂單履行實際上可能使用其他資源(例如,從另一個供應商處退貨或生產更多)。這樣,銷售將從當前的庫存水平中分離出來。

總之,如果你要保持它的簡單依賴「僅銷售-什麼可用 - 右 - 現在」,那麼你需要考慮以下幾點:

  • 多個銷售可能在以下回事同一時間
  • 如何處理只能部分實現的銷售,例如是否應該銷售所有可用的物品,還是應該將整個訂單處理爲無法完成?

要解決第一個問題,可以採取不同的方法。最簡單的方法是,只要您決定是否處理訂單(和庫存交易),就可以鎖定您感興趣的庫存記錄。

SELECT QTY "KABIL_PRACTICE"."Inventory" WHERE P_ID = :P_ID FOR UPDATE; 

本聲明將收購的相關行(S)鎖,並返回,或者等到鎖定的情況下,另一個會話已持有它變得可用。

一旦檢索到一件物品的數量,就可以調用進一步的業務邏輯(完全履行訂單,部分履行或者拒絕)。
這些應用程序路徑中的每一個都可以是一個存儲過程,將必要的步驟分組在一起。 通過COMMIT交易鎖定將被釋放。

作爲一般性評論:這不應該作爲觸發器來實現。觸發器通常不應涉及可能導致鎖定情況的應用程序路徑,以避免系統掛起的情況。此外,觸發器並不能真正理解語句執行的順序,這很容易導致不必要的副作用。

存儲過程不是觸發器,而是爲應用程序提供接口,以有意義和安全的方式處理數據。 例如

  • 程序ProcessOrder

    • 每個項目爲了
      • 查詢股票和鎖條目
    • (根據業務邏輯):
    • 減除所有可用的項目從庫存到匹配順序與possi一樣多ble
    • OR:只完成可完全提供的訂單商品並將其他商品標記爲不可用。減少銷售訂單SUM。
    • OR:拒絕整個訂單。

    • COMMIT;

您的應用程序可以然後只需調用程序,並採取檢索結果的數據(例如,當前的訂單數據,狀態,...),而不必擔心如何表需要更新。