【问题标题】:MySQLi does not return error codeMySQLi 不返回错误代码
【发布时间】:2015-01-19 20:35:56
【问题描述】:

在我的 MySQL 数据库中,我有一个表“table1”,在“名称”列上设置了唯一约束 - 我想防止重复名称。

如果表中已经有姓名“约翰”,则此代码:

$db=new mysqli(...);

$sql="INSERT INTO table1 SET id=10,name='John'";

if(!$db->query($sql))
{
  if($db->errno==1062)
  {
    throw new InsertNonUniqueException(...);
  }
  else
  {
    throw new InsertException(...);
  }
}

应该抛出 InsertNonUniqueException() (我自己的异常)。相反,它会抛出 InsertException()。

查询的执行返回false,执行进入if()循环。 $db->row_affected 也是 -1 但问题是 $db->e​​rrno 总是 O(应该是 1062)!!!所以我无法检测到我的插入错误是由违反 name 列的唯一键约束引起的!

不知道为什么mysqli在违反唯一键约束时不返回1062码!

【问题讨论】:

  • 您确定您的列上有唯一索引吗?
  • 是的,我确定,因为如果我在 SQL 命令行中执行相同的 sql,它会返回“错误代码 1062,SQL 状态 23000:重复条目 'John' for key...”
  • echo $db->e​​rrno 看看是怎么说的。
  • 您的 sql 代码在这里运行良好 - mysql 5.5.16。我假设'throw InsertNonUniqueException'是一个打字错误,因为它应该是:'throw new insertNonUniqueException(...'。
  • 试试INSERT INTO table1 (id, name) VALUES (10, 'John')

标签: php mysql mysqli


【解决方案1】:

我不能发表评论,所以想在这里问你。

请提供SHOW CREATE TABLE table1;的结果

我无法使用您的代码和下一个表格重现您的问题:

CREATE TABLE `table1` (
`name` varchar(11) COLLATE utf8_unicode_ci NOT NULL,
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

【讨论】:

    【解决方案2】:

    是这里唯一一个认为你的 SQL 语法有错误的人吗?.. INSERT INTO 中没有SET 的空间,因为你只能在UPDATE 语句中使用SET(假设你在 5.5 或更低版本中使用 MySQL)。

    INSERT INTO 语法如下(如described in the docs):

    INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
        [INTO] tbl_name [(col_name,...)]
        SELECT ...
        [ ON DUPLICATE KEY UPDATE col_name=expr, ... ]
    

    INSERT INTO tbl_temp2 (fld_id)
      SELECT tbl_temp1.fld_order_id
      FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;
    

    试试这样:

    <?php
    $sql="INSERT INTO table1 (id, name) VALUES ('10', 'John')";
    ...
    

    【讨论】:

    • 你可以在INSERT INTO中使用SET和mysql:doc
    • @Meeuuuhhhh 好的,在 MySQL 5.6 及更高版本中。在 5.5 以下不支持。
    【解决方案3】:

    第一步

    确保表具有唯一键

    SHOW CREATE TABLE table1
    

    预期结果

    CREATE TABLE `table1` (
        `id` INT(11) default NULL,
        `name` varchar(11) COLLATE utf8_general_ci NOT NULL,
        PRIMARY KEY (id),
        UNIQUE KEY `name` (`name`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci
    

    如果有UNIQUE KEY name (name),我们就有一个唯一的密钥

    第二步

    尝试更改您的代码

    $db  = new mysqli(...);
    
    // first insert
    if( !$db->query("INSERT INTO table1 (id, name) VALUES (10, 'John')") ) {
      throw new Exception($db->error);
    }
    
    // second insert (for me raise:  Duplicate entry 'John' for key 'name')
    if( !$db->query("INSERT INTO table1 (id, name) VALUES (11, 'John')") ) {
      throw new Exception($db->error);
    }
    

    请尝试这两个步骤

    附注:如果您有重复的名称和 ID,则只会在消息中返回遇到的第一个重复。

    【讨论】:

      【解决方案4】:

      我对您的代码的唯一问题是:

      已设置您的表格和列。

      我在表上设置了一个唯一索引。我做了 .. 在一个两列表格上的东西,以确保它有效。

      你错过了'新' “抛出异常”时的关键字。 这是您发布的代码中我能找到的唯一错误。

      即: throw new Exception('除以零。'); // 示例取自 PHP 手册。

      【讨论】:

        猜你喜欢
        • 2012-08-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-04
        • 2014-07-03
        • 1970-01-01
        • 1970-01-01
        • 2017-06-03
        相关资源
        最近更新 更多