sql
,php
,pdo
非常新,我试图在我的项目表中为现有帐户执行插入语句,但它仍然失败。我看不出我哪里出错了。
这是结构
帐户表
id = pk
项目表
id = pk
account_id = fk
project_name = varchar(100)
pm = varchar(100)
apm = varchar(100)
est_start =日期
est_end =日期
contact = varchar(100)
project_status = varchar(100)
comments = text
所有相关字段均为utf8_unicode_ci校对
限制被设置为在XAMPP服务器上对innodb mySQL
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,所以数据库插入失败。
如果您还需要更多信息,我会尝试使用所有代码/信息保持简短和甜蜜。任何帮助表示赞赏。
修改
我在更新代码后发现此错误
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。我是对的吗?
也只是一个fyi,我在插入之前回显了我的变量,它们都被设置了,如果有人想知道的话,它们都不是空的。
答案 0 :(得分: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错误相同 - 所以,你可以使用站点范围的设置来定义行为 - 因此,您将收到错误消息而没有此无用的代码。 虽然无条件回显的错误消息可能会向潜在的攻击者泄露一些敏感信息,但会混淆一个诚实的访客。
- 以后可以添加custom exception handler,但不是必需的。特别是对于新用户,建议使用未处理的异常,因为它们提供的信息非常丰富,有用且安全。
- 仅当您要处理错误本身时才使用
try..catch
- 例如,回滚事务。
答案 1 :(得分:1)
实际上这是一个非索引列的情况。你看我使用的是phpmyadmin而我没有索引列'account id'。这是什么意思?这意味着当我将关系设置为'account_id'时,对于accounts表'id'字段,fk为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设置到另一个表时,你只需要下拉那个名为Internal relation的中间列,并且有一个来自其他表的pk列表.. 或者我认为! 第三列是产生所有差异的原因,如果列没有索引,则不能将其定义为另一个表的fk。
这样做 NOT 工作。
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实际设置为正确的值。我没有意识到这一点。所以无论如何,这就是我如何解决我的问题。我希望这可以帮助将来的某个人