”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 在数据库中更新插入不使用主键或唯一约束的行

在数据库中更新插入不使用主键或唯一约束的行

发布于2024-11-08
浏览:104

Upsert a row in a DB that doesn

在我 7 年的程序员职业生涯中,我大部分时间都是通过 ORM 与 SQL 交互。我发现 Laravel 的 Eloquent ORM 的一项特别有用的功能是它的 updateOrInsert() 方法:

DB::table('posts')
    ->updateOrInsert(
        ['slug' => 'about'], // matching condition
        ['content' => 'Like and subscribe'] // created or updated values
    );

在上面的示例中,Eloquent 将在 posts 表中查找 slug 等于“about”的行。如果存在带有该 slug 的行,Eloquent 会将该行的内容更新为“点赞并订阅”。如果行与该slug存在,Eloquent将创建一个新行,其中slug为“about”,内容为“Like and subscribe”。

问题:没有主键或唯一约束

我目前正在编写一个迁移脚本,将页面数据从旧的 WordPress 站点移动到新的 WordPress 站点。该脚本连接到旧站点的数据库,然后创建一个可以导入到新站点的数据库中的 SQL 文件。新网站已有一些已手动移动的页面,但其内容可能已过时。当新站点上已经存在页面时,我们不想再次创建它:我们想要更新已经存在的页面。我们可以通过使用 WordPress 数据库中的 post_name 列来确定该页面是否已经存在,该列对应于页面的 URL slug。

如果 post_name 是主键,我们可以使用 REPLACE 语句完成类似于 Eloquent 的 createOrUpdate() 方法的操作,但 post_name 不是主键。

如果 post_name 有唯一约束,我们可以使用 INSERT ... ON DUPLICATE KEY UPDATE 语句完成类似于 Eloquent 的 createOrUpdate() 方法的操作,但 post_name 没有唯一约束。

啊,WordPress 的乐趣。

我研究了MySQL的IF语句,但IF语句只适用于存储过程、触发器和函数。我不想在要导入到新站点数据库的 SQL 文件中创建存储过程,因此我必须搜索其他选项。

解决方案:2条语句

我能找到的在纯 SQL 中模拟 Eloquent 的 updateOrInsert() 功能的最简单的解决方案是将问题分成两部分:

  1. 使用匹配的 slug 更新任何现有行。
  2. 如果没有匹配 slugs 的行,则创建一个新行。

实际情况如下:

-- Update the post if it already exists.

UPDATE wp_posts
SET post_type = 'page',
    post_title = 'About',
    post_content = 'Like and subscribe'
WHERE post_name = 'about';

-- Create a new post if it does not exist.

INSERT INTO wp_posts (post_name, post_type, post_title, post_content)
SELECT 'about', 'page', 'About', 'Like and subscribe'
WHERE NOT EXISTS (
    SELECT 1
    FROM wp_posts
    WHERE post_name = 'about'
);

注意: 为了简洁和清晰起见,此示例省略了许多 WordPress 所需的 wp_posts 列。

了解 INSERT ... SELECT 语句对我来说是“顿悟”时刻。它的目的是使用另一个表的查询结果来一次执行多次插入。但是,您可以通过提供自己的值并仅在 post_name 为“about”的帖子不存在时执行插入来使用和滥用 SQL 的功能。

这是解决这个问题最优雅、最有效的解决方案吗?可能不会。但对于 WordPress 站点的一次性迁移来说,它已经足够好了,并且它允许您更新或插入一行,而无需存储过程或任何应用程序逻辑。希望这篇文章可以帮助您在不借助 ORM 的情况下编写强大的查询。

