sql-server - 如何在合并中插入多行?
问题描述
如何在 SQL 的合并中插入多行?我正在使用 MERGE INSERT,我想知道是否可以同时添加两行?下面是我写的查询,但是如您所见,我想为 IsNew 插入两个布尔值,当它不匹配时,我想为 IsNew = 1 和一个 IsNew = 0 添加一行。我该如何实现这个?
MERGE ITEMS AS TARGET
USING @table AS SOURCE
ON T.[ID]=S.ID
WHEN MATCHED THEN
UPDATE SET
T.[Content] = S.[Content],
WHEN NOT MATCHED THEN
INSERT (ID, Content, TIME, IsNew)
VALUES (ID, TEXT, GETDATE(), 1),
解决方案
您不能直接使用merge
语句来执行此操作,但有一个简单的解决方案。
merge
statement<merge_not_matched>
子句(即)insert...values|default values
子句只能为源表中的每一行在目标表中插入一行。
这意味着要为每个匹配项输入两行,您只需更改源表 - 在这种情况下,它就像交叉连接查询一样简单。
但是,该<merge_matched>
子句要求源中只有一行可以匹配目标中的任何一行 - 否则您将收到以下错误:
MERGE 语句多次尝试更新或删除同一行。当目标行匹配多个源行时会发生这种情况。MERGE 语句不能多次 UPDATE/DELETE 目标表的同一行。优化 ON 子句以确保目标行最多匹配一个源行,或使用 GROUP BY 子句对源行进行分组。
要解决此问题,您必须向 中添加一个条件,when match
以确保源表中只有一行更新目标表:
MERGE Items AS T
USING (
SELECT Id, Text, GetDate() As Date, IsNew
FROM @table
-- adding one row for each row in source
CROSS JOIN (SELECT 0 As IsNew UNION SELECT 1) AS isNewMultiplier
) AS S
ON T.[ID]=S.ID
WHEN MATCHED AND S.IsNew = 1 THEN -- Note the added condition here
UPDATE SET
T.[Content] = S.[Text]
WHEN NOT MATCHED THEN
INSERT (Id, Content, Time, IsNew) VALUES
(Id, Text, Date, IsNew);
说了这么多,我想向您推荐另一个stackoverflow 帖子,它提供了比使用merge
语句更好的选择。
答案的作者是 Microsoft MVP 和 SQL Server 专家 DBA,您至少应该阅读他所说的内容。
推荐阅读
- swift - SwiftUI:停止永远重复的动画
- spring-webflux - 如何在 spring-webflux 中使用请求和会话范围(截至最新版本)
- java - 如何在 Android Studio 中压缩 Kotlin 项目
- python - def create 方法中的 Django Rest Framework 问题..在试用结束字段中面临空值
- vb.net - 如何在 vb.net 中将对象转换为 json?
- python - Python 下载包含 JS 的网站 HTML
- javascript - 如何在特定坐标上的图像上绘制 svg 或画布
- c# - 如何在 c# 中使用正则表达式获取指定值?
- mysql - 如何在mysql中导入数据库?我正在使用 laradock,但无法增加 mysql 的导入文件大小
- vbscript - Windows以间隔将文件从URL下载到指定位置