为什么出现像未捕获的mysqli_sql_exception之类的错误:无法添加或更新子行:外键约束失败?

问题描述 投票:-1回答:1

我遇到这样的错误,idk为什么会出错。

Uncaught mysqli_sql_exception:无法添加或更新子行:外键约束失败(studentsinformationhonor,CONSTRAINT honor_ibfk_1外键(ExamineeID))参考personalExamineeID)ON在C:\ xampp \ htdocs \ Practice \ dummy.php:74中删除级联更新堆栈:#0 C:\ xampp \ htdocs \ Practice \ dummy.php(74):mysqli_stmt-> execute()#1 {main}在第74行的C:\ xampp \ htdocs \ Practice \ dummy.php中抛出

这些是我的代码:

else{


        $sql = "SELECT FirstName, MiddleName, LastName, LastSchoolAttended From personal Where FirstName = ? And MiddleName = ? And LastName = ? And LastSchoolAttended = ? Limit 1";
        $sqlhonor = "SELECT Honor1, Honor2, Honor3, Honor4 From honor Where Honor1 = ? And Honor2 = ? And Honor3 = ? And Honor4 = ? Limit 0";
        $sqlparent = "SELECT Father, EducationalFather, Mother, EducationalMother, Guardian, Occupation From parent Where Father = ? And EducationalFather = ? And Mother = ? And EducationalMother = ? AND Guardian = ? AND Occupation = ? Limit 0";

    if ($stmt = $conn->prepare($sql)); {

        $INSERTpersonal = "INSERT INTO personal (FirstName, MiddleName, LastName, Age, HomeAddress, ContactNumber, LastSchoolAttended, Strand, SchoolAddress, Adviser) values (?,?,?,?,?,?,?,?,?,?)";

        $stmt -> bind_param("ssss", $FirstName,$MiddleName,$LastName,$LastSchoolAttended);
        $stmt -> execute();
        $stmt -> bind_result($FirstName,$MiddleName,$LastName,$LastSchoolAttended);
        $stmt -> store_result();
        $rnum = $stmt -> num_rows;

        if ($rnum == 0 ) {  
            $stmt->close();
            $stmt = $conn -> prepare($INSERTpersonal);
            $stmt -> bind_param("sssisissss", $FirstName,$MiddleName,$LastName,$Age,$HomeAddress,$ContactNumber,$LastSchoolAttended,$Strand, $SchoolAddress,$Adviser);
            $stmt -> execute(); 
        }
    }
     if ($stmthonor = $conn->prepare($sqlhonor)) {
                $INSERThonor = "INSERT INTO honor (Honor1,Honor2,Honor3,Honor4) values (?,?,?,?)";
                $stmthonor -> bind_param("ssss", $Honor1,$Honor2,$Honor3,$Honor4);
                $stmthonor -> execute();
                $stmthonor -> bind_result($Honor1,$Honor2,$Honor3,$Honor4);
                $stmthonor -> store_result();
                $rnum = $stmthonor -> num_rows;

            if ($rnum == 0 ) {  
            $stmthonor->close();
            $stmthonor = $conn -> prepare($INSERThonor);
            $stmthonor -> bind_param ("ssss", $Honor1, $Honor2, $Honor3, $Honor4);  
            $stmthonor -> execute();    
        }
    }

        if ($stmtparent = $conn -> prepare ($sqlparent)) {
            $INSERTparent = "INSERT INTO parent (Father, EducationalFather,Mother,EducationalMother,Guardian,Occupation) values (?,?,?,?,?,?)";
            $stmtparent -> bind_param("ssssss", $Father,$EducationalFather,$Mother,$EducationalMother, $Guardian, $Occupation);
            $stmtparent -> execute();
            $stmtparent -> bind_result($Father,$EducationalFather,$Mother,$EducationalMother,$Guardian ,$Occupation );
            $stmtparent -> store_result();
            $rnum = $stmtparent -> num_rows;

            if ($rnum == 0 ) {  
            $stmtparent->close();
            $stmtparent = $conn -> prepare($INSERTparent);  
            $stmtparent -> bind_param ("ssssss", $Father, $EducationalFather, $Mother, $EducationalMother, $Guardian, $Occupation); 
            $stmtparent -> execute();
        }
    }

}

例如,如果我要填写所需的信息,我希望将它们分发到自己的表中,但仍保持相互连接(这就是我分配FK的原因),但是在我的情况是,他们根本没有分发,只填了个人表,而其他人则是空的,并显示了类似的错误。

我希望数据库成为:enter image description here

php mysql syntax
1个回答
0
投票

解决问题的非常基本且非常糟糕的例子。

NOTE提供的代码只能用作示例,也许可以帮助您解决问题。我在这里尽可能多地发表评论。

首先发布在下面的代码基本上可以确保personal表中存在具有给定参数的记录。这些参数包括ExamineeID。

接下来,它首先尝试使用ExamineeID从honor表中选择数据,并确保先前成功完成ExamineeID的查询。

如果具有此ExamineeID的记录已存在于honor中,那么什么也不会发生,如果该记录不存在,则将其插入其中

该代码正在处理您在This fiddle中提供的数据库结构,>

