我试着写一篇文章:
DROP FUNCTION IF EXISTS upsert_post;
CREATE OR REPLACE FUNCTION upsert_post(
title text,
content text,
short_id text DEFAULT NULL,
image text DEFAULT NULL,
status post_status DEFAULT 'draft',
updated_at timestamptz DEFAULT NULL,
published_at timestamptz DEFAULT NULL,
created_at timestamptz DEFAULT NULL
)
RETURNS SETOF posts
AS $$
DECLARE
post_id uuid;
BEGIN
-- Get the id based on the provided short_id
SELECT id INTO post_id FROM posts as p
WHERE p.short_id = upsert_post.short_id;
-- Upsert the post and return the changed row
RETURN QUERY
INSERT INTO posts as i (
id,
status,
title,
content,
image,
updated_at,
published_at,
created_at
)
VALUES (
COALESCE(post_id, uuid_generate_v4()),
upsert_post.status,
upsert_post.title,
upsert_post.content,
upsert_post.image,
COALESCE(upsert_post.updated_at, now()),
COALESCE(upsert_post.published_at, now()),
COALESCE(upsert_post.created_at, now())
)
ON CONFLICT (id, updated_at) DO UPDATE
SET
title = EXCLUDED.title,
content = EXCLUDED.content,
image = COALESCE(EXCLUDED.image, i.image),
updated_at = COALESCE(EXCLUDED.updated_at, i.updated_at),
published_at = COALESCE(EXCLUDED.published_at, i.published_at),
created_at = COALESCE(EXCLUDED.created_at, i.created_at)
RETURNING *;
END;
$$ LANGUAGE plpgsql;
但我得到了错误:
{
code: '42702',
details: 'It could refer to either a PL/pgSQL variable or a table column.',
hint: null,
message: 'column reference "updated_at" is ambiguous'
}
我尽可能地使用化名。我怎样才能在不使用前缀i_
或类似的东西重命名我的upsert_post
参数的情况下使其工作?
J型
2条答案
按热度按时间rbl8hiat1#
我需要熟练的功能,作为用户类型和功能提供和创建表也将有很大帮助
简而言之,永远不要像列名那样命名变量,这样postgres就不会有区分它们的问题了
short_id背后的想法我只能猜测。但我认为你也应该输入它,当插入一个新的行
| 地位|标题|内容|短ID|影像|更新_at|发表于|创建于| created_at |
| - -----|- -----|- -----|- -----|- -----|- -----|- -----|- -----| ------------ |
| 吃水|一个|B|联系我们|D级|2023-06-25 18:50:17.61884+01| 2023-06-25 18:50:17.61884+01| 2023-06-25 18:50:17.61884+01| 2023-06-25 18:50:17.61884+01 |
fiddle
2izufjch2#
这里的问题是输入参数与
ON CONFLICT
参数冲突。我很惊讶人们是如何毫无理由地冷漠地否决你的帖子的。我终于找到了三个真实的的答案。
1. #variable_conflict
Postgres有三个变量可用于此用例:
但我得到了它的工作感谢上面提供的变量替换文档:
2.论约束冲突
我上面代码的问题是
ON CONFLICT
不允许使用别名。如果你知道一个方法,请让我知道。否则,我只是简单地使用了复合约束的名称ON CONSTRAINT
。编辑:也可以在schema中任意命名约束:
3.创建子函数
基本上,你可以创建一个函数
_upsert_post()
,它接受前缀参数。然后将你的非前缀参数传入这个函数:upsert_post
说你必须使用
prefixes
是不正确的。在我的例子中,用户必须更改前端代码,以使用与后端代码不同的参数。这对团队来说可能很重要。或者,您可以限定不明确的引用以使其清晰。
这是我写这篇文章的目的,我觉得很清楚。你不需要我的完整模式来理解这个问题。一旦有人否决了一个帖子,其他人就会认为这不是一个有效的问题。请多加留意。
谢谢
J型