【问题标题】:PDO insert into MySQL Database not working with another PDO queryPDO 插入 MySQL 数据库不能与另一个 PDO 查询一起使用
【发布时间】:2015-04-10 13:30:11
【问题描述】:

(我不知道标题是否具有描述性。我不确定问题出在哪里,所以想出一个好的标题有点困难。)

所以事情就是这样。我想使用 PDO 将值(来自 HTML 表单)插入 MySQL 数据库。

到目前为止一切顺利。我设法获得了 $_POST['xyz'] 值并成功地将它们插入到数据库中。但现在我想确保只有一行具有相同的电子邮件地址 ($email) 和相同的问题 ID ($qid)。正如您在代码中看到的那样,我通过检查行数来做到这一点。不确定这是否是一个好方法。

现在我不能成功地插入两行具有相似电子邮件地址的行,但由于某种原因,我无法插入任何其他电子邮件地址的行。一直试图弄清楚我做错了什么,但不能。所以这里是代码。希望你能看到我在那里做了什么(因为我看不到)。

try {
        $cnnxn = new PDO("mysql:host=$db_host;dbname=$db_name", $db_username, $db_password);
    } catch (PDOException $e2) {
        die("ERROR: " . $e2->getMessage());
    }

    $query2 = $cnnxn->prepare("SELECT count(*) as cnt FROM grdj_replies WHERE email = :email AND question_id = :qid");
    $query2->bindParam(':email', $email);
    $query2->bindParam(':qid', $qid);

    $isQueryOk = $query2->execute();

    if ($isQueryOk) {
      $count = $query2->fetchColumn();
      } else {
      trigger_error('Error executing statement.'); 
    }
    $query2->closeCursor();


      if ($count > 0){
          echo '<div class="tools-alert tools-alert-red"><p>Sähköpostiosoitteellasi <strong>'.$email.'</strong> löytyy jo tallennettu vastaus tähän tehtävään. Jos haluat muuttaa vastausta, seuraa sähköpostiosoitteeseesi lähetetyn viestin ohjeita.<p>';
          echo '<p>(<a href="#">Klikkaa tästä, jos haluat lähettää ohjeet uudestaan osoitteeseen '.$email.'</a>.)</p></div>';
      }

    else {

        $cnnxn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTIONS);
        $cnnxn->exec("SET NAMES utf8");
        $query = $cnnxn->prepare("INSERT INTO grdj_replies (question_id, last_name, first_name, email, question_number, answer, status, accesstoken) VALUES (:qid, :lastname, :firstname, :email, :questionnumber, :answer, :status, :accesstoken)");
        $query->bindParam(':qid', $qid);
        $query->bindParam(':lastname', $last_name);
        $query->bindParam(':firstname', $first_name);
        $query->bindParam(':email', $email);
        $query->bindParam(':questionnumber', $question_number);
        $query->bindParam(':answer', $answer);
        $query->bindParam(':status', $status);
        $query->bindParam(':accesstoken', $accesstoken);
        $query->execute();

        if ($query !== false)
                    {
                        print "<div class=\"tools-alert tools-alert-green\">Vastauksesi on tallennettu!</div>";
                    }
        $query->closeCursor();
        $cnnxn = null; 
    }

【问题讨论】:

    标签: php mysql pdo


    【解决方案1】:

    首先,您正在使用 ->bindParam(),其中 ->bindValue() 就足够了(也许更合适)。

    你问你的输入处理是否是一种很好的做事方式:我看不到那个代码。与其使用超全局变量,不如使用 filter_input() / filter_input_array()

    您描述的问题可能不在 PHP 代码中:仔细查看数据库索引。您是否按 qid 对 grdj_replies 进行了唯一索引(例如,您是否仅在“qid”上有一个主键)?对于同一个 qid,是否还有其他不充分的索引阻止您在表中插入额外的行?或许你应该通过qid、email联合唯一索引。

    您将错误处理应用于 PDO 对象(数据库连接)的创建;在这种情况下,我经常发现将错误处理(try/catch,$error->getMessage())应用于 SQL 语句的执行是很有帮助的(这样,你可以看到数据库试图告诉你什么. 它是否抛出了不运行查询的借口/解释?)

    【讨论】:

    • 这很有趣。我没有收到任何错误信息。脚本只是没有运行。根据 HTML 代码,它在 try/catch 或插入时死亡。我确实创建了一个联合唯一索引,但这也无济于事。我会尝试你的其他建议并回到这个问题。
    • 您是否在脚本目录中查看过错误日志?您是否尝试过添加“echo('TEST');”说明问题出在哪里?
    • 哦,你是对的!问题是主键列(id)没有开启自增,但是需要唯一值,所以当然不行!
    【解决方案2】:

    我建议你使用 MySQL 唯一索引:

    ALTER TABLE `grdj_replies`   
      ADD  UNIQUE INDEX `UNIQUE_IDX` (`email`, `question_id`);
    

    现在 MySQL 将在插入新行之前确保没有其他行具有相同的电子邮件和 question_id,您不必“手动”检查它。 在已有相同数据的情况下,INSERT 请求会失败。

    【讨论】:

    • 不错!现在,最终用户如何知道该电子邮件/问题 ID 组合是否已经存在一行?我如何将这些信息传递给他们(而不是“插入”请求失败)。
    • 看看this thread,这就是您可能检测到表中已经存在相同数据的方式。现在,当发生此错误时,只需向用户显示一条消息,告诉他已经有人具有相同的信息。
    猜你喜欢
    • 1970-01-01
    • 2018-04-06
    • 2012-04-21
    • 1970-01-01
    • 2014-11-26
    • 2015-02-04
    • 2017-08-30
    • 1970-01-01
    相关资源
    最近更新 更多