PostgreSQL -- 使用 CTE INSERT ID 加入 UNNEST 输出 -- INSERT 多对多

PostgreSQL -- JOIN UNNEST output with CTE INSERT ID -- INSERT many to many

在 PostgreSQL 函数中,是否可以将 UNNEST 的结果(函数输入的整数数组)与 CTE INSERT 返回的 ID 连接起来?

我有像这样的 PostgreSQL 表:

CREATE TABLE public.message (
    id SERIAL PRIMARY KEY,
    content TEXT
);

CREATE TABLE public.message_tag (
    id SERIAL PRIMARY KEY,
    message_id INTEGER NOT NULL CONSTRAINT message_tag_message_id_fkey REFERENCES public.message(id) ON DELETE CASCADE,
    tag_id INTEGER NOT NULL CONSTRAINT message_tag_tag_id_fkey REFERENCES public.tag(id) ON DELETE CASCADE
);

我想创建一个 PostgreSQL 函数,它接收 content 的输入和 tag_id 的数组。这是针对石墨的。我想在一个函数中完成所有工作,所以我得到了一个突变。

这是我到目前为止得到的。我不知道如何通过 CTE 返回的 ID 加入 UNNEST

CREATE FUNCTION public.create_message(content text, tags Int[])
RETURNS public.message
AS $$

-- insert to get primary key of message, for many to many message_id
WITH moved_rows AS (
  INSERT INTO public.message (content)
  RETURNING *;
)

-- many to many relation
INSERT INTO public.message_tag
SELECT moved_rows.id as message_id, tagInput.tag_id  FROM moved_rows, UNNEST(tags) as tagInput;
RETURNING *

$$ LANGUAGE sql VOLATILE STRICT;

您离目标不远了:

  • CTE 中的分号位置错误
  • 第一个 INSERT 语句缺少 SELECTVALUES 子句来指定 应插入什么
  • INSERTtag_message 应该指定要插入的列(特别是如果你有不必要的序列号 id
  • 您已经为 UNNEST 调用指定了关系别名,但是 none 为列 tag_id
  • 您的函数是 RETURNING 一组 message_tag 行,但被指定为 return 单个 message

要解决这些问题:

CREATE FUNCTION public.create_message(content text, tags Int[])
RETURNS public.message
AS $$

-- insert to get primary key of message, for many to many message_id
WITH moved_rows AS (
  INSERT INTO public.message (content)
  VALUES ()
  RETURNING *
),
-- many to many relation
_ AS (
INSERT INTO public.message_tag (message_id, tag_id)
SELECT moved_rows.id, tagInput.tag_id
FROM moved_rows, UNNEST() as tagInput(tag_id)
)
TABLE moved_rows;

$$ LANGUAGE sql VOLATILE STRICT;

(Online demo)