我试图在任何约束上触发 UPSERT,但似乎找不到类似于 ON CONFLICT ON CONSTRAINT (*)
的语法。我尝试使用案例来声明我的特定约束:
ON CONFLICT ON CONSTRAINT (
CASE "@Type"
WHEN 'user' THEN "Meta_User_Namespace"
WHEN 'device' THEN "Meta_Device_Namespace"
WHEN 'profile' THEN "Meta_UserProfile_Namespace"
WHEN 'group' THEN "Meta_Group_Namespace"
END
)
但我认为这不是一种合适的方式,而且这种语法似乎不起作用。
我该如何解决?我基本上有这个 SP 可以处理各种表类型的元数据。我认为只有 4 个具有唯一索引的列就足够了,而不是 4 个单独的表链接到我的元数据。请注意,此 SP 充当 UPSERT。
CREATE OR REPLACE FUNCTION "SetMeta" (
"@Type" VARCHAR(10),
"@ID" UUID,
"@Namespace" VARCHAR(50),
"@Data" JSONB
)
RETURNS void AS
$func$
BEGIN
INSERT INTO
"Meta" AS um (
"ID",
"UserID",
"UserProfileID",
"DeviceID",
"Namespace",
"Data"
)
VALUES (
UUID_GENERATE_V4(),
CASE "@Type" WHEN 'user' THEN "@UserID" ELSE null END,
CASE "@Type" WHEN 'profile' THEN "@UserProfileID" ELSE null END,
CASE "@Type" WHEN 'device' THEN "@DeviceID" ELSE null END,
CASE "@Type" WHEN 'group' THEN "@Namespace" ELSE null END,
"@Namespace",
"@Data"
)
ON CONFLICT ON CONSTRAINT (
CASE "@Type"
WHEN 'user' THEN "Meta_User_Namespace"
WHEN 'device' THEN "Meta_Device_Namespace"
WHEN 'profile' THEN "Meta_UserProfile_Namespace"
WHEN 'group' THEN "Meta_Group_Namespace"
END
)
DO UPDATE SET
"Data" = "@Data",
"Updated" = NOW()
WHERE
(
um."UserID" = "@UserID" OR
um."UserProfileID" = "@UserProfileID" OR
um."DeviceID" = "@DeviceID" OR
um."GroupID" = "@GroupID"
) AND
um."Namespace" = "@Namespace";
END;
$func$ LANGUAGE PLPGSQL;
最佳答案
I'm trying to trigger an UPSERT on any constraint but can't seem to find a syntax that would be similar to
ON CONFLICT ON CONSTRAINT (*)
.
只需省略可选的冲突目标子句 ON CONSTRAINT
以触发任何独特的违规行为:
INSERT INTO "Meta" AS um ( ... )
VALUES ( ... )
<b>ON CONFLICT</b> -- that's all!
DO UPDATE SET ...
Details in the manual on INSERT
.
我会提供您函数的工作版本,但您发布的内容不一致。 "@UserID"
未定义等
并且在 Postgres 中到处使用简单的、不带引号的、合法的、小写的标识符,比如 @a_horse already suggested . (包括 SQL 和 PL/pgSQL 函数中的参数和变量名称。)
关于postgresql - ON CONFLICT ON CONSTRAINT 从任何约束触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44508178/