Одна и та же триггерная функция PostgreSQL для ОБНОВЛЕНИЯ по INSERT в разные таблицы (с использованием одной и той же схемы) - PullRequest
0 голосов
/ 12 января 2019

У меня есть сотни таблиц, имеющих одинаковую схему, и у меня есть функция триггера для ОБНОВЛЕНИЯ некоторого столбца всякий раз, когда данные вставляются в эту таблицу.

Схема таблицы:

CREATE TABLE symbol_daily_ohlc (
 cdate date,
 open numeric(8,2),
 high numeric(8,2),
 low numeric(8,2),
 close numeric(8,2),
 sma8 numeric(8,2)
);

Функция запуска:

create or replace function update_sma8() RETURNS TRIGGER AS
$$
BEGIN
UPDATE symbol_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 symbol_daily_ohlc sec
)s where s.cdate = NEW.cdate  --The newly inserted cdate
 AND d.cdate = s.cdate;   
RETURN NULL;
END $$ language plpgsql;

Настройка триггера на столе:

CREATE TRIGGER trig_update_sma
AFTER INSERT ON symbol_daily_ohlc
FOR EACH ROW
EXECUTE PROCEDURE update_sma8();

Это хорошо работает для данной таблицы, т.е. symbol_daily_ohlc. Я хотел бы использовать одну и ту же триггерную функцию, т.е. update_sma8 (), которая будет использоваться с любой таблицей, имеющей одинаковую схему (я не хочу переписывать одну и ту же функцию для разных таблиц).

Я попытался заменить имя таблицы (например, symbol_daily_ohlc) на TG_TABLE_NAME, но это не сработало - из-за ошибок. Так как это сделать?

Ссылка: Функция триггера SQL для ОБНОВЛЕНИЯ дневной скользящей средней после INSERT

Ответы [ 2 ]

0 голосов
/ 12 января 2019

У вас может быть такая же процедура, которая выполняет и возвращает триггер для всех таблиц, но вы не можете иметь один и тот же триггер для всех ваших таблиц.

Вот блок, который динамически создает триггер с суффиксом имени таблицы (используя EXECUTE format)

DO $$
declare
tabs RECORD;
BEGIN
for tabs IN
(select table_name,table_schema
   from information_schema.tables where table_name 
   like 'symbol_daily_ohlc%' 
  -- and table_schema like '%'
) LOOP
EXECUTE format('CREATE TRIGGER check_update_%I
    AFTER INSERT ON %I.%I
    FOR EACH ROW
EXECUTE PROCEDURE update_sma8()',tabs.table_name,
 tabs.table_schema
,tabs.table_name);
END LOOP;
END $$;

А вот ваш триггер, который динамически принимает имя таблицы от TG_TABLE_NAME

create or replace function update_sma8() RETURNS TRIGGER AS
$$
 BEGIN

EXECUTE format ('UPDATE %I 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 %I sec
)s where s.cdate = %L  --The newly inserted cdate
     AND d.cdate = s.cdate',TG_TABLE_NAME,TG_TABLE_NAME,NEW.cdate);   
RETURN NULL;

END $$ language plpgsql;

Демо

Как и предполагали другие, не рекомендуется создавать несколько таблиц с одинаковой структурой. Вы должны рассмотреть возможность объединения их в одну таблицу.

0 голосов
/ 12 января 2019

Я думаю, вам, вероятно, придется использовать SQL для генерации SQL, а затем запустить сгенерированный SQL. Что-то вроде:

select CONCAT('create or replace function update_sma8() RETURNS TRIGGER AS
  $$
  BEGIN
  UPDATE ', table_name, '  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 ', table_name, '
  )s where s.cdate = NEW.cdate  --The newly inserted cdate
  AND d.cdate = s.cdate;   
  RETURN NULL;
  END $$ language plpgsql;
') from information_schema.tables

Но на самом деле вы должны принять во внимание совет Гордона (и мои наблюдения) и поместить все свои данные обратно в одну таблицу:

SELECT CONCAT('INSERT INTO all_hist SELECT ''', table_name, ''', t.* FROM ', table_name) FROM information_schema.tables

Это сгенерирует группу sqls, которая поместит все данные таблицы в all_hist, таблицу, которая должна иметь схему, идентичную другим тысячам, за исключением дополнительного столбца "символ" или чего-либо еще.

Вы можете использовать подобную уловку, чтобы создать себе набор представлений, чтобы воссоздать подход с тысячными таблицами, если вы действительно хотите ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...