enz*_*nzo 3 sql postgresql upsert common-table-expression postgresql-9.2
我正在尝试通过更新或在vote_user_table中插入新记录来更新数据库.该表定义如下:
Column | Type | Modifiers
-----------+---------+--------------------------------------------------------------
id | integer | not null default nextval('vote_user_table_id_seq'::regclass)
review_id | integer | not null
user_id | integer | not null
positive | boolean | default false
negative | boolean | default false
Indexes:
"vote_user_table_pkey" PRIMARY KEY, btree (id)
Run Code Online (Sandbox Code Playgroud)
这是我正在使用的查询.我实际上正在为所有值使用参数,但出于测试目的,我将它们替换为我确定应该工作的值.用户名aaa@aaa.com存在.
WITH updated AS (
UPDATE vote_user_table
SET
positive = 'true',
negative = 'false'
FROM usuario
WHERE
review_id = 6 AND
user_id = usuario.id AND
usuario.username ILIKE 'aaa@aaa.com'
RETURNING vote_user_table.id
)
INSERT INTO vote_user_table
(review_id, user_id, positive, negative)
SELECT 6, usuario.id, 'true', 'false'
FROM usuario, updated
WHERE
updated.id IS NULL AND
usuario.username ILIKE 'aaa@aaa.com'
Run Code Online (Sandbox Code Playgroud)
运行查询后得到的输出是:
INSERT 0 0
Run Code Online (Sandbox Code Playgroud)
虽然它应该插入新值,因为该行尚不存在于数据库中.当我手动插入一行,仅使用insert子句,然后执行上面显示的upsert查询时,它正确地更新了行.
我正在使用PostgreSQL版本9.2.4.
我想到了从另一个问题编写这个查询:
插入,在PostgreSQL中重复更新?
关于我可能做错什么的任何想法?
关于如何实现我想做的任何建议?
为vote_user_table创建语句:
CREATE TABLE vote_user_table (
id integer NOT NULL,
review_id integer NOT NULL,
user_id integer NOT NULL,
positive boolean DEFAULT false,
negative boolean DEFAULT false
);
CREATE SEQUENCE vote_user_table_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE vote_user_table_id_seq OWNED BY vote_user_table.id;
Run Code Online (Sandbox Code Playgroud)
第UPDATE一个CTE中没有updated产生任何行.这意味着,您没有得到任何NULL值updated.id.加入时updated,你什么也得不到,所以也没有INSERT.
应该与NOT EXISTS:
WITH updated AS (
UPDATE vote_user_table v
SET positive = TRUE -- use booleann values ..
,negative = FALSE -- .. instead of quoted string literals
FROM usuario u
WHERE v.review_id = 6 -- guessing origin
AND v.user_id = u.id
AND u.username ILIKE 'aaa@aaa.com'
RETURNING v.id
)
INSERT INTO vote_user_table (review_id, user_id, positive, negative)
SELECT 6, u.id, TRUE, FALSE
FROM usuario u
WHERE NOT EXISTS (SELECT 1 FROM updated)
AND u.username ILIKE 'aaa@aaa.com';Run Code Online (Sandbox Code Playgroud)
请注意,在严重的并发负载下,竞争条件仍然很小.此相关问题下的详细信息:
使用事务进行Upsert
| 归档时间: |
|
| 查看次数: |
1613 次 |
| 最近记录: |