原样使用该语句是不可能的。违反唯一密钥会引发错误。您必须找到该错误,或者使用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组合都是唯一的。 –