Mevcut tabloya Yabancı Anahtar ekle


324

"Katalog" adlı bir tabloya Yabancı Anahtar eklemek istiyorum.

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

Bunu yapmaya çalıştığımda, bu hata iletisini alıyorum:

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

INNODB Durumunda Hata:

120405 14:02:57 Tablo mytable'ın yabancı anahtar kısıtlamasında hata. # 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

Bu sorguyu kullandığımda çalışır, ancak yanlış "silme" eylemi ile:

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

Her iki tablo da InnoDB ve her iki alan da "INT (11) null değil" dir. MySQL 5.1.61 kullanıyorum. Bu ALTER Sorgusunu bir MacBook Pro'da MySQL Workbench (en yeni) ile tetiklemeye çalışın.

Tablo İfadeleri Oluşturma:

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
Çıkışını yayınlamadığınız için SHOW CREATE TABLE, sadece sorabilirim - sorabilirim - sütun adı gerçekten büyük harf mi?
NB

Şimdi fark etmek daha kolay - katalogvar int(11) unsigned. spracheyok usignedbu nedenle iki sütun aynı değildir, parçası.
NB

Her iki Birincil alanın da aynı veri türünde olması gerekir mi?
frgtv10

2
Tasarımınızdaki sorun bu: ilk olarak, auto_incrementkötü olan iki sütuna başvuruyorsunuz . Ayrıca, MySQL manuel diyor: 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.. Bu nedenle, evet, benzer veri türü ve aynı işaret.
NB

2
İki auto_increment alanına başvurmuyorum. katalog.Sprache (otomatik değil) -> sprache.ID (otomatik)
frgtv10

Yanıtlar:


560

Varolan bir tabloya (kullanıcılar) yabancı anahtar (grade_id) eklemek için aşağıdaki adımları izleyin:

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
Nedenleri anlamama ve hatırlamama yardımcı olur. Çünkü işaretsiz bir alana yabancı anahtar ekleyemezsiniz, değil mi?
PixMach

8
@PixMach, cevap hayır. Tamsayıları yabancı anahtar olarak imzalamış olabilirsiniz. NB'nin soruda belirttiği gibi, alanların türü ve işaretinin eşleşmesi gerekir. Bu nedenle, arama tablosundaki birincil anahtarınız UNSIGNED ise, yabancı anahtar alanının da UNSIGNED olması gerekir. Birincil anahtar alanı İMZALA ise, yabancı anahtar alanı da imzalanmalıdır. Şöyle düşünün: bir tablodaki sütun SHOW CREATE TABLE'da nasıl tanımlanırsa tanımlansın, diğer tabloda aynı tanıma sahip olması gerekir.
Ben Keene

1
Bunun tek bir sorgu ile de yapılabileceğini unutmayın (hata durumunda daha iyi olabilir)
Stijn de Witt

6
"SET FOREIGN_KEY_CHECKS = 0;" ADD CONSTRAINT komutunu veya SQL'i çalıştırmadan önce "Bir alt satır eklenemez veya güncellenemez: bir yabancı anahtar kısıtlaması başarısız" ifadesinden şikayet eder.
Erin Geyer

2
Do not sadece "SET FOREIGN_KEY_CHECKS = 0;" koşmak "yabancı anahtar kısıtlaması başarısız" hatasını alırsanız, düzeltmeniz gereken kötü verileriniz var demektir, aksi takdirde daha büyük sorunlar elde edersiniz.
MazeChaZer

72

Sadece bu sorguyu kullanın, benim senaryom göre denedim ve iyi çalışıyor

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

25

Basit Adımlar ...

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

15

bu bağlantıyı kontrol edin. Errno 150 ile bana yardımcı oldu: http://verysimple.com/2006/10/22/mysql-error-number-1005-cant-create-table-mydbsql-328_45frm-errno-150/

Kafamın üstünde iki şey akla geliyor.

  • Yabancı anahtar dizininiz tüm veritabanında benzersiz bir isim mi (listede 3 numara)?
  • Güncelleme sırasında PK tablosunu NULL olarak ayarlamaya mı çalışıyorsunuz (listede 5 numara)?

Sorunun güncellemedeki set NULL ile olduğunu tahmin ediyorum (eğer beynim bugün sık sık olduğu gibi geriye doğru değilse ...).

Düzenleme: Orijinal yayınınızdaki yorumları kaçırdım. İmzasız / imzasız int sütunları durumunuzu çözmüş olabilir. Umarım bağlantım ileride düşünecek birine yardım eder.


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

Ancak tablonuzda şunlar var:

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

Bu olamaz o DEĞİL NULL olarak tanımlanır çünkü NULL sütun sprache ayarlayın.


5

MySQL şu sorguyu yürütür:

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;

Şerefe!


5

Nasıl düzeltilir Error Code: 1005. Can't create table 'mytable.#sql-7fb1_7d3a' (errno: 150) in mysql.

  1. tablonuzu değiştirin ve bir dizin ekleyin.

    ALTER TABLE users ADD INDEX index_name (index_column)
  2. Şimdi kısıtlamayı ekleyin

    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;

Bir dizin eklemezseniz işe yaramaz.

Yaklaşık 6 saat boyunca onunla savaştıktan sonra çözüm buldum umarım bu bir ruh kurtarır.


4

ALTER TABLE kullanarak bir tabloya yabancı anahtar kısıtlaması eklediğinizde, önce gerekli dizinleri oluşturmayı unutmayın.

  1. Dizin oluştur
  2. Tabloyu değiştir

Her ikisi için de dizin oluşturdum. Çalıştırmayı denediğimde önceki hata mesajını alıyorum. "Güncellemede silme" bölümünü
reddettiğimde işe yarar

@ frgtv10 büyük olasılıkla tablo verilerinin "silindiğinde" çakışmasıdır.
Maksym Polshcha

3

hepsini tek bir sorguda dene

  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

bu temelde olur çünkü tablolarınız iki farklı karakter kümesinde yer alır. örnek olarak charset = utf-8'de oluşturulan bir tablo ve diğer tablolar CHARSET = latin1'de oluşturulur, böylece bu tablolara yabancı anahtar ekleyebilirsiniz. Her iki tabloda da aynı karakter kümesini kullanın, sonra yabancı anahtarlar ekleyebilirsiniz. Hata 1005 yanlış oluşturulmuş foriegn anahtar kısıtlaması bu sorunu çözebilir


0

aynı sorunu yaşadım. Benim durumumda tablo zaten veri var ve bu tabloda referans tabloda mevcut olmayan anahtar vardı. Bu yüzden kısıtlamaları saygısızlık eden bu satırları silmek zorunda kaldım ve her şey çalıştı.


0

1. adım: bu komut dosyasını çalıştırın

SET FOREIGN_KEY_CHECKS=0;

2. adım: sütun ekleyin

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

3. adım: eklenen sütuna yabancı anahtar ekleyin

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

4.Adım: Bu komut dosyasını çalıştırın

SET FOREIGN_KEY_CHECKS=1;

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

Misal:-

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

1
Lütfen kodunuza başkalarının ondan öğrenebilecekleri bir açıklama ekleyin
Nico Haase
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.