我以前曾经这样做过,但在我盲目地重复一些我认为是黑客的事情之前,我在这里问一下。
我有 3 个表(为了清楚起见,省略了详细信息):
id bigserial (PK)
sku character varying(24)
name character varying(32)
...
Run Code Online (Sandbox Code Playgroud)
id bigserial (PK)
name cahracter varying(32)
...
Run Code Online (Sandbox Code Playgroud)
item_group_id bigint (FK -> inv_item_groups)
item_id bigint (FK -> inv_items)
Run Code Online (Sandbox Code Playgroud)
现在,在我的代码中,我有一个像这样的对象(以伪代码形式)
class ItemGroup
id:long
groupName:String
items:long[]
Run Code Online (Sandbox Code Playgroud)
并且这些对象是可以修改的,然后需要更新。由于我想保留密钥完整性,因此我需要该inv_item_group_members表(否则,我会使用其他解决方案)。
现在,我通常的做法是
DELETE FROM inv_item_group_members WHERE item_group_id = $1
-- where $1 is the object's id
Run Code Online (Sandbox Code Playgroud)
的,对于items对象中的每个
INSERT INTO inv_item_group_members (item_group_id, item_id) VALUES ($1, $2)
Run Code Online (Sandbox Code Playgroud)
有更好的解决方案吗?有哪些替代方案?我正在考虑一个 SQL 函数,但不太确定这里最好的方法是什么(我对 PGSQL 还不太有经验。)我已经阅读过有关可写 CTE 的内容,但它没有解决从其中删除元素时的情况数组(即删除关联)。
我找到了“UPSERT”命令的有效实现。到目前为止,效果很好。
WITH upsert AS (UPDATE inv_items_group_members
SET priority = $3
WHERE group_id = $1
AND item_id = $2
RETURNING *)
INSERT INTO inv_items_group_members
(group_id, item_id, priority)
SELECT $1, $2, $3 WHERE NOT EXISTS (SELECT * FROM upsert)
Run Code Online (Sandbox Code Playgroud)