我在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.';
在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
任何人都可以告诉我我的代码有什么问题。我到处搜寻。
编辑:要执行的过程的代码。此过程已成功添加到数据库中。
-- 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.';
答案 0 :(得分:6)
您应该在official docs中阅读有关触发程序的更多信息。当你调用触发器函数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();
<强>更新强>
所以在你的情况下,触发器应如上所示并触发如下函数:
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;
来自文档
当PL / pgSQL函数被调用为触发器时,会在顶级块中自动创建几个特殊变量。他们是:
NEW
数据类型记录;变量为行级触发器中的INSERT / UPDATE操作保存新数据库行。在语句级触发器和DELETE操作中,此变量为NULL。
OLD
数据类型记录;变量在行级触发器中保存旧数据库行以进行UPDATE / DELETE操作。在语句级触发器和INSERT操作中,此变量为NULL。
...
<强>摘要强>
您应该记住触发器功能与“普通”PostgreSQL功能完全不同,它只能通过触发器调用,触发器提供适当的上下文。另一方面NEW。旧。和其他触发器相关的东西在触发器执行上下文之外是完全没有意义的。