在 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;
我一直在尝试创建一个函数,旨在为声明的变量赋值,并根据该值采取相应的行动。
我使用 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;