【问题标题】:Is this query really unsafe?这个查询真的不安全吗?
【发布时间】:2015-03-14 22:22:50
【问题描述】:

以下查询正在按需要执行,但是当我通过远程管理工具 (heidisql) 执行时,我收到一条消息:

注意:使用语句格式写入二进制日志的不安全语句,因为 BINLOG_FORMAT = STATEMENT。从另一个表中选择后写入具有自动增量列的表的语句是不安全的,因为检索行的顺序决定了将写入哪些(如果有)行。此顺序无法预测,主从可能会有所不同。

查询如下:

UPDATE t016sliderimages AS t016

JOIN t004images AS t004
ON t004.ImageID = t016.ImageID

JOIN t034imagealbums AS t034
ON t004.ImageAlbumID = t034.ImageAlbumID


SET t016.SliderNumber = t016.SliderNumber - 1

WHERE t034.ItemID = 32
AND t016.SliderNumber > 4

这可能是误报还是此查询有问题,即使它似乎正在执行所需的操作?

【问题讨论】:

    标签: mysql sql database mariadb


    【解决方案1】:

    例如,如果您有一个包含键值 1、2、3 的表,并且您希望这些值从零开始,您可以说 set key = key - 1,对于大多数 DBMS,这已经足够了。然而,在这方面,MySQL 与大多数 DBMS 不同。假设它首先尝试更新 ID=3 的行。减一,新 ID 为 2。但表中已经有一行 ID=2。糟糕的魔力。

    所以,这仅适用于 MySQL(据我所知),您必须明确指定 order by 以便不会发生此类冲突。在这种情况下,您必须强制它从最低值开始并进行处理。

        SET t016.SliderNumber = t016.SliderNumber - 1
    WHERE   t034.ItemID = 32
        AND t016.SliderNumber > 4
    ORDER BY t016.SliderNumber ASC;
    

    但是,您从大于 4 的值开始。因此,如果高于 4 的第一个值是 5,那么您必须确保没有值 = 4。KnoWhaddaMean?

    更新:我为这种行为找到了 reference。查找以“如果 UPDATE 语句包含 ORDER BY 子句...”开头的段落

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-29
      • 1970-01-01
      • 2012-10-14
      • 2012-06-12
      • 2010-09-06
      • 1970-01-01
      相关资源
      最近更新 更多