我正在下载与先前下载的数据重复的数据。
我成功使用MERGE语句根据事务编号丢弃重复项。据说这已经足够了,但我想监控某个特定交易的细节是否发生变化。
为此,我在when matched
上添加了merge
子句,并附加了一个插件,用于将记录标识为重复。
这种逻辑不应该经常触发,所以我不太担心这种方法(如果有效)会多次报告相同的重复。
当我准备此代码时,我收到以下错误消息:
An action of type 'INSERT' is not allowed in the 'WHEN MATCHED' clause of a MERGE statement.
有没有办法让重复记录使用MERGE语句插入到此表或另一个表中?
我对其他解决方案持开放态度,但我真的希望找到一种方法来使用MERGE语句,因为它会影响我的代码。
MERGE INTO dbo.TransactionDetail as t
USING (SELECT @TransNr --bigint
,@Detail -- [VARCHAR](50) NOT NULL
) as s
([TranNr]
,[Detail]
)
on t.TranNr = s.TranNr and t.CHANGED_RECORD = 0
when not matched then
INSERT (CHANGED_RECORD
,[TranNr]
,[Detail]
)
VALUES(0, s.TranNr, s.Detail)
/* Adding this does not allow statement to be prepared....
when matched and s.Detail <> t.Detail
then
INSERT (CHANGED_RECORD
,[TranNr]
,[Detail]
)
VALUES(1, s.TranNr, s.Detail)
*/
;
答案 0 :(得分:1)
您可以使用INSERT
语句,如下所示:
INSERT INTO dbo.TransactionDetail (CHANGED_RECORD,TranNr,Detail)
SELECT CASE WHEN EXISTS (
SELECT * FROM dbo.TransactionDetail
WHERE TranNr=@TransNr AND CHANGED_RECORD=0 AND Detail<>@Detail
) THEN 1 ELSE 0 END AS CHANGED_RECORD,
@TransNr AS TranNr, @Detail AS Detail
WHERE NOT EXISTS (
SELECT * FROM dbo.TransactionDetail
WHERE TranNr=@TransNr AND CHANGED_RECORD=0 AND Detail=@Detail
)
如果CHANGED_RECORD=0
的行具有相同的细节,则会跳过插入。但是,如果在具有CHANGED_RECORD=1
的另一行中找到相同的详细信息,则会插入新的副本。为避免这种情况,请从AND CHANGED_RECORD=0
子查询中删除WHERE NOT EXISTS
条件。
您可能还想创建一个唯一的过滤索引,以确保具有CHANGED_RECORD=0
的行的唯一性:
CREATE UNIQUE INDEX IX_TransactionDetail_Filtered
ON TransactionDetail (TranNr) /*INCLUDE (Detail)*/ WHERE CHANGED_RECORD=0
INCLUDE (Detail)
子句还可以略微提高查找Detail
行CHANGED_RECORD=0
的查询的性能(以牺牲一些额外的磁盘空间和较小的性能为代价)更新现有行的Detail
列时的惩罚。