简体   繁体   English

在PostgreSQL中创建触发器时出现NEW语法错误

[英]Syntax error with NEW while creating a trigger in PostgreSQL

I am creating a trigger in Postgresql as follows. 我在Postgresql中创建一个触发器,如下所示。

    CREATE TRIGGER "PRODUCT_ADD_TRIGGER" AFTER INSERT
   ON product FOR EACH ROW
   EXECUTE PROCEDURE INVENTORY_ENTRY_NEW_PRODUCT(NEW.productcode);
COMMENT ON TRIGGER "PRODUCT_ADD_TRIGGER" ON product
  IS '-- Executes a procedure that inserts a row into the inventorytxns table.';

When executed in the Query Manager of pgAdmin-III, the following error is thrown. 在pgAdmin-III的查询管理器中执行时,将引发以下错误。

ERROR:  syntax error at or near "."
LINE 3: ... EXECUTE PROCEDURE INVENTORY_ENTRY_NEW_PRODUCT(NEW.productco...
                                                             ^

********** Error **********

ERROR: syntax error at or near "."
SQL state: 42601
Character: 130

Can anyone tell me what is wrong with my code. 任何人都可以告诉我我的代码有什么问题。 I've searched everywhere. 我到处搜寻。

EDIT : Code for the procedure that is to be executed. 编辑:要执行的过程的代码。 This procedure has been successfully added to the database. 此过程已成功添加到数据库中。

-- Function: "INVENTORY_ENTRY_NEW_PRODUCT"(integer)

-- DROP FUNCTION "INVENTORY_ENTRY_NEW_PRODUCT"(integer);

CREATE OR REPLACE FUNCTION "INVENTORY_ENTRY_NEW_PRODUCT"(productcode integer)
  RETURNS record AS
$BODY$
-- Declare the required variables.
DECLARE
    -- Inventory row that stores the result of the query on the inventory table.
    inventoryrow inventory%ROWTYPE;
    result record;
BEGIN

    SELECT * INTO inventoryrow from inventory where fk_productcode = productcode;

    IF NOT FOUND THEN
        -- INVENTORY TRANSACTION CAN BE ADDED.
        -- An inventory transaction can be added to the inventorytxns table
        INSERT INTO inventorytxns (fk_productcode,fk_txntypeid) VALUES(productcode,6);

        -- Once a row is added into the inventory txns table, it automatically adds data into the inventory table.
        SELECT * INTO result FROM INVENTORY WHERE fk_productcode = productcode;

        IF NOT FOUND THEN
            -- RAISE AN EXCEPTION. THIS OPERATION IS SUPPOSED TO HAPPEN.
            RAISE EXCEPTION 'Product with product code % added in inventorytxns table but not added in inventory table',productcode;
        END IF;
        -- Transaction type 6 represents addition of a new product transaction type.
    END IF;

    RAISE DEBUG 'Product with product code % already available in inventory',productcode;

END;
-- Check if the inventory entry already exits in the inventory table.
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION "INVENTORY_ENTRY_NEW_PRODUCT"(integer)
  OWNER TO postgres;
COMMENT ON FUNCTION "INVENTORY_ENTRY_NEW_PRODUCT"(integer) IS 'Adds a new entry in the inventorytxns table for a new product.';

You should read more about trigger procedures in official docs . 您应该阅读官方文档中有关触发器过程的更多信息。 When you call trigger function OLD, NEW and bunch of other things or passed implicitly through TG_NARGS and TG_ARGV, so you shouldn't do it by yourself. 当你调用触发器函数OLD,NEW和其他一些东西或通过TG_NARGS和TG_ARGV隐式传递时,所以你不应该自己动手。

CREATE OR REPLACE FUNCTION INVENTORY_ENTRY_NEW_PRODUCT()
RETURNS TRIGGER AS $INVENTORY_ENTRY_NEW_PRODUCT_TRIGGER$
BEGIN
  -- Here you can access NEW.productcode

RETURN NULL;
END;
 $INVENTORY_ENTRY_NEW_PRODUCT_TRIGGER$ LANGUAGE plpgsql;


CREATE TRIGGER PRODUCT_ADD_TRIGGER AFTER INSERT
ON product FOR EACH ROW
EXECUTE PROCEDURE INVENTORY_ENTRY_NEW_PRODUCT();

UPDATE UPDATE

So in your case trigger should look like above and trigger function like below: 所以在你的情况下,触发器应如上所示并触发如下函数:

CREATE OR REPLACE FUNCTION "INVENTORY_ENTRY_NEW_PRODUCT"()
  RETURNS record AS
$BODY$
-- Declare the required variables.
DECLARE
    -- Inventory row that stores the result of the query on the inventory table.
    inventoryrow inventory%ROWTYPE;
    result record;
BEGIN

    SELECT * INTO inventoryrow from inventory where fk_productcode = NEW.productcode;

    IF NOT FOUND THEN
        -- INVENTORY TRANSACTION CAN BE ADDED.
        -- An inventory transaction can be added to the inventorytxns table
        INSERT INTO inventorytxns (fk_productcode,fk_txntypeid) VALUES(NEW.productcode,6);

        -- Once a row is added into the inventory txns table, it automatically adds data into the inventory table.
        SELECT * INTO result FROM INVENTORY WHERE fk_productcode = NEW.productcode;

        IF NOT FOUND THEN
            -- RAISE AN EXCEPTION. THIS OPERATION IS SUPPOSED TO HAPPEN.
            RAISE EXCEPTION 'Product with product code % added in inventorytxns table but not added in inventory table',NEW.productcode;
        END IF;
        -- Transaction type 6 represents addition of a new product transaction type.
    END IF;

    RAISE DEBUG 'Product with product code % already available in inventory',productcode;

END;
-- Check if the inventory entry already exits in the inventory table.
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

From docs 来自docs

When a PL/pgSQL function is called as a trigger, several special variables are created automatically in the top-level block. 当PL / pgSQL函数被调用为触发器时,会在顶级块中自动创建几个特殊变量。 They are: 他们是:

NEW

Data type RECORD; 数据类型RECORD; variable holding the new database row for INSERT/UPDATE operations in row-level triggers. 变量为行级触发器中的INSERT / UPDATE操作保存新数据库行。 This variable is NULL in statement-level triggers and for DELETE operations. 在语句级触发器和DELETE操作中,此变量为NULL。

OLD

Data type RECORD; 数据类型RECORD; variable holding the old database row for UPDATE/DELETE operations in row-level triggers. 变量在行级触发器中保存旧数据库行以进行UPDATE / DELETE操作。 This variable is NULL in statement-level triggers and for INSERT operations. 在语句级触发器和INSERT操作中,此变量为NULL。

... ...

Summary 摘要

You should remember that trigger functions are really different from 'normal' PostgreSQL function and it can be called only by trigger, which provides proper context. 你应该记住,触发函数与'普通'PostgreSQL函数真的不同,它只能通过触发器调用,触发器提供适当的上下文。 For the other hand NEW. 另一方面NEW。 OLD. 旧。 and other trigger related stuff is completely meaningless outside trigger execution context. 和其他触发相关的东西在触发器执行上下文之外完全没有意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM