Грешка при създаване на външен ключ

djidja83

Registered
Здравейте отново,

Продължавам с малоумните си питанки, но не мога да се оправя. При опит за задаване на външен ключ на таблица ми излиза следната грешка:

"Грешка при създаване на външен ключ: Can't create table `thesis`.`#sql-728_178` (errno: 150 "Foreign key constraint is incorrectly formed")"

Ето и кода:

<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "thesis";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("За съжаление, MySQL връзката не може да бъде осъществена" . $conn->connect_error);
}
$mysqli ="ALTER TABLE `products`
ADD FOREIGN KEY (`bid`) REFERENCES `blocks`(`id`) ON DELETE RESTRICT ON UPDATE RESTRICT";
if ($conn->query($mysqli) === TRUE) {
echo "Успешно създаване на външен ключ";
} else {
echo "Грешка при създаване на външен ключ: " . $conn->error;
}
$conn->close();
?>

Предварително благодаря!
 
По принцип правих разни промени по таблиците с цел да оправя нещата, но пак не стана. Ето заявките на таблиците.

Products

<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "thesis";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("За съжаление, MySQL връзката не може да бъде осъществена" . $conn->connect_error);
}
$mysqli = "CREATE TABLE Products (
id INT(5) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
product VARCHAR(30) NOT NULL)";
if ($conn->query($mysqli) === TRUE) {
echo "Таблицата е създадена успешно";
} else {
echo "Грешка при създаване на таблицата: " . $conn->error;
}
$conn->close();
?>

Blocks

<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "thesis";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("За съжаление, MySQL връзката не може да бъде осъществена" . $conn->connect_error);
}
$mysqli = "CREATE TABLE Blocks (
id INT(5) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
type VARCHAR(30) NOT NULL,
quantity INT(5) NOT NULL)";
if ($conn->query($mysqli) === TRUE) {
echo "Таблицата е създадена успешно";
} else {
echo "Грешка при създаване на таблицата: " . $conn->error;
}
$conn->close();
?>

В последствие в първата таблица е добавена колона

<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "thesis";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("За съжаление, MySQL връзката не може да бъде осъществена" . $conn->connect_error);
}
$mysqli ="ALTER TABLE `products` ADD `bid` INT NOT NULL AFTER `product`";
if ($conn->query($mysqli) === TRUE) {
echo "Колоната е добавена успешно";
} else {
echo "Грешка при добавяне на колоната: " . $conn->error;
}
$conn->close();
?>

Ето и заявката за външен ключ в последния и вариант

<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "thesis";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("За съжаление, MySQL връзката не може да бъде осъществена" . $conn->connect_error);
}
$mysqli = "SET foreign_key_checks = 0";
$mysqli ="ALTER TABLE `products` ADD CONSTRAINT `products_ibfk_1` FOREIGN KEY (`blocks_id`) REFERENCES `blocks`(`id`) ON DELETE CASCADE ON UPDATE CASCADE";
if ($conn->query($mysqli) === TRUE) {
echo "Успешно създаване на външен ключ";
} else {
echo "Грешка при създаване на външен ключ: " . $conn->error;
}
$conn->close();
?>

Имената на колоните са променени през phpMy Admin и в момента съответстват на тези от последната заявка. Ето и грешката, която ми излиза в момента

Грешка при създаване на външен ключ: Cannot add or update a child row: a foreign key constraint fails (`thesis`.`#sql-728_252`, CONSTRAINT `products_ibfk_1` FOREIGN KEY (`blocks_id`) REFERENCES `blocks` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)


Благодаря!
 
Fakeheal каза:
Пробвай:
Код:
ALTER TABLE `products` ADD `bid` INT(5) NOT NULL AFTER `product`

Същата работа

Грешка при създаване на външен ключ: Can't create table `thesis`.`#sql-77c_1c` (errno: 150 "Foreign key constraint is incorrectly formed")

Чудя се ако изтрия цялата база данни и започна всичко от начало дали няма да се получи...
 
Разгледа ли възможните ситуации тук - https://stackoverflow.com/questions/8434518/mysql-foreign-key-constraint-is-incorrectly-formed-error ?

От абсолютно същия тип трябва да са и двете колони, включително и колацията (тя не би трябвало да ти е проблемът в случая)
The foreign key column was SMALLINT(5) UNSIGNED and the referenced column was INT(10) UNSIGNED. Once I made them both the same exact type, the foreign key creation worked perfectly.

Изглежда, в MyISAM не можеш да слагаш външни ключове:
I had the same problem when the parent table was created using MyISAM engine. It's a silly mistake, which I fixed with:

Колоната, с която реферваш, трябва ако не primary key, да е поне indexed:
make sure columns are identical(of same type) and if reference column is not primary_key, make sure it is INDEXED.
 
Може и да е точно от колацията, защото я сменях и на базата данни и на таблиците. Сега започвам от начало да видя какво ще излезе.

Благодаря!
 
Така - направих всичко от начало - нова база, нови таблици, попълване, всичко. Стигнах до задаването на външен ключ и пак същата работа:

Грешка при създаване на външен ключ: Can't create table `graduation_thesis`.`#sql-77c_3e3` (errno: 150 "Foreign key constraint is incorrectly formed")

