如何在 SAP HANA 中使用触发器显示错误消息

how to show error meassage using trigger in SAP HANA

这里我有两个 table 命名为 Product table 和 Sales table:

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

现在,每当我在销售 table 中插入新记录时,我都会尝试使用该概念创建触发器 table 产品 table 应该更新的是基于销售的“库存” table “数量” 代码:

/*---------------------------------------------------------*/
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 我在销售 table 中插入了一条记录,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 1quantity 6 将记录插入销售额 table 即销售额 table 数量超过可用库存数量意味着它变为负值...

我只想告知销售订单数量值高于可用库存数量,它不应变为负值...有什么办法可以解决这个问题...

我试过这段代码:

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;

你这里的问题很经典。通常这两个业务流程 "SALES" 和 "ORDER FULFILLMENT" 是分开的,所以卖东西的行为不会立即影响库存水平。相反,订单履行实际上可以使用其他资源(例如,从另一个供应商处延期交货或生产更多资源)。这样,销售将与当前库存水平脱钩。

无论如何,如果你想让它成为 "only-sell-whats-available-right-now" 的简单依赖,那么你需要考虑以下几点:

  • 可以同时进行多项销售
  • 如何处理只能部分完成的销售,例如是应该出售所有可用的商品,还是应该将整个订单处理为无法履行?

要再次解决第一点,可以采取不同的方法。最简单的可能是锁定您感兴趣的库存记录,只要您决定是否处理订单(和库存交易)。

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

此语句将获取相关行的锁,return 或等到锁可用以防另一个会话已持有它。

检索到商品数量后,您可以调用进一步的业务逻辑(完全、部分履行订单或拒绝)。
这些应用程序路径中的每一个都可以是对必要步骤进行分组的存储过程。 通过 COMMITing 事务,锁将被释放。

作为一般性评论:这不应作为触发器实现。触发器通常不应涉及可能导致锁定情况的应用程序路径,以避免系统挂起情况。此外,触发器并不能很好地理解语句执行的顺序,这很容易导致不必要的副作用。

存储过程可以为应用程序提供一个接口,以便以有意义且安全的方式处理您的数据,而不是触发器。 例如。

  • 程序ProcessOrder

    • 每件商品的顺序
      • 检查库存并锁定条目
    • (取决于业务逻辑):
    • 从库存中减去所有可用商品以尽可能匹配订单
    • 或者:只履行可以完全提供的订单项目,并将其他项目标记为不可用。减少销售订单 SUM。
    • 或者:拒绝整个订单。

    • 提交;

您的应用程序随后可以简单地调用该过程并获取结果数据(例如当前订单数据、状态等),而不必担心需要如何更新表格。