创建 PostgreSql 触发器以更新库存数量

Posted

技术标签:

【中文标题】创建 PostgreSql 触发器以更新库存数量【英文标题】:Creating a PostgreSql trigger to update stock Quantity 【发布时间】:2015-01-15 12:05:29 【问题描述】:

我想为使用 Postgresql DBMS 9.4 版的库存管理系统创建触发器。 它允许我计算库存产品的数量。所以,她是我们需要的表的架构。

produit(produitid(PK),qteInitiale,qteInStock,prixDachat,prixDevente) ; 
entreeDetaille(qteIn,prixDachat,remise,(produitId(FK),bonId(FK),(PK)));
sortieDetaille(qteOut,prixDeVente,remise,(produitId(FK),bonId(FK),(PK)));

The Stock quantity = produit.qteInitiale where id = ? + sum(qteIn) where  id = ? + sum(qteOut) where id = ? 

需要在 entreeDetaille 或 sortieDetaille 表上发生插入事件后调用触发器。

我已经开始尝试,但对我不起作用:

    CREATE OR REPLACE FUNCTION updateqteinstock()
      RETURNS trigger AS
    $BODY$
    declare 
    qteInitiale money;
    qteAcheter money ;
    qteVendue money;
    qteEnStock money ; 
    produitID integer ;
    begin

    if TG_OP == "INSERT" then   
    produitID := NEW.produitid; 
    else
    produitID := OLD.produitid; 
    end if ;


    -- ramener la quantité Initiale de stock
    qteInitiale := select qteinitiale from produit where produitid = produitID ;

    -- ramener la quantité acheter
    qteAcheter := (select sum(qtein) from entreedetaille where produitid = produitID ); 

 -- ramener la quantité vendue
   qteVendue := select sum(qteOut) from sortieDetaille where produitid = produitID ; 

    -- calculate quantité qte en stock + quantité acheter + quantité vendue
    qteEnStock := qteInitiale + qteAcheter - qteVendue;

    -- update la quantite en stock ;
    update produit set qtestock = qteEnStock where produitid = produitID ; 

    if TG_OP == "INSERT" 
    return new;
    else 
    return old;
    end;
    $BODY$
      LANGUAGE plpgsql

我收到了这个错误:

    org.postgresql.util.PSQLException: ERROR: column "produitid" does not exist
  Où : PL/pgSQL function updateqteinstock() line 11 at assignment
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2198)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1927)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:561)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:419)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:365)
    at DAO.BonDachatDAO.create(BonDachatDAO.java:203)
    at CONTROLLER.BonDachatController.createBonDachat(BonDachatController.java:83)
    at VIEW.eventsManagers.BonDachatEventManager.saveBonDachat(BonDachatEventManager.java:108)
    at VIEW.eventsManagers.BonDachatEventManager.actionPerformed(BonDachatEventManager.java:79)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    at java.awt.Component.processMouseEvent(Component.java:6527)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
    at java.awt.Component.processEvent(Component.java:6292)
    at java.awt.Container.processEvent(Container.java:2234)
    at java.awt.Component.dispatchEventImpl(Component.java:4883)
    at java.awt.Container.dispatchEventImpl(Container.java:2292)
    at java.awt.Component.dispatchEvent(Component.java:4705)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
    at java.awt.Container.dispatchEventImpl(Container.java:2278)
    at java.awt.Window.dispatchEventImpl(Window.java:2739)
    at java.awt.Component.dispatchEvent(Component.java:4705)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:746)
    at java.awt.EventQueue.access$400(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:697)
    at java.awt.EventQueue$3.run(EventQueue.java:691)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.awt.EventQueue$4.run(EventQueue.java:719)
    at java.awt.EventQueue$4.run(EventQueue.java:717)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:716)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
org.postgresql.util.PSQLException: ERROR: column "porduitid" does not exist
  Où : PL/pgSQL function updateqteinstock() line 14 at assignment
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2198)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1927)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:561)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:419)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:365)
    at DAO.BonDachatDAO.create(BonDachatDAO.java:203)
    at CONTROLLER.BonDachatController.createBonDachat(BonDachatController.java:83)
    at VIEW.eventsManagers.BonDachatEventManager.saveBonDachat(BonDachatEventManager.java:108)
    at VIEW.eventsManagers.BonDachatEventManager.actionPerformed(BonDachatEventManager.java:79)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    at java.awt.Component.processMouseEvent(Component.java:6527)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
    at java.awt.Component.processEvent(Component.java:6292)
    at java.awt.Container.processEvent(Container.java:2234)
    at java.awt.Component.dispatchEventImpl(Component.java:4883)
    at java.awt.Container.dispatchEventImpl(Container.java:2292)
    at java.awt.Component.dispatchEvent(Component.java:4705)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
    at java.awt.Container.dispatchEventImpl(Container.java:2278)
    at java.awt.Window.dispatchEventImpl(Window.java:2739)
    at java.awt.Component.dispatchEvent(Component.java:4705)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:746)
    at java.awt.EventQueue.access$400(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:697)
    at java.awt.EventQueue$3.run(EventQueue.java:691)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.awt.EventQueue$4.run(EventQueue.java:719)
    at java.awt.EventQueue$4.run(EventQueue.java:717)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:716)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

在这里我已将触发器附加到此过程:

CREATE TRIGGER achatTrigger AFTER INSERT OR DELETE on entreedetaille
FOR EACH ROW EXECUTE PROCEDURE updateqteinstock();



CREATE TRIGGER venteTrigger AFTER INSERT OR DELETE on sortiedetaille
FOR EACH ROW EXECUTE PROCEDURE updateqteinstock();

【问题讨论】:

postgresql.org/docs/current/static/… 【参考方案1】:

将选择值设置为 qteInitiale 变量时需要 start ( 和 end )。

改成这样:

qteInitiale := (select qteinitiale from produit where produitid = produitID) ;

【讨论】:

或使用select qteinitiale into qteInitiale from produit ... 在修复最后一个错误之后,我得到了这个错误:org.postgresql.util.PSQLException: ERROR: org.postgresql.util.PSQLException: ERROR: column "INSERT" does not exist Où : PL/ pgSQL 函数 updateqteinstock() 第 10 行在 IF 使用 ' 单引号而不是 ". 我不知道,但他不接受 qteInitiale :=assignement org.postgresql.util.PSQLException: ERROR: column reference "qteinitiale" is ambiguous 详细信息:它可能指的是 PL /pgSQL 变量或表列。 Où : PL/pgSQL 函数 updateqteinstock() line 18 at assignment

以上是关于创建 PostgreSql 触发器以更新库存数量的主要内容,如果未能解决你的问题,请参考以下文章

创建触发器以重新排序列并修改语句级别

如何修改触发器以更新 PostgreSQL 中的单个属性

MySQL 查询 - 创建一个触发器,在销售发生后更新库存水平

MySQL触发器 trigger之after与before区分

更新 WooCommerce 可变产品变化库存数量问题

postgreSQL创建一个触发器函数:更新过student1表的数据后,更新student1_stats表中数据。