在我 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将创建一个新行,其中包含“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() 功能的最简单解决方案是将问题分成两部分:
- 使用匹配的 slug 更新任何现有行。
- 如果没有匹配 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 语句对我来说是“顿悟”时刻。它的目的是使用另一个表的查询结果来一次执行多次插入。但是,您可以通过提供自己的值来使用和滥用 sql 的功能,并且仅在 post_name 为“about”的帖子不存在时才执行插入。
这是解决这个问题最优雅、最有效的解决方案吗?可能不会。但对于 wordpress 站点的一次性迁移来说,它已经足够好了,并且它允许您更新或插入一行,而无需存储过程或任何应用程序逻辑。希望这篇文章能够帮助您在不借助 orm 的情况下编写强大的查询。
以上就是在数据库中更新插入不使用主键或唯一约束的行的详细内容,更多请关注抖狐科技其它相关文章!
-
彩信多少钱一条
彩信收费标准因运营商和套餐而异,一般在 0.3-1.2 元/条,影响因素包括:运营商(中国移动、中国联通、中国电信等)套餐(免费彩信数量和资费标准)彩信大小(图片、音频或视频文件越大,资费越高)彩信的...
-
怎么把文件存到u盘
要将文件保存到 u 盘:将 u 盘插入计算机。找到要保存的文件并选择 u 盘。复制或移动文件(复制:按 ctrl/command + c,粘贴:按 ctrl/command + v;移动:按 ctrl...
-
优酷vip会员怎么共享两个手机
共有两种方法共享优酷 vip 会员:升级为超级影视 vip 会员,创建家庭组并邀请至多 5 名家庭成员加入;在两个手机上登录同一优酷账号,主手机开启自动续费,次手机可享受 vip 特权。优酷 VIP...
-
win10提示2xlive.dll文件丢失怎么解决
win10提示2xlive.dll文件丢失,如何解决?使用电脑玩游戏时,看到系统提示“无法启动此程序,因为计算机中丢失xlive.dll”让人很苦恼。这个提示表明游戏所需的关键文件缺失或未注册。php...
-
理解 JavaScript 中的原型:继承的支柱
javascript 是一种使用原型继承的强大语言,这对于那些来自基于类的语言的人来说可能有点困惑。在这篇文章中,我们将探讨原型在 javascript 中的工作原理、它们在继承中的作用,以及如何有效...