Dodaj klucz obcy do istniejącej tabeli


324

Chcę dodać klucz obcy do tabeli o nazwie „katalog”.

ALTER TABLE katalog 
ADD CONSTRAINT `fk_katalog_sprache` 
FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL;

Gdy próbuję to zrobić, pojawia się następujący komunikat o błędzie:

Error Code: 1005. Can't create table 'mytable.#sql-7fb1_7d3a' (errno: 150)

Błąd w stanie INNODB:

120405 14:02:57 Błąd ograniczenia klucza obcego tabeli mytable. # Sql-7fb1_7d3a:

FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL:
Cannot resolve table name close to:
(`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL

Kiedy korzystam z tego zapytania, działa, ale ze złym działaniem „przy usuwaniu”:

ALTER TABLE `katalog` 
ADD FOREIGN KEY (`Sprache` ) REFERENCES `sprache` (`ID` )

Obie tabele to InnoDB, a oba pola to „INT (11) nie null”. Używam MySQL 5.1.61. Próba uruchomienia tego zapytania ALTER za pomocą MySQL Workbench (najnowszego) na MacBooku Pro.

Tabela Utwórz instrukcje:

CREATE TABLE `katalog` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`Name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`AnzahlSeiten` int(4) unsigned NOT NULL,
`Sprache` int(11) NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `katalogname_uq` (`Name`)
 ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC$$

CREATE TABLE `sprache` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
 `Bezeichnung` varchar(45) NOT NULL,
 PRIMARY KEY (`ID`),
 UNIQUE KEY `Bezeichnung_UNIQUE` (`Bezeichnung`),
KEY `ix_sprache_id` (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

1
Ponieważ nie opublikowałeś danych wyjściowych SHOW CREATE TABLE, mogę tylko zapytać - czy nazwa kolumny to naprawdę ID, wielkie litery?
NB 5'12

Cóż, teraz łatwiej to zauważyć - katalogma int(11) unsigned. sprachenie ma usignedczęści, dlatego dwie kolumny nie są takie same.
NB 5'12

Czy masz na myśli, że oba pola Primary muszą być tego samego typu danych?
frgtv10,

2
To jest problem z twoim projektem: po pierwsze, odwołujesz się do dwóch auto_incrementkolumn, co jest złe. Ponadto, instrukcja MySQL mówi: Corresponding columns in the foreign key and the referenced key must have similar internal data types inside InnoDB so that they can be compared without a type conversion. The size and sign of integer types must be the same. The length of string types need not be the same. For nonbinary (character) string columns, the character set and collation must be the same.. Dlatego tak, podobny typ danych i ten sam znak.
NB 5'12

2
Nie odnoszę się do dwóch pól auto_increment. katalog.Sprache (nie auto) -> sprache.ID (auto)
frgtv10

Odpowiedzi:


560

Aby dodać klucz obcy (grade_id) do istniejącej tabeli (użytkowników), wykonaj następujące kroki:

ALTER TABLE users ADD grade_id SMALLINT UNSIGNED NOT NULL DEFAULT 0;
ALTER TABLE users ADD CONSTRAINT fk_grade_id FOREIGN KEY (grade_id) REFERENCES grades(id);

12
Powody pomagają mi zrozumieć i zapamiętać. Wynika to z faktu, że nie można dodać klucza obcego do pola niepodpisanego, prawda?
PixMach

8
@PixMach, odpowiedź brzmi nie. Możesz mieć liczby całkowite podpisane jako klucze obce. Jak zauważono w pytaniu NB, typ i znak pól muszą być zgodne. Jeśli więc klucz podstawowy w tabeli odnośników ma wartość UNSIGNED, pole klucza obcego również musi być UNSIGNED. Jeśli pole klucza podstawowego jest PODPISANE, pole klucza obcego również musi zostać podpisane. Pomyśl o tym w ten sposób: cokolwiek kolumna w jednej tabeli jest zdefiniowana jak w POKAŻ TWORZENIE TABELI, musi mieć tę samą definicję w drugiej tabeli.
Ben Keene,

1
Zauważ, że można to również zrobić za pomocą pojedynczego zapytania (może być lepiej w przypadku niepowodzenia itp.)
Stijn de Witt

6
Musiałem uruchomić „SET FOREIGN_KEY_CHECKS = 0;” przed uruchomieniem polecenia ADD CONSTRAINT lub SQL narzeka: „Nie można dodać lub zaktualizować wiersza podrzędnego: ograniczenie klucza obcego kończy się niepowodzeniem”.
Erin Geyer,

2
Czy nie wystarczy uruchomić "set FOREIGN_KEY_CHECKS = 0;" jeśli pojawi się błąd „nie działa ograniczenie klucza obcego”, to oczywiście masz złe dane, które musisz naprawić, bo w przeciwnym razie wystąpią większe problemy.
MazeChaZer

72

Wystarczy użyć tego zapytania, wypróbowałem go zgodnie z moim scenariuszem i działa dobrze

ALTER TABLE katalog ADD FOREIGN KEY (`Sprache`) REFERENCES Sprache(`ID`);

25

Proste kroki ...

ALTER TABLE t_name1 ADD FOREIGN KEY (column_name) REFERENCES t_name2(column_name)

15

sprawdź ten link. Pomogło mi to z errno 150: http://verysimple.com/2006/10/22/mysql-error-number-1005-cant-create-table-mydbsql-328_45frm-errno-150/

Na czubku mojej głowy przychodzą mi na myśl dwie rzeczy.

  • Czy indeks klucza obcego jest unikalną nazwą w całej bazie danych (nr 3 na liście)?
  • Czy próbujesz ustawić tabelę PK na NULL podczas aktualizacji (nr 5 na liście)?

Zgaduję, że problem polega na ustawieniu NULL przy aktualizacji (jeśli moje mózgi nie są dzisiaj odwrócone, jak to często bywa ...).

Edycja: Brakuje komentarzy do twojego oryginalnego postu. Niepodpisane / niepodpisane kolumny int mogą rozwiązać problem. Mam nadzieję, że mój link pomaga komuś w przyszłości pomyśleć.


13
FOREIGN KEY (`Sprache`)
REFERENCES `Sprache` (`ID`)
ON DELETE SET NULL
ON UPDATE SET NULL;

Ale twój stół ma:

CREATE TABLE `katalog` (
`Sprache` int(11) NOT NULL,

To mogę ustawić kolumny Sprache NULL, ponieważ jest zdefiniowana jako NOT NULL.


5

MySQL wykona to zapytanie:

ALTER TABLE `db`.`table1`
ADD COLUMN `col_table2_fk` INT UNSIGNED NULL,
ADD INDEX `col_table2_fk_idx` (`col_table2_fk` ASC),
ADD CONSTRAINT `col_table2_fk1`
FOREIGN KEY (`col_table2_fk`)
REFERENCES `db`.`table2` (`table2_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;

Twoje zdrowie!


5

Jak naprawić Error Code: 1005. Can't create table 'mytable.#sql-7fb1_7d3a' (errno: 150) in mysql.

  1. zmień tabelę i dodaj do niej indeks ...

    ALTER TABLE users ADD INDEX index_name (index_column)
  2. Teraz dodaj ograniczenie

    ALTER TABLE foreign_key_table
    ADD CONSTRAINT foreign_key_name FOREIGN KEY (foreign_key_column)
    REFERENCES primary_key_table (primary_key_column) ON DELETE NO ACTION
    ON UPDATE CASCADE;

Uwaga: jeśli nie dodasz indeksu, nie zadziała.

Po walce z nim przez około 6 godzin wymyśliłem rozwiązanie. Mam nadzieję, że uratuje to duszę.


4

Kiedy dodajesz ograniczenie klucza obcego do tabeli za pomocą ALTER TABLE, pamiętaj, aby najpierw utworzyć wymagane indeksy.

  1. Utwórz indeks
  2. Zmień stół

Dla obu utworzyłem indeks. Podczas próby uruchomienia pojawia się taki sam komunikat o błędzie jak poprzednio. Kiedy zrzekam się części „przy usuwaniu przy aktualizacji” działa, ale z niewłaściwą akcją „przy usuwaniu”;)
frgtv10

@ frgtv10 najprawdopodobniej konflikt danych tabel z „przy usuwaniu”.
Maksym Polshcha,

3

wypróbuj wszystko w jednym zapytaniu

  ALTER TABLE users ADD grade_id SMALLINT UNSIGNED NOT NULL DEFAULT 0,
      ADD CONSTRAINT fk_grade_id FOREIGN KEY (grade_id) REFERENCES grades(id);

0

dzieje się tak w zasadzie, ponieważ tabele są w dwóch różnych zestawach znaków. na przykład jedna tabela utworzona w charset = utf-8, a inne tabele są utworzone w CHARSET = latin1, więc chcesz mieć możliwość dodania klucza foriegn do tych tabel. użyj tego samego zestawu znaków w obu tabelach, wtedy będziesz mógł dodać klucze foriegn. błąd 1005 niepoprawnie utworzone ograniczenie klucza foriegn może rozwiązać ten problem


0

Przeszedłem przez ten sam problem. W moim przypadku tabela ma już dane i w tej tabeli znajdował się klucz, którego nie było w tabeli referencyjnej. Musiałem więc usunąć te wiersze, które nie respektują ograniczeń i wszystko działało.


0

krok 1: uruchom ten skrypt

SET FOREIGN_KEY_CHECKS=0;

krok 2: dodaj kolumnę

ALTER TABLE mileage_unit ADD COLUMN COMPANY_ID BIGINT(20) NOT NULL

krok 3: dodaj klucz obcy do dodanej kolumny

ALTER TABLE mileage_unit
ADD FOREIGN KEY (COMPANY_ID) REFERENCES company_mst(COMPANY_ID);

krok 4: uruchom ten skrypt

SET FOREIGN_KEY_CHECKS=1;

-1
 ALTER TABLE TABLENAME ADD FOREIGN KEY (Column Name) REFERENCES TableName(column name)

Przykład:-

ALTER TABLE Department ADD FOREIGN KEY (EmployeeId) REFERENCES Employee(EmployeeId)

1
Dodaj wyjaśnienie do swojego kodu, aby inni mogli się z niego uczyć
Nico Haase,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.