返回的行结构与触发表的结构不匹配如何解决?

问题描述 投票:0回答:2

我已将 varchar 数据类型的事务表列的长度从 50 更改为 100。一旦我更改了列的长度..来自父表的触发器开始失败..一旦我删除并创建触发器,从主表函数中删除,一切正常.. 不确定问题是什么.. 有什么理由吗?

Detail: Returned type character varying(50) does not match expected type character varying(100) in column 15.

CREATE FUNCTION customer_delete_master()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF 
     AS $BODY$

DECLARE
    r customer%rowtype;
BEGIN
    DELETE FROM ONLY customer where customer_id = new.customer_id returning * into r;
    RETURN r;
end;

$BODY$;

更新1:

CREATE TABLE customer
(
    customer_id character varying(10),
    firstname character varying(100),
    lastname character varying(50),
    CONSTRAINT customer_pkey PRIMARY KEY (customer_id)
);

CREATE TRIGGER after_insert_customer_trigger
    AFTER INSERT
    ON customer
    FOR EACH ROW
    EXECUTE PROCEDURE customer_delete_master();
sql postgresql database-trigger
2个回答
1
投票

每当更改具有触发器和视图等依赖对象的表时,都应该重新编译依赖对象。这是因为数据库引擎直接从缓存访问依赖对象的定义。 例如,对于触发器,可以在更改父表之前和之后禁用和启用它们。或者您可以再次执行 alter 触发器。

禁用:

ALTER TABLE mytable DISABLE TRIGGER mytrigger;

启用:

ALTER TABLE mytable ENABLE TRIGGER mytrigger;

0
投票

我创建了

person
表,如下所示:

CREATE TABLE person (
  id INTEGER,
  name VARCHAR(20),
  age INTEGER
);

然后,我创建了

my_func()
,它返回记录
ROW(1,'John'::VARCHAR,27)
,如下所示:

CREATE FUNCTION my_func() RETURNS trigger
AS $$
BEGIN
  RETURN ROW(1,'John'::VARCHAR,27);
END;  -- ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
$$ LANGUAGE plpgsql;

然后,我创建了

my_t
触发器,如下所示:

CREATE TRIGGER my_t BEFORE INSERT OR UPDATE OR DELETE ON person
FOR EACH ROW EXECUTE FUNCTION my_func();

最后,向

person
表插入一行得到了同样的错误,如下所示:

postgres=# INSERT INTO person (id, name, age) VALUES (NULL, NULL, NULL);
ERROR:  returned row structure does not match the structure of the triggering table
DETAIL:  Returned type character varying does not match expected type character varying(20) in co
lumn 2.
CONTEXT:  PL/pgSQL function my_func() during function exit

所以,我将

::VARCHAR
替换为
::VARCHAR(20)
,如下所示:

CREATE FUNCTION my_func() RETURNS trigger
AS $$
BEGIN
  RETURN ROW(1,'John'::VARCHAR(20),27);
END;              -- ↑ ↑ ↑ ↑ ↑ ↑ ↑
$$ LANGUAGE plpgsql;

然后,我可以向

person
表插入一行,不会出现错误,如下所示:

postgres=# INSERT INTO person (id, name, age) VALUES (NULL, NULL, NULL);
INSERT 0 1
postgres=# SELECT * FROM person;
 id | name | age
----+------+-----
  1 | John |  27
(1 row)
© www.soinside.com 2019 - 2024. All rights reserved.