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

在Postgresql函数中使用EXECUTE format分配变量时出现语法错误,sql,postgresql,triggers,plpgsql,Sql,Postgresql,Triggers,Plpgsql,我一直在尝试创建一个函数,该函数打算为声明的变量赋值,并根据该值采取相应的行动 我使用EXECUTE格式将值分配给cnt 但是,我得到以下错误: ERROR: syntax error at or near "(" LINE 7: cnt := EXECUTE format('SELECT count(*) FROM... 不确定它是否相关,但id是一个文本列,field1是一个枚举,field2也是一个文本列。这可能是SELECT语句中的问题吗 你知道我

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

我使用EXECUTE格式将值分配给cnt

但是,我得到以下错误:

ERROR:  syntax error at or near "("
LINE 7:         cnt := EXECUTE format('SELECT count(*) FROM...
不确定它是否相关,但id是一个文本列,field1是一个枚举,field2也是一个文本列。这可能是SELECT语句中的问题吗

你知道我会错过什么吗

我只想在cnt等于0时触发第二条语句

它可以重写为单个语句:

UPDATE table1 
SET field1 = ...
WHERE id = ...
  AND NOT EXISTS (SELECT * 
                  FROM table1 
                  WHERE field2 = ...
                     AND field1 != ... 
                     AND id != ...);
在触发器中使用它表明这是一种实现部分唯一性的尝试。如果是,则部分/过滤索引也是一个选项:

CREATE UNIQUE INDEX uq ON table1(id, field1) WHERE field2 = ....;
我只想在cnt等于0时触发第二条语句

它可以重写为单个语句:

UPDATE table1 
SET field1 = ...
WHERE id = ...
  AND NOT EXISTS (SELECT * 
                  FROM table1 
                  WHERE field2 = ...
                     AND field1 != ... 
                     AND id != ...);
在触发器中使用它表明这是一种实现部分唯一性的尝试。如果是,则部分/过滤索引也是一个选项:

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;

尽管@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;

我错过什么了吗?我看不出这些声明有任何动态。为什么要使用EXECUTE而不是按原样激发语句?@stickybit我只想在cnt等于0时激发第二个EXECUTE语句。这就是为什么我使用第一个EXECUTE。还有其他方法吗?我在问为什么要使用EXECUTE formatSELECT。。。不只是选择……在这种情况下,我如何将变量传递到没有格式的WHERE子句?只需编写它。。。其中field2=new.field2。。。变量可以在语句中用于值,但不能用于标识符,这时您需要动态SQL,但不能用于值。我遗漏了什么吗?我看不出这些声明有任何动态。为什么要使用EXECUTE而不是按原样激发语句?@stickybit我只想在cnt等于0时激发第二个EXECUTE语句。这就是为什么我使用第一个EXECUTE。还有其他方法吗?我在问为什么要使用EXECUTE formatSELECT。。。不只是选择……在这种情况下,我如何将变量传递到没有格式的WHERE子句?只需编写它。。。其中field2=new.field2。。。变量可以在语句中用于值,但不能用于标识符,这时您需要动态SQL,但不能用于值。如果没有唯一索引,该功能是否有效?是的,唯一索引是未来研究的补充。如果适用,则向上投票。如果没有唯一索引,该功能是否有效?是的,唯一索引是未来调查的附录(如果适用)