首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >创建postgresql触发器函数以为每个insert语句创建修改条目时遇到的问题

创建postgresql触发器函数以为每个insert语句创建修改条目时遇到的问题
EN

Stack Overflow用户
提问于 2021-03-17 09:39:24
回答 1查看 81关注 0票数 2

所以我在这里的第一个问题,让我描述一下设置:我有一个postgressql数据库(版本12),其中有一个表公会(包含一个内部guild_id和一些其他信息)。guild_id用作许多其他表的外键,如teams表。现在,如果一个团队被插入到另一个行会的团队中,那么使用guild_id = 1的行会,我想要一个触发器函数来创建相同的团队条目,但是现在使用一个修改的guild_id (现在应该是1)。

有关自动取款机的定义:

代码语言:javascript
复制
create table if not exists bot.guilds
(
    guild_id         bigserial not null
        constraint guilds_pk
            primary key,
    guild_dc_id      bigint    not null,
);
create table if not exists bot.teams
(
    team_id       bigserial   not null
        constraint teams_pk
            primary key,
    guild_id      bigserial      not null
        constraint teams_guilds_guild_id_fk
            references bot.guilds
            on delete cascade,
    team_name     varchar(20) not null,
    team_nickname varchar(10) not null
);

alter table bot.teams
    owner to postgres;

create unique index if not exists teams_guild_id_team_name_uindex
    on bot.teams (guild_id, team_name);

create unique index if not exists teams_guild_id_team_nickname_uindex
    on bot.teams (guild_id, team_nickname);

create function duplicate_teams() returns trigger
    language plpgsql
as
$$
BEGIN
    INSERT INTO bot.teams VALUES(1,NEW."team_name",NEW."team_nickname");
RETURN NEW;
END;
$$;

create trigger duplicate_team
    after insert
    on bot.teams
    for each row
execute procedure bot.duplicate_teams();

如果我现在尝试在团队中插入一个新的行(INSERT INTO bot.teams ("guild_id", "team_name", "team_nickname")VALUES (14, 'test2', 'test2');),我会得到以下错误消息(orginial德语,由我翻译成英语):

代码语言:javascript
复制
[42804] ERROR: Column »guild_id« has type integer, but the expression has the type character varying
HINT: You have to rewrite the expression or cast the value.
WITH: PL/pgSQL-function duplicate_teams() row 3 in SQL-expressions

执行后,原始插入语句既不在表中,也不在副本中。我试图将行会id的值转换为串行、整数、大串行。但每次都是同样的错误。我对错误消息部分和“有类型的字符变化”感到困惑。

所以我的问题是:

  1. 我的理解是,这个错误是由触发器引起的,对吗?而由于触发器中的错误,原来的insert语句也不能工作吗?
  2. 为什么即使有一个演员,这种类型也很流行呢?
  3. 代码中的错误在哪里?

我试图寻找这个问题,但没有发现有任何帮助。任何提示都欢迎。谢谢你的帮助!

编辑: @Lukas的答案有效,但现在我得到了一个新错误:

代码语言:javascript
复制
[23505] ERROR: doubled key value violates unique-constraint »teams_guild_id_team_name_uindex«
Detail: Key»(guild_id, team_name)=(1, test3)« exists already.
WHERE: SQL-Statement»INSERT INTO bot.teams(guild_id, team_name, team_nickname)  VALUES(1,NEW."team_name",NEW."team_nickname")«
PL/pgSQL-Function duplicate_teams() row 3 in SQL-Statement
SQL-Statment »INSERT INTO bot.teams(guild_id, team_name, team_nickname)  VALUES(1,NEW."team_name",NEW."team_nickname")«
PL/pgSQL-Function duplicate_teams() row 3 in SQL-Statement

但表中只包含"3,11,TeamUtils,TU“.

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-17 10:02:13

bot.teams有四列:team_idguild_id (两种数值数据类型)、team_nameteam_nickname (都是varchars)。在函数定义中的INSERT语句中,只提供三个值,而不提供与特定列的关联。默认情况是按顺序插入它们,这会将1分配给team_id,(关键是)将NEW."team_name"分配给guild_id,因此插入失败时会出现类型不匹配错误。

指定

代码语言:javascript
复制
INSERT INTO bot.teams(guild_id, team_name, team_nickname)  VALUES(1,NEW."team_name",NEW."team_nickname");

在你的职能中应该解决你的问题

回答你的其他问题:

  1. INSERT语句正在事务中执行,触发器中的失败将导致整个事务被中止并回滚,因此您也看不到插入到表中的原始行。
  2. 类型没有偏离转换,而是插入了错误的值才导致数据类型不匹配。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66670457

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档