Mic*_*ren 7 sql-server sql-server-2012 merge
假设你有这样的事情:
源表(变量):
Values (
LeftId INT NOT NULL,
RightId INT NOT NULL,
CustomValue varchar(100) NULL
)
Run Code Online (Sandbox Code Playgroud)
目标表:
Mapping (
LeftId INT NOT NULL,
RightId INT NOT NULL,
CustomValue varchar(100) NULL
)
Run Code Online (Sandbox Code Playgroud)
我想合并Values
成Target
以下规则:
source.LeftId = target.LeftId AND source.RightId = target.RightId
CustomValue
LeftId
源,即只能删除记录中涉及到LefId
什么,我合并的秒。(最后一条规则很难描述,抱歉!)
来源:
1, 10, foo
1, 11, foo
Run Code Online (Sandbox Code Playgroud)
目标:
1, 10, bar
1, 12, foo
2, 20, car
Run Code Online (Sandbox Code Playgroud)
结果目标:
1, 10, foo (updated)
1, 11, foo (inserted)
1, 12, foo (deleted)
2, 20, car (unchanged)
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止所拥有的,它负责update
和insert
:
MERGE Mapping AS target
USING (SELECT LeftId, RightId, CustomValue FROM @Values)
AS source (LeftId, RightId, CustomValue)
ON target.LeftId = source.LeftId
AND target.RightId = source.RightId
WHEN NOT MATCHED THEN
INSERT (LeftId, RightId, CustomValue)
VALUES (source.LeftId, source.RightId, source.CustomValue)
WHEN MATCHED THEN
UPDATE SET
CustomValue = source.CustomValue;
Run Code Online (Sandbox Code Playgroud)
我如何做我的delete
规则的一部分?
Mik*_*son 10
您可以从 CTE 中的目标表中筛选出您需要考虑的行,并使用 CTE 作为合并中的目标。
WITH T AS
(
SELECT M.LeftId,
M.RightId,
M.CustomValue
FROM @Mappings AS M
WHERE EXISTS (SELECT *
FROM @Values AS V
WHERE M.LeftId = V.LeftId)
)
MERGE T
USING @Values AS S
ON T.LeftId = S.LeftId and
T.RightId = S.RightId
WHEN NOT MATCHED BY TARGET THEN
INSERT (LeftId, RightId, CustomValue)
VALUES (S.LeftId, S.RightId, S.CustomValue)
WHEN MATCHED THEN
UPDATE SET CustomValue = S.CustomValue
WHEN NOT MATCHED BY SOURCE THEN
DELETE
;
Run Code Online (Sandbox Code Playgroud)
这是DELETE
我想到的单独操作:
DELETE m
FROM dbo.Mapping AS m
WHERE EXISTS
(SELECT 1 FROM @Values WHERE LeftID = m.LeftID)
AND NOT EXISTS
(SELECT 1 FROM @Values WHERE LeftID = m.LeftID AND RightID = m.RightID);
Run Code Online (Sandbox Code Playgroud)
正如我在这里概述的那样,对于左反半连接,该NOT EXISTS
模式通常会胜过该LEFT JOIN / NULL
模式(但您应该始终进行测试)。
不确定您的总体目标是清晰度还是性能,因此只有您才能判断这是否比NOT MATCHED BY source
选项更符合您的要求。您必须定性地查看计划,以及定量地查看计划和/或运行时指标,才能确定。
如果您希望您的MERGE
命令能够保护您免受多个独立语句可能发生的竞争条件的影响,您最好通过将其更改为:
MERGE dbo.Mapping WITH (HOLDLOCK) AS target
Run Code Online (Sandbox Code Playgroud)
(摘自Dan Guzman 的博客文章。)
就个人而言,我会做这一切没有MERGE
,因为还有未解决的错误,其他原因。并且Paul White 似乎也推荐单独的 DML 语句。
这就是我添加架构前缀的原因:在创建、影响等时,您应该始终按架构引用对象。
归档时间: |
|
查看次数: |
27836 次 |
最近记录: |