почему у меня возникает ошибка типа Uncaught mysqli_sql_exception: невозможно добавить или обновить дочернюю строку: ограничение внешнего ключа не выполнено? - PullRequest
0 голосов
/ 25 марта 2020

У меня такая ошибка, и я знаю, что с ней не так.

Uncaught mysqli_sql_exception: невозможно добавить или обновить дочернюю строку: ограничение внешнего ключа не выполняется (studentsinformation. honor, CONSTRAINT honor_ibfk_1 FOREIGN KEY (ExamineeID) ССЫЛКИ personal ( ExamineeID) НА УДАЛИТЬ КАСКАД НА ОБНОВЛЕНИЕ КАСКАДА) в C: \ xampp \ htdocs \ Practice \ dummy. php: 74 Трассировка стека: # 0 C: \ xampp \ htdocs \ Practice \ dummy. php (74): mysqli_stmt-> execute () # 1 {main} добавляется в C: \ xampp \ htdocs \ Practice \ dummy. php в строке 74

Это мои коды :

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), но в моей ситуации они не распределяются вообще, и только личная таблица была заполнена, в то время как другие пустые и показывают ошибки, подобные этой.

Скрипт моей базы данных, который я хотел, чтобы это было: введите описание изображения здесь

1 Ответ

0 голосов
/ 26 марта 2020

Очень базовый c пример решения проблемы.

ПРИМЕЧАНИЕ предоставленный код может использоваться только в качестве примера и, возможно, поможет вам решить вашу проблему. Я добавил туда столько комментариев, сколько смогу.

Код, размещенный ниже первым, в основном гарантирует, что запись с данными параметрами существует в таблице personal. Эти параметры включают в себя ExamineeID.

Затем он пытается выбрать данные из таблицы honor, используя ExamineeID, сначала удостоверившись, что предыдущие запросы для получения ExamineeID завершены успешно.

Если запись с этим ExamineeID уже существует exsist в honor, тогда ничего не происходит, если такая запись не существует, то она будет вставлена ​​туда

Код работает на структуре базы данных, которую вы предоставили в Эта скрипка

<?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();    
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...