违规:1452无法添加或更新子行:外键约束失败

时间:2016-11-04 17:11:43

标签: php mysql sql

  

首先,它不是重复的!我已经看到了一些有关它的相关问题,我试着按照他们在那些答案中所说的那样做,但是没有用。

这是我的数据库结构的图像 entity relationship diagram

正如你所看到的,一切都很好,正确建立关系当我尝试添加事件时出现此错误:

  

致命错误:带有消息'SQLSTATE [23000]的未捕获异常'PDOException':完整性约束违规:1452无法添加或更新子行:外键约束失败(tvfootballall_streams, CONSTRAINT fk_channels FOREIGN KEY(channel_id)引用channelsID)在C:\ xampp \ htdocs \ aaa \ admin \ addStream中删除更新CASOCE ON UPDATE NO ACTION)' .php:16堆栈跟踪:#0 C:\ xampp \ htdocs \ aaa \ admin \ addStream.php(16):PDOStatement->执行()#1 {main}在C:\ xampp \ htdocs \ aaa \中抛出第16行的admin \ addStream.php

如果我尝试插入频道,我会收到此错误:

  

致命错误:带有消息'SQLSTATE [23000]的未捕获异常'PDOException':完整性约束违规:1452无法添加或更新子行:外键约束失败(tvfootballall_streams, CONSTRAINT fk_events FOREIGN KEY(event_id)引用eventsID)在C:\ xampp \ htdocs \ aaa \ admin \ addStream中删除更新CASOCE ON UPDATE NO ACTION)' .php:31堆栈跟踪:#0 C:\ xampp \ htdocs \ aaa \ admin \ addStream.php(31):PDOStatement->执行()#1 {main}抛出C:\ xampp \ htdocs \ aaa \第31行的admin \ addStream.php

事情是......它将数据插入表,但不会在 all_streams 中插入任何内容

这是我的SQL

DROP TABLE IF EXISTS `all_streams`;
CREATE TABLE `all_streams` (
  `event_id` int(11) DEFAULT '0',
  `stream_id` int(11) DEFAULT '0',
  `channel_id` int(11) DEFAULT '0',
  `date_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  KEY `fk_streams` (`stream_id`),
  KEY `fk_events` (`event_id`),
  KEY `fk_channels` (`channel_id`),
  CONSTRAINT `fk_channels` FOREIGN KEY (`channel_id`) REFERENCES `channels` (`ID`) ON DELETE CASCADE ON UPDATE NO ACTION,
  CONSTRAINT `fk_events` FOREIGN KEY (`event_id`) REFERENCES `events` (`ID`) ON DELETE CASCADE ON UPDATE NO ACTION,
  CONSTRAINT `fk_streams` FOREIGN KEY (`stream_id`) REFERENCES `streams` (`ID`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

这是我的PHP

if(isset($_POST['addStreamsEvents'])){
extract($_POST);
$statement = $db->prepare("INSERT INTO streams (link) VALUES (?)");
$statement->bindParam(1,$stream);
$statement->execute();

$id=$db->lastInsertId();

$statement_join = $db->prepare("INSERT INTO all_streams (event_id,stream_id)VALUES (?,?)");
$statement_join->bindParam(1,$event);
$statement_join->bindParam(2,$id);
$statement_join->execute();
}

if(isset($_POST['addStreamsChannels'])){
    extract($_POST);
    $statement = $db->prepare("INSERT INTO streams (link) VALUES (?)");
    $statement->bindParam(1,$stream);
    $statement->execute();

    $id=$db->lastInsertId();

    $statement_join = $db->prepare("INSERT INTO all_streams (channel_id, stream_id) VALUES (?,?)");
    $statement_join->bindParam(1,$event);
    $statement_join->bindParam(2,$id);
    $statement_join->execute();
}

有人知道我做错了吗?

顺便说一句:

我已经尝试过了:SET FOREIGN_KEY_CHECKS=0;并且无法正常工作..

2 个答案:

答案 0 :(得分:0)

我注意到的第一件事是你在外键约束列上设置了默认值零,但是you said in the comments,零值不作为主键存在,所以你的插入失败,因为您没有在查询中指定它。

`event_id` int(11) DEFAULT '0',
`stream_id` int(11) DEFAULT '0',
`channel_id` int(11) DEFAULT '0',

如果您要继续使用此默认设置,则必须明确插入NULL或有效ID。

此处a working example改变了这一点:

INSERT INTO all_streams (event_id,stream_id) VALUES (?,?)

进入这个:

INSERT INTO all_streams (event_id,stream_id,channel_id) VALUES (?,?, NULL)

但是,我认为最好的办法是删除这些默认值,因为它对我来说没有意义which works also

如果没有看到您的表单,则不清楚,但您可能没有注意到的另一个问题是,您为event和{{1}使用了名为event_id的相同输入值}}

channel_id

在这里the working example尽可能地重现我可以填写表格和表格的缺失值。

$statement_join = $db->prepare("INSERT INTO all_streams (event_id,stream_id)VALUES (?,?)");
$statement_join->bindParam(1,$event);
...
$statement_join = $db->prepare("INSERT INTO all_streams (channel_id, stream_id) VALUES (?,?)");
$statement_join->bindParam(1,$event);
<form method="POST">
    <input type="hidden" name="addStreamsEvents"/>
    <input type="hidden" name="addStreamsChannels"/>

    <label for="stream">Stream</label>
    <input type="text" name="stream"/>

    <label for="event">Event or Channel ID</label>
    <input type="number" name="event" value="1"/>

    <input type="submit" value="Submit"/>
</form>

<?php

// returns an instance of PDO
// https://github.com/jpuck/qdbp
$db = require __DIR__.'/streams_Dtm905_A.pdo.php';

if(isset($_POST['addStreamsEvents'])){
    extract($_POST);
    $statement = $db->prepare("INSERT INTO streams (link) VALUES (?)");
    $statement->bindParam(1,$stream);
    $statement->execute();

    $id=$db->lastInsertId();

    $statement_join = $db->prepare("INSERT INTO all_streams (event_id,stream_id) VALUES (?,?)");
    $statement_join->bindParam(1,$event);
    $statement_join->bindParam(2,$id);
    $statement_join->execute();
}

if(isset($_POST['addStreamsChannels'])){
    extract($_POST);
    $statement = $db->prepare("INSERT INTO streams (link) VALUES (?)");
    $statement->bindParam(1,$stream);
    $statement->execute();

    $id=$db->lastInsertId();

    $statement_join = $db->prepare("INSERT INTO all_streams (channel_id, stream_id) VALUES (?,?)");
    $statement_join->bindParam(1,$event);
    $statement_join->bindParam(2,$id);
    $statement_join->execute();
}

答案 1 :(得分:0)

简而言之,您可以引用不存在的记录(空值)。

例如,您想将外键添加到中,并且您已经在表all streams中有一条记录,其中event_id = 14,stream_id = 2,{{1} } = 91(反之亦然,但已经有约束条件,但想添加一条记录),但是表channel_id中没有events = 14的记录,或者/并且{{ 1}}表中的id = 2或/并且stream表中的id = 91没有记录。

此外,不允许您设置外键的默认值!