如何在同一查询中同时使用ON DUPLICATE KEY和REPLACE INTO


How to use both ON DUPLICATE KEY and REPLACE INTO in the same query?

我有一个这样的表:

// AcceptedAnswer
+----+---------+-------------+-----------+
| id | user_id | question_id | answer_id |
+----+---------+-------------+-----------+
| 1  | 123     | 4335345     | 3342434   |
| 2  | 345     | 4565546     | 3443565   |
+----+---------+-------------+-----------+
// user_id : the id of that person who is author of question

此外,我在这三列上有一个唯一索引组:(user_id, question_id, answer_id)

有三种情况:

  • 当没有任何可接受的答案并且OP(user_id)想要接受asnwer时
  • 当有一个已接受的答案并且OP想要撤消它时
  • 当有一个已接受的答案,并且OP希望将其更改为另一个答案时

我的剧本也适用于前两种情况。但这对第三种情况不起作用。我该如何实现?

这是我的脚本:

try {
    // DB connection here
    // This SELECT statement validates whether user_id is the author of the question     
    $stmt = $db_con->prepare("INSERT INTO AcceptedAnswer(user_id, question_id, answer_id)
                              SELECT ?,?,?
                              FROM questions q
                              WHERE q.id = ? and q.author_id = ? limit 1;");
    $stmt->execute( array( $_SESSION["Id"], $question_id, $answer_id,
                           $question_id, $_SESSION["Id"] ) );

} catch(PDOException $e) {
    // undo acceptance
    if ((int) $e->getCode() === 23000) {
    $stmt = $dbh_conn->prepare(" DELETE FROM AcceptedAnswer
                                 WHERE user_id = ? AND
                                       question_id = ? AND
                                       answer_id = ? ");
    $stmt->execute(array($_SESSION["Id"], $question_id, $answer_id));
}

例如:(基于上表)

当我通过这个:(123, 4335345, 2353423)(更改接受的答案)时,预期输出:

// AcceptedAnswer
+----+---------+-------------+-----------+
| id | user_id | question_id | answer_id |
+----+---------+-------------+-----------+
| 1  | 123     | 4335345     | 2353423   |
| 2  | 345     | 4565546     | 3443565   |
+----+---------+-------------+-----------+

当我通过这个:(345, 4565546, 3443565)(撤消接受的答案)时,预期输出:

// AcceptedAnswer
+----+---------+-------------+-----------+
| id | user_id | question_id | answer_id |
+----+---------+-------------+-----------+
| 1  | 123     | 4335345     | 2353423   |
+----+---------+-------------+-----------+

首先,不能将这两个查询组合在一起,因为它们是互斥的。

此外,您似乎根本不需要REPLACE INTO。

事实上,您只需要两个查询,一个是带有ONDUplicate的INSERT来接受任何答案,另一个是delete-来不接受。

此外,我只会使用一个简单的条件来查看从表单发送的是接受还是不接受,而不是异常处理

请注意,您应该在if condition独立捕获块中有一个else子句,以便重新引发异常(如果不是预期的)。