仅当行不存在时才在 PL/pgSQL 中运行 SQL 语句

2023-12-11

我想在 Postgres 9.6 的 PL/pgSQL 函数中做这样的事情:

INSERT INTO table1 (id, value) VALUES (1, 'a') ON CONFLICT DO NOTHING;
--- If the above statement didn't insert a new row
---   because id of 1 already existed, 
---   then run the following statements

INSERT INTO table2 (table1_id, value) VALUES (1, 'a');
UPDATE table3 set (table1_id, time) = (1, now());

但是,我不知道如何确定是否是第一个INSERT实际上插入了一个新行,或者是否ON CONFLICT DO NOTHING已完成。

我可以做一个SELECT在函数的开头查看是否有一条记录id1 存在于table1在运行所有 SQL 语句之前,但我认为这会导致竞争条件。


对于 PL/pgSQL 函数,请使用特殊变量FOUND:

CREATE FUNCTION foo(int, text)
  RETURNS void
  LANGUAGE plpgsql AS
$func$
BEGIN
   INSERT INTO table1 (id, value)
   VALUES ($1, $2)
   ON CONFLICT DO NOTHING;

   IF NOT FOUND THEN
      INSERT INTO table2 (table1_id, value)
      VALUES ($1, $2);
      UPDATE table3
      SET   (table1_id, time)
          = ($1       , now())
      WHERE  ???;  -- you don't want to update all rows in table3?
   END IF;
END
$func$;

Call:

SELECT foo(1, 'a');

FOUND被设定为false if the INSERT实际上并没有插入任何行。

该手册关于ON CONFLICT Clause:

ON CONFLICT DO NOTHING只是避免插入一行作为其 替代行动。

该手册关于获取结果状态

UPDATE, INSERT, and DELETE语句集FOUND如果至少有一个则为 true 行受到影响,如果没有行受到影响,则为 false。

需要明确的是,如果其中一行,则运行后面的语句table1 does已经存在,因此不会插入新行。 (就像您所要求的,但与您的问题标题相反。)

如果你只是想check是否存在行:

  • PostgreSQL IF 语句

比赛条件?

如果同一事务中的后续命令depend上(尚未解锁)existing row in table1(例如,使用 FK),您需要锁定它以防止并发事务同时删除或更新它。一种方法是:代替DO NOTHING use DO UPDATE,但是做not实际上更新该行。该行仍然被锁定:

INSERT INTO table1 AS t (id, value)
VALUES ($1, $2)
ON     CONFLICT (id) DO UPDATE  -- specify unique column(s) or constraint / index
SET    id = t.id WHERE false;   -- never executed, but locks the row

显然,如果您可以排除可能以冲突方式写入同一行的并发事务,那么问题就不存在。

详细解释:

  • 如何在 RETURNING from INSERT ... ON CONFLICT 中包含排除的行
  • 函数中的 SELECT 或 INSERT 是否容易出现竞争条件?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

仅当行不存在时才在 PL/pgSQL 中运行 SQL 语句 的相关文章

