Pernyataan ALTER TABLE bertentangan dengan batasan ASING KUNCI

184

Saya punya masalah ketika mencoba menambahkan kunci asing ke tblDomaremeja saya ; apa yang saya lakukan salah di sini?

CREATE TABLE tblDomare
(PersNR VARCHAR (15) NOT NULL,
fNamn VARCHAR (15) NOT NULL,
eNamn VARCHAR (20) NOT NULL,
Erfarenhet VARCHAR (5),
PRIMARY KEY (PersNR));

INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (6811034679,'Bengt','Carlberg',10);

INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (7606091347,'Josefin','Backman',4);

INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (8508284163,'Johanna','Backman',1);

CREATE TABLE tblBana
(BanNR VARCHAR (15) NOT NULL,
PRIMARY KEY (BanNR));

INSERT INTO tblBana (BanNR)
Values (1);

INSERT INTO tblBana (BanNR)
Values (2);

INSERT INTO tblBana (BanNR)
Values (3);

ALTER TABLE tblDomare
ADD FOREIGN KEY (PersNR)
REFERENCES tblBana(BanNR);

Pesan eror:

Pernyataan ALTER TABLE bertentangan dengan batasan ASING "FK_ tblDomare _PersN__5F7E2DAC". Konflik terjadi di database "almu0004", tabel "dbo.tblBana", kolom 'BanNR'.

pengguna3162932
sumber

Jawaban:

333

Itu terjadi karena Anda mencoba membuat kunci asing dari tblDomare.PersNRto tblBana.BanNRtapi / dan nilai-nilai di tblDomare.PersNRtidak cocok dengan nilai apa pun di tblBana.BanNR. Anda tidak dapat membuat hubungan yang melanggar integritas referensial.

Smutje
sumber
87
Ini adalah jawaban untuk saya, tetapi saya masih berjuang untuk menyadari di mana masalahnya, jadi saya akan memberikan contoh orang awam. Jika Anda memiliki tabel bernama 'Pesanan' dan meja yang disebut 'Pelanggan', dan Anda telah menghapus beberapa pelanggan lama, tetapi bukan pesanan mereka, Anda akan mendapatkan kesalahan ini jika Anda memutuskan untuk membuat kunci asing dari Pesanan. PelangganId kepada Pelanggan .Indo. Beberapa pesanan tidak lagi memiliki pelanggan yang sesuai, jadi tidak mungkin untuk menambahkan kunci asing.
Chad Hedgcock
10
Berikut ini kueri untuk memeriksa nilai yang salah: pilih referrerTable.referenceColumn berbeda dari referrerTable gabung kiri referTable di referTable.referenceColumn = referrerTable.referenceColumn di mana referTer.referenceColumn adalah null;
jumxozizi
6
Dalam keadaan darurat, Anda juga bisa menggunakan opsi "ALTER TABLE tablename WITH NOCHECK ..." untuk menambahkan FK. Ini akan memungkinkan Anda untuk menambahkan relasi, meskipun data yang ada mematahkan batasannya. Jelas lebih baik membersihkan data Anda terlebih dahulu, tetapi ini setidaknya memberi Anda pilihan lain.
DaveInMaine
2
@DaveInMaine Jika seseorang menonaktifkan batasan database "ketika diinginkan", saya akan bertanya mengapa menyusahkan diri sendiri dengan mereka di tempat pertama dan tidak hanya melewatkannya jika seseorang tidak tertarik pada integritas database.
Smutje
1
apa pesan kesalahan yang buruk. melihatnya sebelumnya tetapi membuat saya benar-benar lengah sekarang berpikir ada sesuatu yang rusak
Simon_Weaver
43

Permintaan ini sangat berguna bagi saya. Ini menunjukkan semua nilai yang tidak memiliki kecocokan

select FK_column from FK_table
WHERE FK_column NOT IN
(SELECT PK_column from PK_table)
dantey89
sumber
37

Coba solusi ini:

Ada item data di tabel Anda yang nilai asosiasinya tidak ada di tabel yang ingin Anda gunakan sebagai tabel kunci utama. Kosongkan meja Anda atau tambahkan nilai terkait ke tabel kedua.

PatsonLeaner
sumber
29

Dimungkinkan untuk membuat kunci asing menggunakan tablename ALTER TABLE WITH NOCHECK ..., yang akan memungkinkan data yang melanggar kunci asing.

"ALTER TABLE tablename WITH NOCHECK ..." pilihan untuk menambahkan FK - Solusi ini berhasil untuk saya.

