讲师中心 微信公众号
AI工具推荐 视频效率加速

如何在SQL存储过程中实现数据的Upsert操作_利用MERGE语句合并插入更新

千枫酱_4671

千枫酱_4671

发布时间:2026-04-27 20:19:26

|

961人浏览过

|

来源于php中文网

原创

SQL Server 的 MERGE 语句需基于唯一键在 ON 子句中精确匹配,WHEN MATCHED 仅判断连接条件是否成立而非列值差异,漏写 WHEN NOT MATCHED 或误用条件易致错误或性能下降。

如何在sql存储过程中实现数据的upsert操作_利用merge语句合并插入更新

MERGE 语句在 SQL Server 中的典型写法

SQL Server 的 MERGE 是实现 Upsert(存在则更新、不存在则插入)最直接的方式,但它不是“写完就跑”,必须明确指定匹配逻辑和操作分支。常见错误是漏掉 WHEN NOT MATCHED THEN INSERT 或误把 WHEN MATCHED 当成“只要字段值不同就更新”——实际上它只判断 ON 子句的连接条件是否成立,不比较具体列值。

基本结构如下:

MERGE target_table AS t
USING (SELECT @id AS id, @name AS name, @score AS score) AS s ON t.id = s.id
WHEN MATCHED THEN
    UPDATE SET name = s.name, score = s.score
WHEN NOT MATCHED THEN
    INSERT (id, name, score) VALUES (s.id, s.name, s.score);
  • ON 子句必须基于唯一键或主键,否则可能触发多匹配导致报错 The MERGE statement attempted to update or delete the same row more than once
  • 源数据(USING 部分)建议用子查询或表变量封装,避免直接拼接参数引发类型隐式转换问题
  • 不能在 WHEN MATCHED 分支里加额外条件(如 AND t.score s.score)来控制更新时机——虽然语法允许,但会显著降低执行计划稳定性,且 SQL Server 2019+ 对带条件的 MATCHED 优化有限

PostgreSQL 怎么做 Upsert(没有 MERGE)

PostgreSQL 没有 MERGE,但支持 INSERT ... ON CONFLICT,这是更轻量、更可控的 Upsert 实现方式。它底层依赖唯一约束或主键冲突检测,比 MERGE 更少出错,也更容易调试。

示例:

INSERT INTO users (id, name, score)
VALUES ($1, $2, $3)
ON CONFLICT (id) DO UPDATE
SET name = EXCLUDED.name, score = EXCLUDED.score;
  • ON CONFLICT (id) 中的 id 必须是已定义的唯一索引或主键列,否则报错 there is no unique or exclusion constraint matching the ON CONFLICT specification
  • EXCLUDED 是个伪表,代表本次被拒绝插入的那行数据,不能写成 VALUES 或引用外部变量
  • 如果想只在某些字段变化时才更新(比如避免无意义的时间戳覆盖),得显式写条件:DO UPDATE SET updated_at = NOW() WHERE users.score EXCLUDED.score

MySQL 的 INSERT ... ON DUPLICATE KEY UPDATE 注意点

MySQL 用 INSERT ... ON DUPLICATE KEY UPDATE 实现 Upsert,表面简单,但几个细节容易翻车:它只响应 PRIMARY KEY 或 UNIQUE 约束冲突,普通索引无效;而且一旦触发更新,LAST_INSERT_ID() 的行为会变——插入时返回新 ID,更新时返回原 ID,这点在业务层生成关联记录时容易出错。

  • 必须确保表上有对应字段的 UNIQUE 或 PRIMARY KEY,否则语句静默变成纯插入,不会报错也不会更新
  • 更新子句中不能直接引用要插入的值,得用 VALUES(col_name) 函数,例如:ON DUPLICATE KEY UPDATE name = VALUES(name), score = VALUES(score)
  • 如果 INSERT 语句含多行,且部分行冲突、部分不冲突,MySQL 默认继续执行(非事务中断),但影响行数统计会包含插入+更新总数,需靠 ROW_COUNT() 判断实际插入了几行

跨数据库写 Upsert 时最该检查的三件事

别指望一套 SQL 能在 SQL Server、PostgreSQL、MySQL 上通用。哪怕只是改个关键字,运行时也可能完全失效或产生意外结果。

  • 确认目标列是否有唯一约束:SQL Server 的 MERGE ON、PostgreSQL 的 ON CONFLICT、MySQL 的 ON DUPLICATE KEY 全部依赖这个,缺了就退化成纯插入
  • 检查空值(NULL)处理逻辑:三个平台对 NULL = NULL 的判断完全不同,尤其当唯一键含可空列时,PostgreSQL 认为 NULL 不冲突,MySQL 和 SQL Server 可能认为冲突或不冲突,取决于索引类型
  • 留意并发安全:所有 Upsert 方案在高并发下都可能因“检查-执行”间隙导致重复插入(即所谓的“thundering herd”),真正保险的做法是在应用层加分布式锁,或在数据库层用 SELECT ... FOR UPDATE 配合事务——但这会让 Upsert 失去原子性优势,得权衡

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

4523

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

951

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

1189

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

6501

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

3263

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

6460

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

8841

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

1190

2024.04.29

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

60

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
零基础精通 PS 视频教程
零基础精通 PS 视频教程

共268课时 | 120.2万人学习

前端工程师必备技能—PS切图
前端工程师必备技能—PS切图

共11课时 | 2.2万人学习

麦子学院Photoshop切片视频教程
麦子学院Photoshop切片视频教程

共13课时 | 4.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn