区分不同密钥

时间:2015-06-01 18:47:43

标签: php mysql

我有一张桌子,可以保持教室和学生之间的联系。学生只能在表格中有一个条目。每个学生在教室里都有一个数字,必须是该教室的独特之处。我已经设置了像这样的索引

Columns: classroom_id, user_id, user_no

Primary key (classroom_id, user_id)
Unique key (classroom_id, user_no)

到目前为止一切顺利。学校管理部门有权将学生添加到教室,有两种情况我难以区分。一个是当一个学生已经在桌子上,即有一个指定的教室,另一个是在教室里已经有一个具有给定数量的学生时。

在我的PHP代码中,这是我如何处理第一个场景

try {

    $db->prepare($sql)->execute(...);

    return true;
} catch (\PDOException $ex) {

    if ($ex->errorInfo[1] === 1062) {
        \Data::setError('student_id', 'This student already has an assigned class room');
        return false;
    }
}

问题是,现有的学生(在表中)和现有的数字都会引发错误,代码为1062重复条目。我看到的唯一可以用来区分这两种情况的是异常的errorInfo属性中的第三个元素,它详细解释了哪个键导致查询失败。我不想这样做,因为这样我将在我的应用程序和密钥名称之间创建一个依赖项,这可能导致程序停止正常工作,并且在将来忘记这一点时可能会造成很多麻烦,或者如果其他人当时正在维护它,那么上帝是禁止的。

发送一个额外的查询只是为了找出它不是一个好的解决方案。

要澄清,问题是:如何用相同的代码区分这两个错误?

编辑:基本的问题解决,我只是继续并在错误信息中设置其中任何一个可能是错误,但这是一个非常有趣的问题,我想找到解决方案,所以我不会删除这个问题。

1 个答案:

答案 0 :(得分:0)

另一种可能性是插入会违反两个唯一键的。 MySQL的错误只能识别​​一个。

要找出答案,你真的必须运行另一个查询来查看表中已有哪些行。

  ( SELECT 'classroom_id and user_id already exist' AS reason_
      FROM mytable t
     WHERE t.classroom_id = :classroom_id
       AND t.user_id      = :user_id
     LIMIT 1
  )
  UNION ALL
  ( SELECT 'classroom_id and user_name already exist' AS reason_
      FROM mytable t
     WHERE t.classroom_id = :classroom_id2
       AND t.user_name    = :user_name
     LIMIT 1
  )

两个SELECT中的任何一个都可能返回一行。如果您返回两行,则不知道它们是来自同一行,还是来自两个不同的行。如果需要透露,则需要修改查询。