0

对,非常新sql,我正在尝试在我的项目表中为现有帐户执行插入语句,但它一直失败。我看不出我哪里错了。phppdo

这是结构

帐户表
id = pk

项目表
id = pk
account_id = fk
project_name = varchar(100)
pm = varchar(100)
apm = varchar(100)
est_start = date
est_end = date
contact = varchar(100)
project_status = varchar(100)
comments= text

所有相关字段都是 utf8_unicode_ci 排序规则
限制设置为mySQLXAMPP 服务器上的 innodb db 级联。

php/pdo

<?php

include "$_SERVER[DOCUMENT_ROOT]/core/init.php";

if (empty($_POST) === false) {
    $fk = '';

    $title = $_POST['title'];

    try {
        $query_get_id = $db->prepare("
            SELECT accounts.id
            FROM accounts 
            WHERE accounts.account_name = ?         
        ");

        $query_get_id->bindValue(1, $title, PDO::PARAM_STR);
        $query_get_id->execute();
        $count = $query_get_id->rowCount();

        if ($count > 0) {
            while ($row = $query_get_id->fetch(PDO::FETCH_ASSOC)) {             
                $fk = $row['id'];
            }           
        } 

    } catch(PDOException $e) {
        die($e->getMessage());
    }

    $pn = $_POST['project_name'];
    $ppm = $_POST['project_pm'];
    $papm = $_POST['project_apm'];  
    $pc = $_POST['project_contact'];
    $pes = $_POST['project_est_start'];
    $pee = $_POST['project_est_end'];
    $ps = $_POST['project_status']; 
    $pcom = $_POST['project_comments']; 

    try {
        $query_ip = $db->prepare('INSERT INTO projects (account_id, project_name, pm, apm, est_start, est_end, contact, project_status, comments) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)');
        $query_ip->bindValue(1, $fk, PDO::PARAM_STR);       
        $query_ip->bindValue(2, $pn, PDO::PARAM_STR);
        $query_ip->bindValue(3, $ppm, PDO::PARAM_STR);
        $query_ip->bindValue(4, $papm, PDO::PARAM_STR);
        $query_ip->bindValue(5, $pes, PDO::PARAM_STR);
        $query_ip->bindValue(6, $pee, PDO::PARAM_STR);
        $query_ip->bindValue(7, $pc, PDO::PARAM_STR);
        $query_ip->bindValue(8, $ps, PDO::PARAM_STR);
        $query_ip->bindValue(9, $pcom, PDO::PARAM_STR);         

        $query_ip->execute();

        echo 'Project Created';     

    } catch(PDOException $e) {
        die($e->getMessage());
    }

} else {
    echo 'project creation failed';
}
?>

这不会吐出任何错误,但我感觉我没有正确设置 fk,因此 db insert 失败。

如果您需要更多信息,请询问,即使有所有代码/信息,我也会尽量保持简短和甜蜜。任何帮助表示赞赏。

编辑

更新代码后,我现在发现了这个错误

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`fsi`.`projects`, CONSTRAINT `projects_ibfk_1` FOREIGN KEY (`id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)' in C:\xampp\htdocs\include\fill_project.php:50 Stack trace: #0 C:\xampp\htdocs\include\fill_project.php(50): PDOStatement->execute() #1 {main} thrown in C:\xampp\htdocs\include\fill_project.php on line 50

第 50 行是使用此代码执行语句的位置

$query_ip->execute();

我太新了,无法完全理解这个错误。我的猜测是我的第一个怀疑是正确的,我没有正确设置我的 fk。我对吗?

同样仅供参考,我在插入之前回显了我的变量,它们都已设置,如果有人想知道,它们都不是空的。

4

2 回答 2

3

这不会吐出任何错误

这是你的主要问题。
并且必须是您最关心的问题。
您必须确保如果发生错误 - 您将能够看到、阅读和理解它。
虽然没有错误消息,但您的工作更像是赌博而不是编程。

一旦你得到它 - 你可以修复它或通过谷歌搜索获得更多解释。错误消息的搜索结果是最相关的。

为了能够看到 PDO 错误,必须将PDO errmode设置为异常。异常在很多方面都优于常规错误:它们始终包含堆栈跟踪,可以使用 try..catch 捕获它们或使用专用错误处理程序进行处理。即使未经处理,它们也会作为常规 PHP 错误提供所有重要信息,遵循站点范围的错误报告设置。

请注意,将此模式设置为连接选项将使 PDO 在连接错误时也抛出异常,这非常重要。
因此,这是一个正确创建 PDO 连接的示例:

$dsn = "mysql:host=$host;dbname=$db;charset=utf8";
$opt = array(
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    // other options 
);
$pdo = new PDO($dsn, $user, $pass, $opt);

以这种方式连接,您将始终收到在查询执行期间发生的所有数据库错误的通知。请注意,您必须能够看到一般的 PHP 错误。在实时站点上,您必须查看错误日志,因此,设置必须是

error_reporting(E_ALL);
ini_set('display_errors',0);
ini_set('log_errors',1);

在本地开发服务器上,可以在屏幕上出错:

error_reporting(E_ALL);
ini_set('display_errors',1);

当然,您永远不应该@在 PDO 语句前使用错误抑制运算符 ( )。

另外,由于许多不好的例子告诉你将每个 PDO 语句包装成try..catch块,我必须做一个明确的说明:

不要使用 try..catch 运算符来回显错误消息。未捕获的异常已经非常适合此目的,因为它的行为方式与其他 PHP 错误相同 - 因此,您可以使用站点范围的设置来定义行为 - 因此,您将获得没有这些无用代码的错误消息。 虽然无条件回显的错误消息可能会向潜在的攻击者透露一些敏感信息,但会使诚实的访问者感到困惑。

于 2013-07-27T06:35:42.510 回答
1

这实际上是一个非索引列的情况。你看我正在使用 phpmyadmin 并且我没有索引列“帐户 ID”。这是什么意思?这意味着当我将关系设置为“account_id”时,帐户表的“id”字段是 fk。它实际上在我的“项目”表上默认为“id”,因为那是唯一的索引列。因此,如果您迷路了,这里有一个快速可视化。

如果您对 'phpmyadmin' 非常陌生,就像我只是在您希望查看的表格上单击“结构”,然后单击表格底部的“关系视图”。

你应该看到像这样的东西

Column______Internal relation_______Foreign key constraint (INNODB)
id          <blank dropdown>        <blank drop down>
account_id  <blank dropdown>        no index found!
name        <blank dropdown>        no index found!   

现在,当您想将 fk 设置为另一个表时,您只需下拉名为内部关系的中间列,并且有一个来自其他表的 pk 列表..或者我想!第三列是所有不同之处,如果该列没有索引,则不能将其定义为另一个表的 fk。

所以这样做是行不通的。

Column______Internal relation_______Foreign key constraint (INNODB)
id          <blank dropdown>        <blank drop down>
account_id  <db.accounts.id>        no index found!
name        <blank dropdown>        no index found!

您必须首先转到表格的结构视图,单击所需列上的“索引”,然后您的屏幕将如下所示

Column______Internal relation_______Foreign key constraint (INNODB)
id          <blank dropdown>        <blank drop down>
account_id  <blank dropdown>        <blank drop down>
name        <blank dropdown>        no index found!

你可以选择你的fk,然后它看起来像这样

Column______Internal relation_______Foreign key constraint (INNODB)
id          <blank dropdown>        <blank drop down>    
account_id  <db.accounts.id>         <`db`.`accounts`.`id`> ON DELETE <CASCADE> ON UPDATE <CASCADE>
name        <blank dropdown>        no index found!

然后你的 fk 实际上设置为正确的值。我不知道这一点。所以无论如何,这就是我解决问题的方法。我希望这对将来的人有所帮助

于 2013-07-27T15:51:41.480 回答