<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); // Turn on mysqli exeptions. Much better than errors.
$conn = new mysqli('localhost', 'user', 'pass', 'db'); //Initialize Db connection

// Generic values for testing
$FirstName = "test";
$MiddleName = "test";
$LastName = "test";
$Age = 1000;
$HomeAddress = "test";
$ContactNumber = 1000;
$LastSchoolAttended = "test";
$Strand = "test";
$SchoolAddress = "test";
$Adviser = "test";
$Honor1 = "test";
$Honor2 = "test";
$Honor3 = "test";
$Honor4 = "test";
$Father = "test";
$EducationalFather = "test";
$Mother = "test";
$EducationalMother = "test";
$Guardian = "test";
$Occupation = "test";
$ExamineeID;

/**
*
* Pay great attention. You have to actually select ExamineeID from table personal, so you need to add it as a selected param.
* Also we limit our result to a single row, ideally this whould not be done with LIMIT 1,
* but in reality we don't have any other way of making sure only one record is selected, using provided.info.
* As I understand it an ExamineeID which solves the selection problem can actually be unknown on the time of selection
*
*/
$sql = "SELECT ExamineeID, FirstName, MiddleName, LastName, LastSchoolAttended From personal Where FirstName = ? And MiddleName = ? And LastName = ? And LastSchoolAttended = ? LIMIT 1";

/**
*
* Pay even greater attention. Honor1, Honor2, Honor3,Honor4 are being selected and should non be in that where clause.
* Determining correct values that should be selected is based on ExamineeID, which should be somehow provided.
* but in reality we don't have any other way of making sure only one record is selected, using provided.info.
* As I understand it an ExamineeID which solves the selection problem can actually be unknown on the time of selection
*
*/
$sqlhonor = "SELECT Honor1, Honor2, Honor3, Honor4 From honor Where ExamineeID = ?";

/**
*
* This statements doesn't relate to problem in any way. Any queries will be omitted as they just bring confusion
*
*/
$sqlparent = "SELECT Father, EducationalFather, Mother, EducationalMother, Guardian, Occupation From parent Where Father = ? And EducationalFather = ? And Mother = ? And EducationalMother = ? AND Guardian = ? AND Occupation = ?";

$stmt = $conn->prepare($sql); // You don't need this if. If this fails then you will get exeption.

$stmt->bind_param("ssss", $FirstName,$MiddleName,$LastName,$LastSchoolAttended);
$stmt->execute();
$stmt->bind_result($ExamineeID,$FirstName,$MiddleName,$LastName,$LastSchoolAttended);
$stmt->store_result(); // As I understand it store_result() doesn't actually fill values specified in bind_result().
$stmt->fetch(); // fetch on the other hand fills  bind_result variables.
$stmt->close();

if (!isset($ExamineeID)) {  // We don't check the number of rows, we check if and ExamineeID was actually found in previous query
  $INSERTpersonal = "INSERT INTO personal (FirstName, MiddleName, LastName, Age, HomeAddress, ContactNumber, LastSchoolAttended, Strand, SchoolAddress, Adviser) values (?,?,?,?,?,?,?,?,?,?)";
  $stmt = $conn->prepare($INSERTpersonal);
  $stmt->bind_param("sssisissss", $FirstName,$MiddleName,$LastName,$Age,$HomeAddress,$ContactNumber,$LastSchoolAttended,$Strand, $SchoolAddress,$Adviser);
  $stmt->execute();
  $stmt->close();

  // After we add a value to personal table we have to re-select all values.
  $stmt = $conn->prepare($sql);
  $stmt->bind_param("ssss", $FirstName,$MiddleName,$LastName,$LastSchoolAttended);
  $stmt->execute();
  $stmt->bind_result($ExamineeID,$FirstName,$MiddleName,$LastName,$LastSchoolAttended);
  $stmt->store_result();
  $stmt->fetch();
  $stmt->close();
}

//Here 
if (isset($ExamineeID)) { // We only need to check that we actually found a $ExamineeID earlier.
  $stmthonor = $conn->prepare($sqlhonor);
  $stmthonor->bind_param("s",$ExamineeID); // We need to bind only a single value as I pointed out earlier.
  $stmthonor->execute();
  $stmthonor->bind_result($Honor1,$Honor2,$Honor3,$Honor4);
  $stmthonor->store_result();
  $stmthonor->fetch(); // Again fetch is needed to actually fill Honor vars

  $rnum = $stmthonor->num_rows;
  $stmthonor->close();
  // If no entries that have ExamineeID we found earlier exist in Database.
  if ($rnum == 0 ) {  
    $INSERThonor = "INSERT INTO honor (Honor1,Honor2,Honor3,Honor4,ExamineeID) values (?, ?, ?, ?, ?)"; // We need to insert 5 values!!

    $stmthonor = $conn->prepare($INSERThonor);
    // We actually insert a record with provided ExamineeID, because earlier there was no such record.
    $stmthonor->bind_param ("ssssi", $Honor1, $Honor2, $Honor3, $Honor4, $ExamineeID); 
    $stmthonor->execute();   
    $stmthonor->close();    
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.