随机推荐

  • 在两个活动之间传递位图[重复]

    这个问题在这里已经有答案了 我正在开发一个绘画应用程序 我想在其中将位图图像从一个活动传递到另一个活动 但该项目没有响应 我将相对布局截图转换为位图并通过Intent传递 但问题没有解决 这是我的代码 绘画活动 package com ne
  • 使用 .net Web 服务从 iPhone 调用 http post URL

    当我点击按钮时 我需要从我的 iPhone 调用一个 url 该 url 将 UITextField 中的值作为参数 并且使用 POST 方法来调用 Web 服务 我如何在我的 iPhone 中使用该 URL 我用 GET 方法做了同样的事
  • iPhone 启动画面

    我真的很尽力 但我无法真正找出我的代码中出了什么问题 我做了很多搜索 但我想我只是无法理解一些客观的 c 基础知识 我的第一个问题与下面的代码有关 window addSubview tabBarController view UIImag
  • java.util.NoSuchElementException:即使我们使用流,也没有值存在

    我是 java 新手 我正在运行本地服务器 jar 并尝试访问 API 端点 所有数据都是正确的 我得到以下信息 java util NoSuchElementException 不存在值 执行似乎发生在代码片段的下面一行 得到 任何帮助是
  • 使用 openpyxl 将 pandas 数据框复制到 Excel

    我在模板文件中保存了一些复杂的格式 我需要将 pandas 数据框中的数据保存到其中 问题是当我使用 pd to excel 保存到此工作表时 pandas 会覆盖格式 有没有办法以某种方式将 df 中的值 粘贴到工作表中 我正在使用熊猫0
  • 是否可以通过Python脚本执行QPDF

    我正在开发一个处理 PDF 文件的 python 脚本 尽管其中一些文件包含加密 限制使用只能打印 我必须手动删除它们才能处理它们 为此我一直手动使用QPDF在运行脚本之前删除对单个 PDF 文件的这些限制 qpdf 的命令非常简单 在命令
  • 无法在 iOS 中将 XMPPFramework 连接到 Openfire 服务器

    我正在研究一个iOS用户登录应用程序的聊天应用程序 我已经下载了XMPPFramework来自 GitHubXMPP框架 我正在尝试连接XMPP框架与Openfire服务器通过以下方式本教程 这是我将 XMPP 连接到 openfire 的
  • 有人在 Windows 7 上成功使用 Visual Studio 6 吗?

    VS6 在 Windows 7 上安装期间出现了一系列错误 然后完全崩溃 我特别需要让 VB6 在 Windows 7 上运行 有人有运气吗 VB6 新闻组中的人们report他们已经设法让它在 Windows 7 上运行 There s
  • 如何在 DirectX 9 中将 XMMATRIX 转换为 D3DMATRIX?

    我从 www directxtutorial com 学习 DirectX DirectX 9 并在 Windows 8 中使用 Visual Studio 2012 d3dx9 d3dx 被其他标头 例如 DirectXMath 替换 因
  • Android - 以编程方式同步联系人添加到谷歌帐户

    在我的应用程序中 我需要将联系人添加到默认谷歌帐户并同步它 这是我的代码 public static void addContact Context context String DisplayName String WorkNumber
  • 未找到命名对象资源 - Omnifaces + JSF 2.2.12

    自从我安装了 Mojorra 版本 2 2 12 从 2 2 8 开始 以来 我的 JSF 页面出现了问题 加载页面时它会抛出异常 例外情况是 命名对象 未找到 org omnifaces component output Resource
  • li:last-child 似乎在 IE8 中不起作用

    下面是我的html结构 div class footerMenu ul li Home li li About li li Feedback li li Contact us li ul div But footerMenu li last
  • 如何翻转x轴?

    I am plotting amplitude reconstruction of FMCW radar 我只想翻转里面的图 但是 x 轴应该是相同的 我该怎么办呢 下面是我的绘图代码 for i 1 2500 dividing each
  • 无法在 win64 模式下运行新项目,但 win32 模式可以正常运行

    我最近重新格式化了运行 Windows 8 1 的计算机 并重新安装了 Delphi XE6 它在格式化计算机之前运行良好 每当我打开一个新项目并按 F9 Windows 64 作为目标平台 时 我都会收到以下错误 Debugger Ass
  • Perl 正则表达式查找精确单词

    我想找到这个词sprintf在我的代码中 应该使用什么 Perl 正则表达式 有些行的文字如下sprintf private 我想排除它 但只需要sprintf 你必须使用 b在单词的边界处 bsprintf b
  • std::vector 元素是否保证是连续的?

    我的问题很简单 是std vector保证元素是连续的 换句话说 我可以使用指向 a 的第一个元素的指针吗 std vector作为 C 数组 如果我没记错的话 C 标准并没有做出这样的保证 但是 那std vector如果元素不连续 几乎
  • Rails 关系排序?

    所以我想将这个 SQL 查询转换为 Rails 并且按照这个确切的顺序 假设我有 WITH sub table as SELECT FROM main table LIMIT 10 OFFSET 100 ORDER BY id SELECT
  • 使用 Rhino 模拟抽象类的默认行为

    我对嘲笑还很陌生 所以这可能是我还没有意识到的事情 但我在任何地方都找不到一个好的例子 我试图断言默认情况下 任何从我的抽象类继承的类都会在构造函数中实例化一个集合 这是抽象类 public abstract class DataColle
  • BufferedReader 用于大 ByteBuffer?

    有没有一种方法可以使用 BufferedReader 读取 ByteBuffer 而不必先将其转换为 String 我想将相当大的 ByteBuffer 作为文本行读取 出于性能原因 我想避免将其写入磁盘 在 ByteBuffer 上调用
  • 仅当行不存在时才在 PL/pgSQL 中运行 SQL 语句

    我想在 Postgres 9 6 的 PL pgSQL 函数中做这样的事情 INSERT INTO table1 id value VALUES 1 a ON CONFLICT DO NOTHING If the above stateme