原樣使用該語句是不可能的。違反唯一密鑰會引發錯誤。您必須找到該錯誤,或者使用insert ignore
(不允許您對第三種情況作出反應)或使用on duplicate key
。
如果您的條件符合,您可以使用on duplicate key
故意拋出錯誤。不幸的是,錯誤消息不會與違規直接相關,它只會是「任何」異常(反常描述您的情況的異常不存在)。在update
-part中,檢查名稱是否不同。如果沒有改變,你什麼都不做(「忽略」),如果改變了,你可以設置一個無效的值爲例如拋出not null
- 錯誤:
INSERT INTO devices_used_by_resource(id,sourcesId,name)
VALUES(123,321,'the name')
on duplicate key update id = if(name = values(name), id, null);
> 1 row(s) affected
INSERT INTO devices_used_by_resource(id,sourcesId,name)
VALUES(123,321,'the name')
on duplicate key update id = if(name = values(name), id, null);
> 0 row(s) affected
INSERT INTO devices_used_by_resource(id,sourcesId,name)
VALUES(123,321,'the name1')
on duplicate key update id = if(name = values(name), id, null);
> Error Code: 1048. Column 'id' cannot be null
你(name, sourcedId)
有第二唯一索引,這也將引發on duplicate key
。你沒有specifiy如果你插入一行違反本應該發生什麼,所以該語句會忽略它(違反(name, sourcedId)
不會改名字,所以不會引發任何異常):
INSERT INTO devices_used_by_resource(id,sourcesId,name)
VALUES(1,321,'the name')
on duplicate key update id = if(name = values(name), id, null);
> 0 row(s) affected
如果你想拋出一個異常,然後也可以改爲比較只是名字的所有值,所以不同的id
也將引發錯誤:
INSERT INTO devices_used_by_resource(id,sourcesId,name)
VALUES(123,321,'the name1')
on duplicate key update
id = if(id = values(id) and sourcesId = values(sourcesId)
and name = values(name), id, null);
> Error Code: 1048. Column 'id' cannot be null
異常消息顯然不是有關該錯誤很清楚,因爲它引發了一個無關的錯誤。如果你只是想捕捉這個異常並知道它的實際意義,那就沒有問題。爲了使它更時尚一點,您可以添加一個觸發器,該觸發器使用id=null
作爲指示器來發出自定義消息,例如,
delimiter $$
create trigger trbu_devices_used_by_resource
before update on devices_used_by_resource
for each row
begin
if new.id is null then
SIGNAL SQLSTATE '45000'
SET message_text = 'Inserted duplicate entry with different attributes!';
end if;
end $$
delimiter ;
這也將拋出一個錯誤,如果您使用update devices_used_by_resource set id = null
沒有插入,但我想這不會發生的時候,也許你可以發現,覆蓋了太多的消息 - 或者你做一些更復雜的通信在upsert和觸發器之間,例如將id
或sourcesId
設置爲-812677
並檢查觸發器中的值。
基於唯一性約束,您的第二個要求將因數據庫異常而失敗。另外,我認爲你可能需要一個唯一的名字來顛倒你的邏輯。我認爲你應該忽略並且在2和3之間拋出。 –
@RossBush 2不應該是一個錯誤,因爲沒有任何改變。 3應該是一個錯誤,因爲改變了一些東西我的意圖是,然後在另一個包含'id.devices_used_by_resources'的表中執行插入操作,並且需要確保它存在並且尚未更改。 – user1032531
我誤解了您的意圖。但是,它並不清楚。爲什麼不將id字段添加到nameSourceUniqueInx唯一約束中。這樣可以保證表中所有的id/sourceId/name組合都是唯一的。 –