sql-server - 合并:在匹配时插入
问题描述
我正在下载与以前下载的数据有重复的数据。
我成功地使用 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)
*/
;
解决方案
您可以使用如下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
现有行的列时的小性能损失为代价)。
推荐阅读
- php - bootstrap4网格一页四行
- wpf - 将 listboxitem 内容绑定到列表框的依赖属性
- r - 使用 R 连接到 Redshift 实例而不使用 oVPN
- android - 如何通过文本观察器在 android 中设置文本
- javascript - 使用 jdeveloper 将 FontAwesome 与 xhtml 一起使用时出错
- database - 返回使用 Rocket 和 Diesel (Rust) 在 PostgreSQL 中创建的单个记录
- python-3.x - 将日志记录级别作为变量传递给 python3 代码?
- javascript - 以透明度(CSS 或 JS)在另一张图片上显示一张新图片
- api - 颤振响应始终相同
- flutter - 从数组中删除特定项目会删除 UI 中的错误项目