Ankita Biswas
sumber
17
Ketahuilah bahwa membiarkan pelanggaran semacam itu mengalahkan tujuan batasan kunci asing.
direformasi
Berbahaya...!!! Seharusnya hanya digunakan jika Anda tidak ingin kehilangan data saat ini di tabel. Tetapi meskipun begitu, mengapa tidak melakukan pencadangan dan kemudian menghapus Id yang tidak valid.
Andrei Bazanov
Saya perlu menerapkan melalui java / spring / code untuk melakukan itu, tidak secara langsung melalui query SQL, ideia bagaimana melakukan ini dengan kode berikut: @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.DETACH) @JoinTable(name = "tbUsuariosTipoOcorrencia", joinColumns = { @JoinColumn(name = "idUsuario") }, inverseJoinColumns = { @JoinColumn(name = "idTipoOcorrencia") }) dan saya melakukan ini menyelesaikan melalui query database:alter table tbUsuariosTipoOcorrencia WITH NOCHECK add constraint FKnbxg3ua7b8c5d53wps69q6jh foreign key (idUsuario) references tbUsuarios
Francisco Souza
11

Saya kira, nilai kolom dalam tabel kunci asing harus cocok dengan nilai kolom dari tabel kunci utama. Jika kita mencoba membuat batasan kunci asing antara dua tabel di mana nilai di dalam satu kolom (akan menjadi kunci asing) berbeda dari nilai kolom dari tabel kunci utama maka itu akan membuang pesan.

Jadi selalu disarankan untuk memasukkan hanya nilai-nilai itu di kolom kunci Asing yang ada di kolom tabel kunci Utama.

Misalnya Jika kolom tabel utama memiliki nilai 1, 2, 3 dan di kolom kunci asing nilai yang dimasukkan berbeda, maka kueri tidak akan dieksekusi karena mengharapkan nilai antara 1 & 3.

sam05
sumber
11

Sebelum Anda menambahkan kunci Asing ke tabel, lakukan hal berikut

  1. Pastikan tabel harus kosong atau Data kolom harus cocok.
  2. Pastikan itu bukan nol.
  3. Jika tabel berisi tidak pergi ke desain dan perubahan, lakukan secara manual.

    ubah tabel Tabel 1 tambahkan referensi kunci asing (Nama Kolom) Tabel 2 (Nama Kolom)

    ubah tabel Tabel 1 ubah kolom Atribut Nama Kolom bukan nol

GirishBabuC
sumber
10

Bersihkan data Anda dari tabel Anda dan kemudian buat hubungan di antara mereka.

maks
sumber
Terima kasih, maks. itu berfungsi untuk saya jika mereka memiliki data bahkan hubungan yang sempurna perintah Update-Database tidak akan berfungsi.
robert jebakumar2
Tidak perlu menghapus data apa pun selama data itu valid sesuai dengan kunci asing yang dibuat.
jumxozizi
7

Coba DELETEdata saat ini dari tblDomare.PersNR. Karena nilai dalam tblDomare.PersNRtidak cocok dengan nilai apa pun di tblBana.BanNR.

Bell Pemikir
sumber
@ agenc apakah saya menjawab pertanyaan Anda?
Thinker Bell
3

saya memiliki kesalahan ini juga ketika Smutje direferensikan memastikan bahwa Anda tidak memiliki nilai dalam kolom kunci asing dari tabel kunci asing asing Anda yang tidak ada dalam tabel referensi Anda yaitu (setiap nilai dalam tabel kunci asing asing Anda (nilai kolom yang kunci asing) juga harus ada di kolom tabel referensi Anda) sebaiknya dikosongkan dari tabel kunci asing dasar Anda terlebih dahulu kemudian atur kunci asing

ako
sumber
2

data yang Anda masukkan tabel (tbldomare) tidak cocok dengan data yang telah Anda tetapkan tabel kunci primer. tulis di antara tbldomare dan tambahkan kata ini (dengan nocheck) kemudian jalankan kode Anda.

misalnya Anda memasukkan tabel untuk data ini

INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (6811034679,'Bengt','Carlberg',10);

dan Anda menetapkan foreign keytabel untuk menerima saja1,2,3 .

Anda memiliki dua solusi, satu adalah menghapus data yang telah Anda masukkan dalam tabel, kemudian jalankan kodenya. lain adalah menulis kata ini (dengan nocheck) letakkan di antara nama tabel Anda dan tambahkan seperti ini

ALTER TABLE  tblDomare with nocheck
ADD FOREIGN KEY (PersNR)
REFERENCES tblBana(BanNR);
khadar
sumber
2

Ini terjadi pada saya, karena saya sedang merancang database saya, saya perhatikan bahwa saya mengubah benih saya di tabel utama saya, sekarang tabel relasional tidak memiliki kunci asing di tabel utama.

Jadi saya harus memotong kedua tabel, dan sekarang berfungsi!

Willy David Jr
sumber
2

Anda harus melihat apakah tabel Anda memiliki data di baris. Jika "ya" maka Anda harus memotong tabel (s) atau Anda dapat membuat mereka memiliki jumlah data yang sama pada tblDomare.PersNRke tblBana.BanNRdan catok-ayat.

