sql-server - 插入/更新,忽略违反 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, FromCurrencyCode, ToCurrencyCode, Rate) VALUES
('20200429','EUR','RON',4.8425),
('20200429','EUR','ROL',48425),
('20200430','EUR','RON',4.8421),
('20200430','EUR','ROL',48421)
INSERT INTO Sales.CurrencyRate (CurrencyRateDate, FromCurrencyCode, ToCurrencyCode, 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, FromCurrencyCode, ToCurrencyCode, AverageRate, EndOfDayRate)
SELECT sd.CurrencyRateDate, sd.FromCurrencyCode, sd.ToCurrencyCode, sd.Rate, 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
推荐阅读
- angular-universal - i18n json 文件上的 404
- android - 文字未在 ios 上显示,但在 Android 和桌面上显示
- windows - windows下如何将一个文件夹复制到多个文件夹中
- swift - Swift UIImageView Firebase DispatchQueue
- c++ - Emscripten:如何在 JavaScript(TypeScript)中创建/使用 std::unique_ptr?
- javascript - 对自引用父/子列表的子值求和并将父值设置为总和
- google-chrome - 无法在 Centos 7 上安装 google-chrome-stable 95
- javascript - 如何浏览对象数组的所有值
- kubernetes - 在 K8s 中查找 pod 存在于哪些节点
- javascript - Javascript:检测鼠标点击与 video.play() 或使用 video.play() 而不触发事件