版本声明 本文转载于:https://dev.to/tylerlwsmith/upsert-a-row-in-a-db-that-doesnt-use-primary-keys-or-unique-constraints-2jnl?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何解决使用 JavaScript 更改 iframe src 的问题
    如何解决使用 JavaScript 更改 iframe src 的问题
    使用 JavaScript 更改 iframe src:疑难解答单击单选按钮时更改 iframe 的 src 属性时遇到问题。要纠正此问题,必须检查代码以确定确切的原因。一个可能的问题是括号的错误使用。在您的代码中,该行:document.getElementById['calendar'].src...
    编程 发布于2024-11-08
  • 为什么 `window.onscroll` 在 iPhone/iPad 上不起作用?
    为什么 `window.onscroll` 在 iPhone/iPad 上不起作用?
    在 iPhone/iPad 上使用滚动事件捕获事件尝试在 iPad 上捕获滚动事件时,故障排除工作揭示了常见的方法例如 window.onscroll 和 document.onscroll 无法触发所需的响应。理解 iOS 上的事件处理设备iPhoneOS 事件处理机制与传统桌面浏览器不同。在连续...
    编程 发布于2024-11-08
  • 从开发人员到审阅者:初级开发人员审阅数据库查询的清单
    从开发人员到审阅者:初级开发人员审阅数据库查询的清单
    作为开发人员,提供高质量的代码至关重要,这些代码不仅具有功能性,而且还针对性能进行了优化。在开发人员领域的三年里,我从一名实践开发人员转变为审阅者角色。我在审核过程中关注的关键领域之一是数据库查询优化。 为什么关注数据库查询? 数据库查询可以显着影响应用程序的性能。编写得好的查询可以有效地获取数据,...
    编程 发布于2024-11-08
  • Mockito 是最好的 Java 模拟框架吗?  对其优缺点的综合评价。
    Mockito 是最好的 Java 模拟框架吗? 对其优缺点的综合评价。
    最佳 Java 模拟框架:Mockito在 Java 中,制作模拟对象对于有效的单元测试至关重要。鉴于选择过多,为此目的确定最佳框架可能会令人畏惧。本文评估了最突出的选择之一 Mockito,重点介绍了它的优点和缺点。Mockito 因其用户友好的语法而脱颖而出,使其易于开发人员使用。其简化方法针对...
    编程 发布于2024-11-08
  • 如何可靠地获取当前运行的Python文件的路径?
    如何可靠地获取当前运行的Python文件的路径?
    如何获取当前执行的Python文件的路径问题:确定当前运行的Python文件的路径可能很麻烦,特别是当遇到在特定场景下证明不可靠的方法时。其中包括从另一个脚本或在 IDLE 或 Mac OS X v10.6 等特定环境中启动执行的实例。解决方案:通用获取当前执行的 Python 的文件路径文件,采用...
    编程 发布于2024-11-08
  • Stack Overflow 如何创建这些信息丰富的弹出消息?
    Stack Overflow 如何创建这些信息丰富的弹出消息?
    复制 Stack Overflow 的弹出消息功能您可能已经注意到 Stack Overflow 上出现的时尚且内容丰富的弹出消息。这些消息为用户提供了有价值的通知和指导,您可能想知道如何在自己的网站上实现类似的功能。Stack Overflow 利用 HTML、CSS 和 JavaScript 的...
    编程 发布于2024-11-08
  • 为什么 Python 中没有元组理解?
    为什么 Python 中没有元组理解?
    理解 Python 中元组推导式的缺失在 Python 编程语言中,列表推导式和字典推导式提供了生成结构化数据的有效方法。然而,缺乏元组理解是一个异常现象。本文深入探讨了这一遗漏背后的原因。元组不变性是原因的假设并不成立。元组确实是不可变的,但这个属性并不妨碍它们在推导式中构建。问题的关键在于 Py...
    编程 发布于2024-11-08
  • 如何使用 VLC 模块在 Python 中播放 MP3 歌曲?
    如何使用 VLC 模块在 Python 中播放 MP3 歌曲?
    使用 Python 播放 MP3 歌曲使用正确的工具,在 Python 中播放 MP3 歌曲可以非常简单。错误的做法:尝试使用wave模块打开MP3文件,如下图所示不推荐:import wave w = wave.open("e:/LOCAL/Betrayer/Metalik Klinik...
    编程 发布于2024-11-08
  • 如何为Apache PHP应用程序配置环境变量?
    如何为Apache PHP应用程序配置环境变量?
    Apache PHP 应用程序的环境变量配置开发依赖环境变量的 PHP 应用程序时,必须清楚地了解如何配置环境变量使用 Apache 时设置这些变量。本文旨在提供有关配置可在 PHP 中访问的环境变量的指导,确保 Web 应用程序的正确运行。具体来说,为同一服务器中的各个域配置单独的环境变量是一种常...
    编程 发布于2024-11-08
  • 如何从 Activity 访问 ViewPager 片段方法?
    如何从 Activity 访问 ViewPager 片段方法?
    从 Activity 访问 ViewPager Fragment 方法许多移动应用程序使用片段,即代表模块化屏幕部分的独立组件。使用视图分页器管理多个片段可实现流畅的导航和页面动画。有时,开发人员需要在片段中执行特定操作以响应外部事件,例如用户在视图寻呼机上滑动。然而,实现此功能可能会遇到某些挑战。...
    编程 发布于2024-11-08
  • 如何在 Python 中按列值对散点图着色?
    如何在 Python 中按列值对散点图着色?
    按列值对散点图着色在 Python 中,Matplotlib 库提供了多种自定义散点图美观的方法。一项常见任务是根据特定列中的值分配颜色。Seaborn 集成一种解决方案是利用基于 Matplotlib 构建的 Seaborn 库。 Seaborn 提供 sns.relplot 和 sns.Face...
    编程 发布于2024-11-08
  • 为什么 fmt.Printf 显示负整数的二进制表示与 Go 中预期的不同?
    为什么 fmt.Printf 显示负整数的二进制表示与 Go 中预期的不同?
    二进制补码和 fmt.Printf:解开二进制表示之谜处理有符号整数时,计算机使用二进制补码来表示负值。这与典型的二进制表示不同,其中符号由单独的位指示。例如,在二进制补码中,整数 -5 表示为 1111 1011。但是,使用 fmt.Printf 打印二进制表示形式可能会产生意外结果。例如,以下代...
    编程 发布于2024-11-08
  • 读取控制台输入
    读取控制台输入
    InputStream读取方法: read():允许您直接从流中读取字节。 read()的三个版本: int read():读取单个字节并在流末尾返回-1。 int read(byte data[]):读取字节,直到数据数组填满、到达流末尾或发生错误。返回读取的字节数,如果到达流末尾则返回 -1。 ...
    编程 发布于2024-11-08
  • PHP 构造函数属性推广初学者指南
    PHP 构造函数属性推广初学者指南
    PHP 8 引入了一个名为 构造函数属性提升 的奇妙功能。如果您是 PHP 或一般编程新手,这可能听起来有点复杂。但别担心!本博客将通过大量编码示例向您介绍它是什么、为什么有用以及如何使用它。开始吧! 什么是建筑商财产促销? 在 PHP 8 之前,创建具有属性的类并在构造函数中初始化...
    编程 发布于2024-11-08
  • 如何使用 CNTLM 访问工作场所代理后面的 pip?
    如何使用 CNTLM 访问工作场所代理后面的 pip?
    与 CNTLM 的 PIP 代理连接要使用 CNTLM 访问工作场所代理后面的 pip,用户可能会遇到 --proxy 选项的问题。然而,利用环境变量提供了可靠的解决方案。CNTLM 配置验证可以通过运行“cntlm.exe -c cntlm.ini -I -M http://google.com”...
    编程 发布于2024-11-08

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3