adrianex03
sumber
2

Smutje benar dan Chad HedgeCock menawarkan contoh yang bagus bagi orang awam. Saya ingin membangun contoh Chad dengan menawarkan cara untuk menemukan / menghapus catatan-catatan itu. Kami akan menggunakan Pelanggan sebagai Orang Tua dan Pesanan sebagai anak. CustomerId adalah bidang yang umum.

select * from Order Child 
left join Customer Parent on Child.CustomerId = Parent.CustomerId
where Parent.CustomerId is null 

jika Anda membaca utas ini ... Anda akan mendapatkan hasil. Ini adalah anak-anak yatim. pilih * dari Orde Anak kiri bergabung dengan Induk Pelanggan di Child.CustomerId = Parent.CustomerId di mana Parent.CustomerId adalah nol. Perhatikan jumlah baris di kanan bawah.

Pergi memverifikasi tanpa siapa pun yang Anda butuhkan sehingga Anda akan menghapus baris ini!

begin tran 
delete Order
from Order Child 
left join Customer Parent on Child.CustomerId = Parent.CustomerId
where Parent.CustomerId is null 

Jalankan bit pertama. Periksa jumlah baris itu = apa yang Anda harapkan

melakukan tran

commit tran 

Hati-hati. Pemrograman seseorang yang ceroboh membuat Anda terlibat dalam kekacauan ini. Pastikan Anda memahami alasannya sebelum Anda menghapus anak yatim. Mungkin orang tua perlu dipulihkan.

greg
sumber
Terima kasih balasannya. Saya bermain dengan database stackoverflow (sebenarnya gamedev) dan menemukan dua NULL ketika saya LEFT BERGABUNG Lencana dengan Pengguna. Tidak heran kendala tidak berhasil ...
Nicholas Humphrey
1

Dalam skenario saya, menggunakan EF, setelah mencoba membuat Kunci Asing baru ini pada data yang ada, saya salah mencoba untuk mengisi data (membuat tautan) SETELAH membuat kunci asing.

Cara mengatasinya adalah mengisi data Anda sebelum membuat kunci asing karena memeriksa semuanya untuk melihat apakah tautan tersebut memang valid. Jadi itu tidak mungkin bekerja jika Anda belum mengisinya.

jeromej
sumber
1

Saya menemukan beberapa masalah dalam proyek saya.

masukkan deskripsi gambar di sini

Di tabel anak, tidak ada catatan Id sama dengan 1 dan 11

mage

Saya memasukkan tabel DEAL_ITEM_THIRD_PARTY_PO yang Idnya sama dengan 1 dan 11 maka saya bisa membuat FK

Metin Atalay
sumber
0

Pertama-tama hapus data dari tabel itu dan kemudian jalankan migrasi lagi. Anda akan mendapatkan kesuksesan

M Arslan Riaz
sumber
0

Ketika Anda mendefinisikan Kunci Asing di tabel B referensi Kunci Utama tabel A itu berarti bahwa ketika nilai dalam B, itu harus dalam A. Ini untuk mencegah modifikasi yang tidak konsisten ke tabel.

Dalam contoh Anda, tabel Anda berisi:

tblDomare dengan PRIMARY KEY (PersNR):

PersNR     |fNamn     |eNamn      |Erfarenhet
-----------|----------|-----------|----------
6811034679 |'Bengt'   |'Carlberg' |10
7606091347 |'Josefin' |'Backman'  |4
8508284163 |'Johanna' |'Backman'  |1
---------------------------------------------

tblBana:

BanNR
-----
1
2
3
-----

Pernyataan ini:

ALTER TABLE tblDomare
ADD FOREIGN KEY (PersNR)
REFERENCES tblBana(BanNR);

mengatakan bahwa setiap baris tblDomaredengan kunci PersNRharus memiliki korespondensi dalam tabel tblBanapada kunci BanNR. Kesalahan Anda adalah karena Anda memiliki garis yang dimasukkan tblDomaretanpa ada korespondensi di tblBana.

2 solusi untuk mengatasi masalah Anda: - tambahkan baris tblBanadengan BanNR in (6811034679, 7606091347, 8508284163) - or remove all lines intblDomarethat have no correspondance in tblBana` (tetapi meja Anda akan kosong)

Saran umum : Anda harus memiliki batasan Kunci Asing sebelum mengisi tabel. Kunci asing di sini untuk mencegah pengguna tabel dari mengisi tabel dengan inkonsistensi.

belka
sumber
-3

dan hanya FYI, jika Anda melakukan semua pemeriksaan referensi data Anda dan tidak menemukan data yang buruk ... ternyata tidak mungkin untuk membuat batasan kunci asing antara dua tabel dan bidang di mana bidang tersebut adalah kunci utama di kedua tabel! Jangan tanya saya bagaimana saya tahu ini.

Doug Boude
sumber