【问题标题】:How to get the generated id from an insert to a postgres foreign table?如何从插入到 postgres 外部表中获取生成的 id?
【发布时间】:2021-06-09 10:55:47
【问题描述】:

我使用的是 PostgreSQL 版本 13.2,我需要插入一个外部表(Postgres 也是),它有一个序列生成的 id,从外部表返回生成的 id。

我添加了“postgres_fdw”扩展,创建了服务器和用户映射。

当我这样做时:

INSERT INTO public.remote_users (name) VALUES ('username') RETURNING id;

使用以下外部表定义:

CREATE FOREIGN TABLE public.remote_users
(
    id bigint,
    name character varying(20)
)
SERVER remote
OPTIONS (schema_name 'public', table_name 'users');

我收到一条错误消息,指出 id 不能为空(因为 fdw 使用 'id' 列构建远程插入语句并且它具有非空约束)。

错误:关系“用户”的“id”列中的空值违反非空约束 详细信息:失败行包含(空,用户名)。 上下文:远程 SQL 命令:INSERT INTO public.users(id, name) VALUES ($1, $2) RETURNING id SQL状态:23502

使用这个外部表定义:

CREATE FOREIGN TABLE public.remote_users
(
    name character varying(20)
)
SERVER remote
OPTIONS (schema_name 'public', table_name 'users');

我收到一条错误消息,提示“列“id”不存在”。

有什么方法可以使INSERT INTO public.remote_users (name) VALUES ('username') RETURNING id; 语句起作用?

【问题讨论】:

  • 我认为您必须在外部表定义中包含 ID

标签: postgresql postgres-fdw sql-returning


【解决方案1】:

我找到了一种解决方法(尽管它不是我想要的解决方案)。

在远程表上创建一个插入前触发器来检查空 id 并替换为序列值,我可以使用插入(使用指定 id 列的外部表定义)。

更明确...

远程:

CREATE FUNCTION public.users_insert()
    RETURNS trigger
    LANGUAGE 'plpgsql'
AS $BODY$
BEGIN
  IF (new.id IS NULL) THEN
     new.id = nextval('public.users_id_seq'::regclass);
  END IF;
  RETURN new;
END;
$BODY$;

CREATE TRIGGER insert_tr
    BEFORE INSERT
    ON public.users
    FOR EACH ROW
    EXECUTE PROCEDURE public.users_insert();

【讨论】:

  • ALTER TABLE [TableName] ADD DEFAULT nextval('public.users_id_seq') FOR [column_name]. 默认值不一定是常数。
【解决方案2】:

试试这个查询来创建表

CREATE FOREIGN TABLE public.remote_users
(
    id serial,
    name character varying(20)
)
SERVER remote
OPTIONS (schema_name 'public', table_name 'users');

【讨论】:

  • 感谢@IndunilUdayangana 的意见,但它不起作用,因为它将在本地数据库中创建一个序列并使用此序列而不是远程数据库中的序列。
猜你喜欢
  • 1970-01-01
  • 2011-07-21
  • 2010-11-23
  • 1970-01-01
  • 2015-09-04
  • 1970-01-01
  • 2013-10-06
  • 2019-08-04
  • 2011-04-03
相关资源
最近更新 更多