插入/更新,忽略会违反 FK 的行

问题描述

如果有人在具有指向另一个外键的表上执行更新或插入,如果出现不存在的值,则会引发错误。是否有足够自动化的方法来忽略错误列并继续处理其他列?

我只能想到一个代替触发器,但听起来很乱。

解决方法

您应该检查 INSERT 查询中的行,将源数据与引用的表连接起来。

例如,假设您在 SourceData 表中有以下数据,并且您想将其插入到 AdventureWorks2019 数据库的 Sales.CurrencyRate 表中:

CREATE TABLE SourceData (
    CurrencyRateDate datetime,FromCurrencyCode char(3),ToCurrencyCode char(3),PRIMARY KEY (CurrencyRateDate,FromCurrencyCode,ToCurrencyCode),Rate money NOT NULL
)

INSERT INTO SourceData (CurrencyRateDate,ToCurrencyCode,Rate) VALUES 
('20200429','EUR','RON',4.8425),('20200429','ROL',48425),('20200430',4.8421),48421)

INSERT INTO Sales.CurrencyRate (CurrencyRateDate,AverageRate,EndOfDayRate)
SELECT sd.CurrencyRateDate,sd.FromCurrencyCode,sd.ToCurrencyCode,sd.Rate,sd.Rate
FROM SourceData sd

如果您简单地运行上面提到的 INSERT 语句,您会得到一个错误,提示 "The INSERT statement conflicted with the FOREIGN KEY constraint "FK_CurrencyRate_Currency_ToCurrencyCode". The conflict occurred in database "AdventureWorks2019",table "Sales.Currency",column 'CurrencyCode'.",因为货币“RON”不在 Sales.Currency 表中。

为了避免这个错误并只插入引用表中具有相应行的数据,您只需为每个 FK 使用一个 JOIN,如下所示:

INSERT INTO Sales.CurrencyRate (CurrencyRateDate,sd.Rate
FROM SourceData sd
INNER JOIN Sales.Currency c1 ON c1.CurrencyCode=sd.FromCurrencyCode
INNER JOIN Sales.Currency c2 ON c2.CurrencyCode=sd.ToCurrencyCode