在 Postgresql 函数中使用 EXECUTE 格式分配变量时出现语法错误

Syntax error while using EXECUTE format in Postgresql Function to assign variable

我一直在尝试创建一个函数,旨在为声明的变量赋值,并根据该值采取相应的行动。

我使用 EXECUTE format(<SQL statement>) 将值分配给 cnt

CREATE OR REPLACE FUNCTION my_function() RETURNS TRIGGER AS $$ 
DECLARE 
    cnt bigint;
BEGIN 
    IF NEW.field1 = 'DECLINED' THEN 
        cnt := EXECUTE format('SELECT count(*) FROM table1 WHERE field2 =  AND field1 !=  AND id != ;') USING NEW.field2, NEW.field1, NEW.id INTO cnt;
        IF cnt = 0 THEN
             EXECUTE format('UPDATE table1 SET field1 = %1$s WHERE id = ') USING 'DECLINED', NEW.field2;
         END IF;
    END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER my_trigger BEFORE 
UPDATE OF field1 ON table1 FOR EACH ROW WHEN (NEW.field1 = 'DECLINED') EXECUTE FUNCTION my_function();

但是,我收到以下错误:

ERROR:  syntax error at or near "("
LINE 7:         cnt := EXECUTE format('SELECT count(*) FROM...

不确定是否相关,但 id 是一个文本列,field1 是一个 ENUM,field2 也是一个文本列。这可能是 SELECT 语句中的问题吗?

有什么我可能遗漏的想法吗?

I only want to fire the second statement if cnt equals to 0

它可以改写为单个语句:

UPDATE table1 
SET field1 = ...
WHERE id = ...
  AND NOT EXISTS (SELECT * 
                  FROM table1 
                  WHERE field2 = ...
                     AND field1 != ... 
                     AND id != ...);

在trigger中使用,说明这是实现部分唯一性的尝试。如果是这样,那么 partial/filtered 索引也是一个选项:

CREATE UNIQUE INDEX uq ON table1(id, field1) WHERE field2 = ....;

尽管@Lukasz 解决方案也可能有效。我最终在问题

的评论中使用了@stickybit 建议的实现

答案:

CREATE OR REPLACE FUNCTION my_function() RETURNS TRIGGER AS $$ 
DECLARE 
    cnt bigint;
BEGIN 
    IF NEW.field1 = 'DECLINED' THEN 
        cnt := ('SELECT count(*) FROM table1 WHERE field2 = NEW.field2 AND field1 != NEW.field1 AND id != NEW.id;')
        IF cnt = 0 THEN
             'UPDATE table1 SET field1 = 'DECLINED' WHERE id = NEW.field2';
         END IF;
    END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;