这是一个解释我的意思的示例陈述:
DECLARE @sourceTable table(ID int, tmstmp datetime, data varchar(max))
DECLARE @targetTable table(ID int, tmstmp datetime, data varchar(max))
INSERT INTO
@sourceTable
VALUES
(1, '2015-07-23T01:01:00', 'Testdata6')
,(1, '2015-07-23T02:02:00', 'Testdata7')
,(2, '2015-07-23T03:03:00', 'Testdata8')
,(2, '2015-07-23T04:04:00', 'Testdata9')
INSERT INTO
@targetTable
VALUES
(2, '2015-07-23T00:01:00', 'Testdata1')
,(2, '2015-07-23T00:02:00', 'Testdata2')
,(2, '2015-07-23T00:03:00', 'Testdata3')
,(3, '2015-07-23T00:04:00', 'Testdata4')
,(3, '2015-07-23T00:05:00', 'Testdata5')
MERGE INTO
@targetTable T
USING
@sourceTable S
ON
S.ID = T.ID
WHEN MATCHED THEN
DELETE
-- also want to INSERT newer ID 2 source records here after delete
WHEN NOT MATCHED THEN
INSERT (ID, tmstmp, data)
VALUES (S.ID, S.tmstmp, S.data)
;
当我做出选择......
SELECT
*
FROM
@targetTable
...我得到下表:
ID tmstmp data
3 2015-07-23 00:04:00.000 Testdata4
3 2015-07-23 00:05:00.000 Testdata5
1 2015-07-23 01:01:00.000 Testdata6
1 2015-07-23 02:02:00.000 Testdata7
但我希望得到下表:
ID tmstmp data
3 2015-07-23 00:04:00.000 Testdata4
3 2015-07-23 00:05:00.000 Testdata5
1 2015-07-23 01:01:00.000 Testdata6
1 2015-07-23 02:02:00.000 Testdata7
2 2015-07-23 03:03:00.000 Testdata8
2 2015-07-23 04:04:00.000 Testdata9
如何在一个语句中实现这一点,因为我对源表使用了大量的CTE。
提前致谢...
答案 0 :(得分:1)
我们可以在"来源"中添加一些额外的行。用于清除现有行的表,然后让所有当前行都属于NOT MATCHED
子句,这是唯一允许执行INSERT
操作的子句:
;With Clears as (
SELECT *,0 as Rem from @sourceTable
union all
select distinct ID,'1900-01-01','',1 from @sourceTable
)
MERGE INTO
@targetTable T
USING
Clears S
ON
S.ID = T.ID and s.Rem = 1
WHEN MATCHED THEN
DELETE
WHEN NOT MATCHED and Rem = 0 THEN
INSERT (ID, tmstmp, data)
VALUES (S.ID, S.tmstmp, S.data)
;
尝试在MERGE
语句中实现多个操作的基本规则是,您需要为要执行的每个操作至少设置一个源行。因此,在ON
子句之后制定WHEN
子句和各种附加条件是一项挑战,以便在您需要时执行每项操作。
E.g。如果没有将额外的and Rem = 0
添加到上面的WHEN NOT MATCHED
,我们添加到Clears
以删除ID
1
的所有行的额外行将最终创建额外的行,因为目标表中没有任何ID
1
行。
答案 1 :(得分:0)
这不是一个简单的DELETE
- INSERT
吗?
DELETE t FROM @targetTable t
WHERE EXISTS(
SELECT 1
FROM @sourceTable
WHERE ID = t.ID
)
INSERT INTO @targetTable(ID, tmstmp, data)
SELECT ID, tmstmp, data
FROM @sourceTable s
WHERE NOT EXISTS(
SELECT 1
FROM @targetTable
WHERE ID = s.ID
)
您可能希望将这两个陈述保留在一个交易中。
编辑:我刚刚意识到你想要一个声明。但我会把它作为替代解决方案留在这里。