簡體   English   中英

在插入 PostgreSQL 之前觸發,某些列除外

[英]Trigger before insert in PostgreSQL and except some columns

我正在嘗試為我的表編寫觸發器。 該表有 50 列,其中 3 列是timestamp類型。 將來我將插入新行,它們可以與現有行重復,因此我需要計算每行的 hash。 我的想法是在每次插入中計算行的 hash 並檢查它是否存在,這就是我編寫觸發器的原因。 我想計算 hash 並將其寫入我的主表的最后一列(我在創建表時創建了它)。 我有一個問題 - 我需要計算 hash 而不是整行,我不應該使用時間戳類型的 3 列(對於行的散列,我應該排除 3 列)。

我剛剛開始這樣做並遇到了一個問題 - 我不知道如何排除這些列進行散列。

CREATE OR REPLACE FUNCTION check_row_hash() RETURNS TRIGGER AS $mergetrigger$
BEGIN
    -- As I understand I can get row's data using NEW.column_name
    -- But how to exclude 3 columns and get others dynamically ??
    -- I can use these script for getting needed columns 
 
       select column_name
            from user_tab_columns
       where table_name = 'main_table' 
            data_type not in ('date', 'timestamp')
    
    -- But what should i do next?

END;


CREATE TRIGGER check_inserted_row
    BEFORE INSERT ON main_table
    for each row
    EXECUTE PROCEDURE check_row_hash();

如果列名始終相同,則通過 JSON 值進行重定向會使這有點動態:

CREATE OR REPLACE FUNCTION check_row_hash() 
RETURNS TRIGGER AS $mergetrigger$
declare
  l_row_data jsonb;
  l_row_text text;
BEGIN
  l_row_data := to_jsonb(new) - 'updated_at' - 'created_at'; 
  select string_agg(t.v, ',')
    into l_row_text
  from jsonb_each_text(l_row_data) as t(k,v);
  
  new.hash_value := md5(l_row_text::text);
  return new;  
END;

has_value是目標表中應該存儲生成的 hash 的列(我使用了 MD5 哈希)。

您可以通過使用以下內容查詢pg_attribute來使其完全動態化:

select attname
from pg_attribute
where attnum > 0
and not attisdropped
and atttypid in ('date'::regtype, 'timestamp'::regtype)
and attrelid = TG_RELID;

然后使用該查詢中的列列表從 JSONB 值中刪除鍵。

暫無
暫無

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

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