Всичко е на utf8.

Products

<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "Graduation_thesis";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("За съжаление, MySQL връзката не може да бъде осъществена" . $conn->connect_error);
}
$mysqli = "CREATE TABLE Products (
id INT(5) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
product VARCHAR(99) NOT NULL) CHARACTER SET utf8 COLLATE utf8_unicode_ci";
if ($conn->query($mysqli) === TRUE) {
echo "Таблицата е създадена успешно";
} else {
echo "Грешка при създаване на таблицата: " . $conn->error;
}
$conn->close();
?>

Добавяне на колоните към нея

<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "Graduation_thesis";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("За съжаление, MySQL връзката не може да бъде осъществена" . $conn->connect_error);
}
$mysqli ="ALTER TABLE `products` ADD `bid` INT(5) NOT NULL AFTER `product`,
ADD `pqid` INT(5) NOT NULL AFTER `bid`,
ADD `qid` INT(5) NOT NULL AFTER `pqid`";
if ($conn->query($mysqli) === TRUE) {
echo "Колоните са добавени успешно";
} else {
echo "Грешка при добавяне на колоните: " . $conn->error;
}
$conn->close();
?>

Blokcs

<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "Graduation_thesis";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("За съжаление, MySQL връзката не може да бъде осъществена" . $conn->connect_error);
}
$mysqli = "CREATE TABLE Blocks (
id INT(5) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
type VARCHAR(30) NOT NULL,
quantity INT(5) NOT NULL)CHARACTER SET utf8 COLLATE utf8_unicode_ci";
if ($conn->query($mysqli) === TRUE) {
echo "Таблицата е създадена успешно";
} else {
echo "Грешка при създаване на таблицата: " . $conn->error;
}
$conn->close();
?>

Заявката за външен ключ

<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "Graduation_thesis";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("За съжаление, MySQL връзката не може да бъде осъществена" . $conn->connect_error);
}
mysqli_set_charset($conn, 'utf8');
$mysqli = "SET foreign_key_checks = 0";
$mysqli ="ALTER TABLE `products` ADD CONSTRAINT `products_ibfk_1` FOREIGN KEY (`bid`) REFERENCES `blocks`(`id`) ON DELETE CASCADE ON UPDATE CASCADE";
if ($conn->query($mysqli) === TRUE) {
echo "Успешно създаване на външен ключ";
} else {
echo "Грешка при създаване на външен ключ: " . $conn->error;
}
$conn->close();
?>
 
anonimen каза:
Разгледа ли възможните ситуации тук - https://stackoverflow.com/questions/8434518/mysql-foreign-key-constraint-is-incorrectly-formed-error ?

От абсолютно същия тип трябва да са и двете колони, включително и колацията (тя не би трябвало да ти е проблемът в случая)
The foreign key column was SMALLINT(5) UNSIGNED and the referenced column was INT(10) UNSIGNED. Once I made them both the same exact type, the foreign key creation worked perfectly.

Изглежда, в MyISAM не можеш да слагаш външни ключове:
I had the same problem when the parent table was created using MyISAM engine. It's a silly mistake, which I fixed with:

Колоната, с която реферваш, трябва ако не primary key, да е поне indexed:
make sure columns are identical(of same type) and if reference column is not primary_key, make sure it is INDEXED.

Колоните са от един тип както се вижда от заявките.

Идея нямам дали базата данни е MyISAM или InnoDB. Как да разбера и евентуално да го променя?

Колоната си е primary key.
 
Можеш да гугълнеш "check if db is mysam or innodb"

И, тук пише как: https://stackoverflow.com/a/1638107/

[sql]select engine
from information_schema.tables
where table_schema = 'schema_name'
and table_name = 'table_name' [/sql]

За да смениш на InnoDB:

[sql]alter table the_table engine = InnoDB;[/sql]

Хубаво е да се научиш как сам да откриваш инфорамцията, която ти трябва. Така по-бързо ще напредваш и няма да зависиш от отговорите на други хора :?: По тези теми има доста изписан материал, лесно откриваем в гугъл, така че ще можеш да се справиш :?: :?:
 
Всичко ми е InnoDB, но продължава да ми излиза същата грешка при опит да създам външен ключ. :cry:
 
Проблема е решен

<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "Graduation_thesis";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("За съжаление, MySQL връзката не може да бъде осъществена" . $conn->connect_error);
}
mysqli_set_charset($conn, 'utf8');
$mysqli = "SET foreign_key_checks = 0";
$mysqli ="ALTER TABLE `products` ADD CONSTRAINT `products_ibfk_1` FOREIGN KEY (`bid`) REFERENCES `blocks`(`id`) ON DELETE CASCADE ON UPDATE CASCADE";
$mysqli = "SET foreign_key_checks = 1";
if ($conn->query($mysqli) === TRUE) {
echo "Успешно създаване на външен ключ";
} else {
echo "Грешка при създаване на външен ключ: " . $conn->error;
}
$conn->close();
?>

Проблемът беше от оцветения в червено ред - просто липсваше в предходната заявка. :D
Благодаря на всички!
 

Горе