Skip to content
Advertisement

Create a trigger that updates the columns of another table (Postgresql)

I have two tables “books” and “bookOrder” and they look something like this:

bookOrder

orderID book name required availability
1 Harry Potter 9 yes
2 Twilight 8 yes
3 Bible 8 yes

books

book name quantity
Harry Potter 10
Twilight 5
Bible 8

I want to create a trigger that every time the books table is updated, it will update the bookorder availability column based on the book quantity column.

I have created a query as follows that does what I need:

UPDATE bookOrder bo
SET avalability = CASE WHEN b.quantity < bo.required THEN 'NO' ELSE 'YES' END
FROM books b
WHERE b.bookName = bo.bookName

However, would be better if this was automatic so a trigger was my first thought. To create a trigger, I would need a function to execute. This is where I have been trouble creating the function. My attempt is as below:

CREATE OR REPLACE FUNCTION update_books() RETURNS TRIGGER AS $$
    BEGIN
        UPDATE bookOrder bo
        SET avalability = CASE WHEN b.quantity < bo.required THEN 'NO' ELSE 'YES' END
        FROM books b
        WHERE b.bookName = bo.bookName
    END
$$  LANGUAGE plpgsql;

Why do I get an error at the last line where the ($$) is at?

Advertisement

Answer

The procedure compiled after adding a semi-colon after the WHERE clause.
And it also had to return something.

But the update doesn’t need to update each row in the target table whenever books gets updated.

CREATE OR REPLACE FUNCTION update_bookorder_availability() 
RETURNS TRIGGER
AS $$
BEGIN

  UPDATE bookOrder bo
  SET availability = CASE 
                     WHEN bo.required <= NEW.quantity THEN 'yes' 
                     ELSE 'no' 
                     END
  WHERE bo.bookName = NEW.bookName;
  
  RETURN NEW;
END
$$ LANGUAGE plpgsql;
CREATE TRIGGER bookorder_availability_changes
  AFTER UPDATE
  ON books
  FOR EACH ROW
  EXECUTE PROCEDURE update_bookorder_availability();
-- before update
select * from books;
select * from bookOrder;
bookname     | quantity
:----------- | -------:
Harry Potter |       10
Twilight     |        5
Bible        |        8

orderid | bookname     | required | availability
------: | :----------- | -------: | :-----------
      1 | Harry Potter |        9 | yes         
      2 | Twilight     |        8 | yes         
      3 | Bible        |        8 | yes         
update books set quantity = quantity;
3 rows affected
-- after update
select * from books;
select * from bookOrder;
bookname     | quantity
:----------- | -------:
Harry Potter |       10
Twilight     |        5
Bible        |        8

orderid | bookname     | required | availability
------: | :----------- | -------: | :-----------
      1 | Harry Potter |        9 | yes         
      2 | Twilight     |        8 | no          
      3 | Bible        |        8 | yes         

Test on db<>fiddle here

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement