簡體   English   中英

PostgreSQL 相同的觸發器函數將 INSERT 上的 UPDATE 更新到不同的表中(使用相同的模式)

[英]PostgreSQL same trigger function to UPDATE on INSERT into different tables (using the same schema)

我有 100 個具有相同架構的表,並且我有一個觸發器函數可以在數據插入該表時更新某些列。

表架構:

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() 與具有相同模式的任何表一起使用(我不想為不同的表重寫相同的函數)。

我嘗試用 TG_TABLE_NAME 替換表名(即 symbol_daily_ohlc),但這不起作用 - 拋出錯誤。 那么怎么做呢?

參考: 在插入時更新每日移動平均線的 SQL 觸發器函數

您可以使用相同的過程為所有表執行並返回觸發器,但不能為所有表使用相同的觸發器。

這是一個動態創建帶有表名后綴的觸發器的塊(使用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;

演示

正如其他人所建議的那樣,擁有多個具有相同結構的表並不是一個好主意。 您應該考慮將它們合並到一張表中。

我認為您可能必須使用 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

但實際上,您應該考慮 Gordon 的建議(以及我的后續行動)並將所有數據放回一張表中:

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

這將生成一堆將所有表數據放入 all_hist 的 sql,該表應該與其他數千個表具有相同的架構,除了附加列“符號”或其他任何內容。

如果你真的想要,你可以使用類似的技巧為自己創建一堆視圖來重新創建千表方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM