gpt4 book ai didi

由于已设置的 NOT NULL 字段,MySQL DUPLICATE KEY UPDATE 无法更新

转载 作者:可可西里 更新时间:2023-11-01 08:51:29 25 4
gpt4 key购买 nike

我有一个使用严格模式的 MySQL 数据库,所以我需要在插入一行时填充所有 NOT NULL 值。我创建的 API 仅使用 DUPLICATE KEY UPDATE 功能来执行插入/更新。

如果插入了预期的任何 NOT NULL 属性,则客户端应用程序会提示。

基本示例(id为主键,有两个非空的字段aaa和xxx)

INSERT INTO tablename (aaa, xxx, id ) VALUES ( "value", "value", 1)
ON DUPLICATE KEY UPDATE aaa=VALUES(aaa), xxx=VALUES(xxx)

到目前为止一切都很好。一旦插入,系统将允许进行更新。尽管如此,仅更新其中一个字段时出现以下错误。

INSERT INTO tablename (aaa, id ) VALUES ( "newValue", 1)
ON DUPLICATE KEY UPDATE aaa=VALUES(aaa)

java.sql.SQLException: Field 'xxx' doesn't have a default value

这个异常是一个谎言,因为该行已经被插入并且 xxx 属性具有“值”作为值。我希望下面的句子等同于:

UPDATE tablename SET aaa="newValue" WHERE id=1

如果有人能阐明这个问题,我会很高兴。

编辑:

我可以在 PhpMyAdmin 中使用 SQL 查询成功更新一个字段,所以恐怕这不是 SQL 问题,而是 JDBC 的驱动程序问题。那可能就没有办法了。

@Marc B:您的见解可能是正确的,并且会表明我刚才描述的内容。这意味着 JDBC 中存在错误,因为它不应该在插入为 ON DUPLICATE 类型时进行检查,因为毕竟该行可能有默认值。无法提供真实的表格数据,但我相信上面的解释已经很清楚了。

@ruakh:它不会插入失败,我也不期待延迟验证。我的一个要求是使用相同的查询完成插入/更新,因为 servlet 不知道该行是否存在。 JAVA API 服务仅无法更新具有 NOT NULL 字段的行,这些字段在插入完成时已被填充。异常是一个谎言,因为该字段确实有一个默认值,因为它是在更新之前插入的。

最佳答案

这是DRY/SRP失败的典型案例;为了不重复代码,您创建了一个违反单一职责原则的函数。

INSERT 语句的语义是您期望没有冲突的行; ON DUPLICATE KEY UPDATE 选项只是为了避免处理代码内部的冲突,需要另一个单独的查询。这与 UPDATE 语句截然不同,在后者中您会期望至少存在一个匹配行。

假设 MySQL 只会在 INSERT 不冲突时检查列,并且由于某种原因刚刚从数据库中删除了一行,而您希望执行更新的代码必须处理它不期望的异常。鉴于语句行为的差异,最好将插入和更新逻辑分开。

撇开理论不谈,MySQL 在运行查询时会制定一个执行计划;在 INSERT 语句的情况下,它必须假设它在尝试时可能会成功,因为这是最佳策略。它避免了必须检查索引等后才发现缺少列。

这是根据设计而不是 JDBC 中的错误。

关于由于已设置的 NOT NULL 字段,MySQL DUPLICATE KEY UPDATE 无法更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13403671/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com