来自触发功能的错误:ERROR:列不存在

时间:2019-06-02 14:34:09

标签: sql postgresql plpgsql database-trigger

我创建了一个触发器:

CREATE OR REPLACE FUNCTION public.delete_user() 
 RETURNS TRIGGER AS $func$
BEGIN
    EXECUTE format('UPDATE public.user SET %I = %L WHERE state = %L', 
    "state", "active", "deleted");
END;
$func$ LANGUAGE plpgsql;

 CREATE TRIGGER deleted_user
    AFTER UPDATE ON public.user
      FOR EACH ROW
      WHEN (OLD.state IS DISTINCT FROM NEW.state)
      EXECUTE PROCEDURE delete_user();

比跑步后:

update public.user set state = 'active' where fullname = '1234'

我收到错误消息:

> ERROR:  column "state" does not exist
> LINE 1: ...UPDATE public.user SET %I = %L WHERE state = %L', "state", "...
>                                                              ^
> QUERY:  SELECT format('UPDATE public.user SET %I = %L WHERE state = %L', "state", "active", "deleted")
> CONTEXT:  PL/pgSQL function delete_user() line 3 at EXECUTE SQL state: 42703

这是在用户表中定义状态的方式:

state text COLLATE pg_catalog."default" NOT NULL DEFAULT 'active'::text,

我是Postgres的新手,所以我想这是语法错误?

1 个答案:

答案 0 :(得分:0)

这将起作用

CREATE OR REPLACE FUNCTION public.delete_user() 
  RETURNS TRIGGER AS
$func$
BEGIN
  EXECUTE format('UPDATE public.user SET %I = %L WHERE state = %L', 
  'state', 'active', 'deleted');

  RETURN NULL;  -- or OLD (for AFTER trigger)
END
$func$ LANGUAGE plpgsql;

字符串文字的单引号而不是双引号(用于标识符)。为此,您不需要动态SQL,并且可以简化:

CREATE OR REPLACE FUNCTION public.delete_user() 
  RETURNS TRIGGER AS
$func$
BEGIN
  UPDATE public.user SET state = 'active' WHERE state = 'deleted';

  RETURN NULL;
END
$func$  LANGUAGE plpgsql;

虽然语法现在可以使用,但它会导致无限循环,并且按原样没有意义。我不确定你要去哪里。

相关:

在旁边:public.user起作用,因为架构限定消除了歧义,但是裸表名称user始终需要双引号:"user" 从不 使用保留字如user作为标识符。