PostgreSQL upsert 查询的问题

2024-03-25

我正在尝试通过更新或插入新记录来更新数据库投票用户表。该表定义如下:

  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)

这是我正在使用的查询。实际上,我对所有值都使用了参数,但出于测试目的,我将它们替换为我确信应该有效的值。用户名[电子邮件受保护] /cdn-cgi/l/email-protection exists.

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 '[email protected] /cdn-cgi/l/email-protection'
    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 '[email protected] /cdn-cgi/l/email-protection'

运行查询后获得的输出是:

INSERT 0 0

尽管它应该插入新值,因为数据库中尚不存在该行。当我仅使用 insert 子句手动插入行,然后执行上面所示的 upsert 查询时,它正确更新了该行。
我使用的是 PostgreSQL 版本 9.2.4。

我从另一个问题中得到了编写此查询的想法:
在 PostgreSQL 中重复更新时插入? https://stackoverflow.com/questions/1109061/insert-on-duplicate-update-postgresql

关于我可能做错了什么有什么想法吗?
关于如何实现我想做的事情有什么建议吗?


创建声明投票用户表:

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;

The UPDATE在第一个 CTE 中updated产生no row。这意味着,您不会得到NULL价值updated.id任何一个。当加入到updated, 你得到nothing, so no 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 '[email protected] /cdn-cgi/l/email-protection'
   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 '[email protected] /cdn-cgi/l/email-protection';

请注意,仍有很小的机会竞争条件在高并发负载下。此相关问题下的详细信息:
更新插入交易 https://stackoverflow.com/questions/17152860/upsert-with-a-transaction

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PostgreSQL upsert 查询的问题 的相关文章

  • INET6_ATON 的替代 MySQL 代码

    将旧的 INET ATON 值转换为新的二进制 INET6 ATON 值 无需 INET6 ATON INET6 NTOA 我们在表中已有数据 字段类型为UNSIGNED INT其中保存了使用以下命令创建的 IPv4 数据INET ATON
  • SQLAlchemy - 连接表关系上的 order_by

    我正在使用声明式 SQLAlchemy 并且有三个模型 Role Permission and RolePermission 在我的Role模型 我有以下内容 class Role Base name Column u NAME VARCH
  • 如何优化 postgres 查询

    我正在运行以下查询 SELECT fat FROM Table1 fat LEFT JOIN modo captura mc ON mc id fat modo captura id INNER JOIN loja lj ON lj id
  • 实体框架将本地数据添加到数据库中的列表

    我对实体框架相当陌生 我正在使用此方法来查询我的数据库 var context new StudioEntities var results context tblStudios Select u gt new u Standort u N
  • MySQL 偏移无限行

    我想构造一个查询 显示表中的所有结果 但从表的开头偏移 5 据我所知 MySQLLIMIT需要一个限制和一个偏移量 有什么办法可以做到这一点吗 来自MySQL LIMIT 手册 http dev mysql com doc refman 5
  • 有没有由 HTML + css + javascript 驱动的 sql 编辑器? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 语法高亮 sql代码格式 代码镜像 http codemirror net 会成功的 这太好了 非常容
  • 在 Microsoft Sql Server 2008R2 及更高版本上隐藏登录数据库 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 请任何人协助隐藏 sql server 2008R2 或更高版本上的可用数据库 我有一个新的登录用户 已映射到特定数据库 使用特定登录用户登录时 我可
  • 更新表并返回旧值和新值

    我正在编写一个 VB 应用程序 用于清理 DB2 数据库中的一些数据 在一些表中我想更新整个列 例如帐号列 我正在将所有帐号更改为从 1 开始 并在列表中向下递增 我希望能够返回旧帐号和新帐号 这样我就可以生成某种可以引用的报告 这样我就不
  • 将日期格式(在数据库或输出中)更改为 dd/mm/yyyy - PHP MySQL

    MySQL 将日期存储在我的数据库中 默认情况下 为 YYYY MM DD 我的日期的字段类型是 DATE 我不需要任何时间存储 有没有一种简单的方法可以默认更改它到 DD MM YYYY 我在两个不同的表中调用不同的日期 并且在我的任何代
  • php postgresql pdo 从标准输入复制

    COPY table name field1 field2 field3 FROM STDIN CSV 1 2 q w 3 4 a s 5 6 d 如何通过 PDO 执行此查询 Update 问题是 PDO 驱动程序将此查询作为语句执行 例
  • 通过一个表中的列更新另一表中的列

    我有两张桌子 A 和 B 两者都有一个共同的列 name 并通过列 id 相互链接 表A中的 name 列是空的 而表B中有数据 我的任务是用相应的id填充从表B到表A的该列中的所有数据 我正在使用以下查询 UPDATE A SET A n
  • 如何获取列中每个不同值的计数? [复制]

    这个问题在这里已经有答案了 我有一个名为 posts 的 SQL 表 如下所示 id category 1 3 2 1 3 4 4 2 5 1 6 1 7 2 每个类别编号对应一个类别 我将如何计算每个类别出现在帖子中的次数一条 SQL 查
  • sql/mysql 过滤器仅包含最大值

    我有一个像这样的结果集 ID name myvalue 1 A1 22 2 A2 22 3 A3 21 4 A4 33 5 A5 33 6 A6 10 7 A7 10 8 A8 10 9 A9 5 我想要的是仅包含包含可用的最高 myval
  • 创建用于插入、修改和删除的数据库触发器的正确​​语法是什么

    我有一个看起来像是 SQL Server 中数据库触发器的基本场景 但我遇到了一个问题 我有桌子Users 身份证 姓名 电话等 我有桌子用户历史记录 id user id 操作 字段 时间戳 我想要一个数据库触发器 可以随时插入 更新或删
  • 无法安装 psycopg2 Ubuntu

    试图为 django 项目准备好服务器 但我在设置 postgres 时遇到了一些问题 我正在遵循本指南 https jee appy blogspot com 2017 01 deply django with nginx html ht
  • 触发器以捕获服务器中的架构更改

    是否可以实现类似以下触发器的东西 CREATE TRIGGER tr AU ddl All Server ON DATABASE WITH EXECUTE AS self FOR DDL DATABASE LEVEL EVENTS AS D
  • android sqlite 如果不存在则创建表

    创建新表时遇到一点问题 当我使用 CREATE TABLE 命令时 我的新表按应有的方式形成 但是当我退出活动时 应用程序崩溃 并且我在 logcat 中得到一个表已存在 如果我使用 CREATE TABLE IF NOT EXISTS 则
  • 选择表中的人员并排除妻子,但合并他们的名字

    我有一张桌子Person PersonID FirstName LastName 1 John Doe 2 Jane Doe 3 NoSpouse Morales 4 Jonathan Brand 5 Shiela Wife And a R
  • 用户非超级管理员和大对象的 pg_dump

    我与非超级管理员的用户开始了导出数据库的长期职业生涯 但我发现了一个问题 在新版本的postgresql中只有超级管理员才能访问大对象 ERROR permission denied for large object 5141 没有办法做到
  • 如何在 typeorm 中使用 LEFT JOIN LATERAL?

    我想在 TypeOrm 中使用以下查询 但找不到将其转换为 TypeOrm 的方法 任何帮助表示赞赏 SELECT FROM blocked times bt LEFT JOIN LATERAL SELECT FROM bookings b

随机推荐