代码之家  ›  专栏  ›  技术社区  ›  Accountant Ù

更新时出现MySQL错误1157,但是我在where子句中使用主键

  •  0
  • Accountant Ù  · 技术社区  · 7 年前

    我有个1157错误

    错误代码:1175您正在使用安全更新模式,并且尝试更新没有使用键列的WHERE的表。 若要禁用安全模式,请在“首选项”->“SQL编辑器”中切换该选项并重新连接。

    当我试图执行这个语句时

    UPDATE ip 
    SET 
        ip_countryCode = 'GB',
        ip_countryName = 'United Kingdom',
        ip_city = 'London' 
    
    WHERE BINARY ip_ip >= INET6_ATON('2.57.77.0') AND 
          BINARY ip_ip <= INET6_ATON('2.57.77.255');
    

    这是 ip 桌子

    CREATE TABLE `ip` (
      `ip_ip` varbinary(16) NOT NULL,
      `ip_last_request_time` timestamp(3) NULL DEFAULT NULL,
      `ip_city` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT '',
      `ip_countryCode` varchar(3) COLLATE utf8mb4_unicode_ci DEFAULT '',
      `ip_countryName` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT '',
    /*
    more 23 columns have been omitted for readability
    */
      PRIMARY KEY (`ip_ip`),
      KEY `countryCode_index` (`ip_countryCode`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
    

    我在这里做错什么了为什么我会犯这个错误 初级的 where子句中使用了key?

    2 回复  |  直到 7 年前
        1
  •  2
  •   Barmar    7 年前

    仅仅使用键列是不够的,您必须以允许使用索引来查找行的方式使用它。从 documentation :

    如果优化器决定不对键列使用索引,则UPDATE和DELETE语句可能在安全更新模式下产生错误,即使在WHERE子句中指定了键。

    因为你在测试 BINARY ip_ip 而不仅仅是 ip_ip 它本身不能使用索引,所以您会得到错误。

    你能用一个函数来转换 INET6_ATON() varbinary ,而不是使用 BINARY 专栏的接线员然后它应该能够使用索引,并且不会出现错误。

    UPDATE ip 
    SET 
        ip_countryCode = 'GB',
        ip_countryName = 'United Kingdom',
        ip_city = 'London' 
    
    WHERE ip_ip BETWEEN CAST(INET6_ATON('2.57.77.0') AS BINARY(16)) AND 
                        CAST(INET6_ATON('2.57.77.255') AS BINARY(16);
    
        2
  •  1
  •   Jim.B    7 年前

    您可以添加 SET SQL_SAFE_UPDATES=0; 在更新查询之前。使用时要小心,因为它可能会进行意外的数据修改。

    或者您可以尝试包含列 ip_countryCode 在你的where子句中。

    UPDATE ip 
    SET 
        ip_countryCode = 'GB',
        ip_countryName = 'United Kingdom',
        ip_city = 'London' 
    
    WHERE BINARY ip_ip >= INET6_ATON('2.57.77.0') AND 
          BINARY ip_ip <= INET6_ATON('2.57.77.255') AND ip_countryCode <> 'GB';
    

    或者可以删除二进制函数

    WHERE ip_ip >= INET6_ATON('2.57.77.0') AND 
          ip_ip <= INET6_ATON('2.57.77.255');