我有一個表,我需要upsert。如果該行已經存在,那麼我想更新並返回該行。如果該行尚不存在,那麼我需要插入並返回該行。通過下面的查詢,我得到了插入時返回的行,但沒有更新。需要從upsert返回的行
Table "main.message_account_seen"
Column | Type | Modifiers
----------------+--------------------------+-------------------------------------------------------------------
id | integer | not null default nextval('message_account_seen_id_seq'::regclass)
field_config_id | integer | not null
edit_stamp | timestamp with time zone | not null default now()
audit_stamp | timestamp with time zone |
message_id | integer | not null
account_id | integer |
這裏是sql。
with upsert as (
update message_account_seen set (message_id, account_id, field_config_id) = (1, 60, 980)
where message_id = 1 and account_id = 60 and field_config_id = 980 returning *
)
insert into message_account_seen (message_id, account_id, field_config_id)
select 1, 60, 980
where not exists (select message_id, account_id, field_config_id from upsert) returning *;
我不能做一個postgres函數,它需要在一個普通的sql查詢中處理。此外,沒有限制表的行唯一性,否則我會使用on conflict
。但是我願意放棄這個查詢,並在需要的時候使用其他的東西。
這些是我運行查詢時的結果,然後再次運行它。你可以在插入或首次運行時看到返回的行。但是,在後續運行的查詢中,我返回了0行。我知道它正在工作,因爲edit_stamp在時間上增加。這是好事。
# with upsert as (
update message_account_seen set (message_id, account_id, field_config_id) = (1, 60, 980)
where message_id = 1 and account_id = 60 and field_config_id = 980 returning *
)
insert into message_account_seen (message_id, account_id, field_config_id)
select 1, 60, 980
where not exists (select message_id, account_id, field_config_id from upsert) returning *;
id | field_config_id | edit_stamp | audit_stamp | message_id | account_id
--+-----------------+--------------------------------+-------------+------------+------------
38 | 980 | 09/27/2016 11:43:22.153908 MDT | | 1 | 60
(1 row)
INSERT 0 1
# with upsert as (
update message_account_seen set (message_id, account_id, field_config_id) = (1, 60, 980)
where message_id = 1 and account_id = 60 and field_config_id = 980 returning *
)
insert into message_account_seen (message_id, account_id, field_config_id)
select 1, 60, 980
where not exists (select message_id, account_id, field_config_id from upsert) returning *;
id | field_config_id | edit_stamp | audit_stamp | message_id | account_id
----+-----------------+------------+-------------+------------+------------
(0 rows)
INSERT 0 0
你使用的是什麼版本的postgres?另外,似乎'(message_id,account_id,field_config_id)'的組合是唯一的,正確的? – redneb
版本是9.5.3,組合是唯一的,但沒有唯一約束,我現在無法添加它。這會讓事情變得更容易。 – thepriebe
一個獨特的索引會讓思考變得更容易。另外,還不清楚你希望它做什麼更新:目前在你的代碼中,你正在爲3列分配他們已有的值,所以這將不起作用。 – redneb