Upserting with Postgresql
我有类似这样的表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | CREATE TABLE saldo ( id BIGINT NOT NULL, uid INTEGER, VALUE NUMERIC(12,2), currency CHARACTER(3) ); CREATE SEQUENCE saldo_id_seq START WITH 1 INCREMENT BY 1 NO MAXVALUE NO MINVALUE CACHE 1; ALTER TABLE ONLY saldo ALTER COLUMN id SET DEFAULT NEXTVAL('saldo_id_seq'::regclass); ALTER TABLE ONLY saldo ADD CONSTRAINT saldo_id_key UNIQUE (id); |
我想更新行如果存在或插入如果不存在,所以我在这里找到了一些有关upserting的信息。 这是我得到的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | $saldo = $Db->PREPARE(" WITH update_outcome AS( UPDATE saldo SET value=value+ :value WHERE uid=:uid AND currency=:currency ), insert_outcome AS ( INSERT INTO saldo (uid, value, currency) SELECT :uid2 AS uid, :value2 AS value, :currency2 AS currency WHERE NOT EXISTS (SELECT id FROM saldo WHERE uid= :uid3 AND currency= :currency3 LIMIT 1) )"); $saldo->bindParam(':uid', $uid, PDO::PARAM_INT); $saldo->bindParam(':value', $_SESSION['throw'], PDO::PARAM_STR, 8); $saldo->bindParam(':currency', $_SESSION['currency'], PDO::PARAM_STR, 3); $saldo->bindParam(':uid2', $uid, PDO::PARAM_INT); $saldo->bindParam(':value2', $_SESSION['throw'], PDO::PARAM_STR, 8); $saldo->bindParam(':currency2', $_SESSION['currency'], PDO::PARAM_STR, 3); $saldo->bindParam(':uid3', $uid, PDO::PARAM_INT); $saldo->bindParam(':currency3', $_SESSION['currency'], PDO::PARAM_STR, 3); $saldo->EXECUTE(); |
我改进了这个查询一次,但我仍然得到例外:
SQLSTATE [42601]:语法错误:7错误:"UPDATE"或其附近的语法错误
第3行:更新saldo
怎么了? 也许有更好的方法来解决这个问题?
重要提示:可能有几行使用相同的uid,但货币不同。
您需要"with"部分才能成为具有结果的正确查询。 UPDATE本身不返回结果,因此Postgres抱怨这一点。 链接下给出的示例使用UPDATE .... RETURNING in with query part来实现。 顺便说一下,你应该经常提到你正在使用的PG版本。 另外,看看这个。