I am creating a trigger in Postgresql as follows.
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.
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.';
Syntax. CREATE TRIGGER trigger_name [BEFORE|AFTER|INSTEAD OF] event_name ON table_name [ -- Trigger logic goes here.... ]; Here, event_name could be INSERT, DELETE, UPDATE, and TRUNCATE database operation on the mentioned table table_name. You can optionally specify FOR EACH ROW after table name.
The error message “syntax error at or near 'grant'” is one of the most common PostgreSQL database errors. However, it can easily be identified and resolved. To understand this issue, you need to know that SQL distinguishes between reserved and non-reserved key word tokens.
To enable a trigger or all triggers associated with a table, you use the ALTER TABLE ENABLE TRIGGER statement: ALTER TABLE table_name ENABLE TRIGGER trigger_name | ALL; In this syntax: First, specify the name of the table of the trigger that you want to enable.
This is not currently implemented by PostgreSQL. PostgreSQL only allows the execution of a user-defined function for the triggered action. The standard allows the execution of a number of other SQL commands, such as CREATE TABLE , as the triggered action.
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.
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
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
When a PL/pgSQL function is called as a trigger, several special variables are created automatically in the top-level block. They are:
NEW
Data type RECORD; variable holding the new database row for INSERT/UPDATE operations in row-level triggers. This variable is NULL in statement-level triggers and for DELETE operations.
OLD
Data type RECORD; variable holding the old database row for UPDATE/DELETE operations in row-level triggers. This variable is NULL in statement-level triggers and for INSERT operations.
...
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. For the other hand NEW. OLD. and other trigger related stuff is completely meaningless outside trigger execution context.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With