如何在触发器函数中将 NEW.* 传递给 EXECUTE

Ben*_*min 1 postgresql triggers dynamic-sql plpgsql

我有一个简单的任务是将巨大的 MD5 值插入到表(分区表)中,并创建了一个触发器和一个触发器函数来代替INSERT操作。在函数中,我检查了前两个字符NEW.md5以确定应插入哪个表。

DECLARE
  tb text;
BEGIN
  IF TG_OP = 'INSERT' THEN
    tb = 'samples_' || left(NEW.md5, 2);
    EXECUTE(format('INSERT INTO %s VALUES (%s);', tb, NEW.*)); <- WRONG
  END IF;
  RETURN NULL;
END;
Run Code Online (Sandbox Code Playgroud)

问题是如何连接NEW.*到SQL语句中?

Erw*_*ter 5

最好使用USING以下子句EXECUTE

CREATE FUNCTION foo ()
  RETURNS trigger
  LANGUAGE plpgsql AS
$func$
BEGIN
  IF TG_OP = 'INSERT' THEN
     EXECUTE format('INSERT INTO %I SELECT $1.*'
                  , 'samples_' || left(NEW.md5, 2);
     USING NEW;
  END IF;
  RETURN NULL;
END
$func$;
Run Code Online (Sandbox Code Playgroud)

EXECUTE不需要括号。
而且您知道标识符会折叠为小写,除非在必要时引用:格式说明符%I而不是%sfor format()- 这也可以防止 SQL 注入尝试。

更多细节: