I am trying to create a SQL trigger function which should UPDATE a column when data is INSERTed INTO the table. The update is based on the values present in the values being INS
Can't you just do something along those lines?
INSERT INTO daily_ohlc
SELECT current_date, 101, 110, 95, 108, (COUNT(*)*AVG(close)+108)/(1+Count(*))
FROM daily_ohlc
WHERE cDate >= ANY (
SELECT MIN(cdate)
FROM (SELECT CDate, ROW_NUMBER() OVER (ORDER BY CDate DESC) as RowNum FROM daily_ohlc) a
WHERE RowNum <= 7
)
I know very well it could appear complicated compared to a trigger.
However, I am trying to avoid a case where you successfully create the ON INSERT
trigger and next want to handle updates in the table. Updating a table within a procedure triggered by an update in the same table is not the best idea.
You may do an UPDATE FROM
your select query using appropriate joins in your Trigger.
create or replace function update_sma8() RETURNS TRIGGER AS
$$
BEGIN
UPDATE daily_ohlc d SET sma8 = s.simple_mov_avg
FROM
(
SELECT sec.cdate,AVG(sec.close)
OVER(ORDER BY sec.cdate ROWS BETWEEN 7 PRECEDING AND CURRENT ROW) AS
simple_mov_avg FROM daily_ohlc sec
)s where s.cdate = NEW.cdate --The newly inserted cdate
AND d.cdate = s.cdate;
RETURN NULL;
END $$ language plpgsql;
Demo
The only caveat of using this method is that if someone deletes a row or updates close
column, then the values have to be recalculated, which won't happen for existing rows. Only the inserted row will see the right re-calculated value.
Instead, you may simply create View
to calculate the sma8
column from the main table for all rows when requested.