पूर्व सारणी कथन पूर्व प्रमुख कुंजी बाधा के साथ विरोध किया


184

मुझे अपनी tblDomareमेज पर एक विदेशी कुंजी जोड़ने की कोशिश करते समय एक समस्या है ; मुझसे यहां क्या गलत हो रहा है?

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);

त्रुटि संदेश:

पूर्व सारणी के बयान ने प्रमुख कुंजी बाधा "FK_ tblDomare _PersN__5F7E2DAC" के साथ विरोध किया । डेटाबेस "almu0004", टेबल "dbo.tblBana", कॉलम 'BanNR' में संघर्ष हुआ।

जवाबों:


333

यह हुआ है क्योंकि आप से एक विदेशी कुंजी बनाने की कोशिश की tblDomare.PersNRकरने के लिए tblBana.BanNRलेकिन / और में मूल्यों tblDomare.PersNRमें मानों से मेल नहीं खाती tblBana.BanNR। आप एक संबंध नहीं बना सकते हैं जो संदर्भात्मक अखंडता का उल्लंघन करता है।


87
यह मेरे लिए जवाब था, लेकिन मैं अभी भी यह महसूस करने के लिए संघर्ष कर रहा था कि समस्या कहां थी, इसलिए मैं एक आम आदमी का उदाहरण दूंगा। यदि आपके पास 'ऑर्डर' नाम की एक तालिका है और 'ग्राहक' नाम की एक तालिका है, और आपने कुछ पुराने ग्राहकों को हटा दिया है, लेकिन उनके आदेश नहीं, तो आपको यह त्रुटि मिलेगी यदि आप Orders.CustomerId से ग्राहकों के लिए एक विदेशी कुंजी बनाने का निर्णय लेते हैं .id। कुछ आदेशों में संबंधित ग्राहक को कोई अधिक नहीं है, इसलिए विदेशी कुंजी को जोड़ना असंभव है।
चाड हेडगॉक

10
यहां गलत मानों की जांच करने के लिए एक क्वेरी है: referrerTable से अलग referrerTable.referenceColumn का चयन करें। बाएँ बाएँ से जोड़ा जा रहा है, यहTTable.referenceColumn = referrerTable.referenceColumn पर है जहाँTT.referenceColumn शून्य है;
jumxozizi

6
एक चुटकी में, आप FK को जोड़ने के लिए "ALTER TABLE tablename with NOCHECK ..." विकल्प का भी उपयोग कर सकते हैं। यह आपको संबंध जोड़ने की अनुमति देगा, भले ही मौजूदा डेटा बाधा को तोड़ दे। अपने डेटा को पहले साफ़ करना बेहतर है, लेकिन यह कम से कम आपको एक और विकल्प देता है।
डेवइनमाइन

2
@DaveInMaine यदि कोई डेटाबेस बाधाओं को "जब वांछित है" को निष्क्रिय कर देता है, तो मैं पूछूंगा कि पहली बार में उनके साथ खुद को परेशान क्यों करना चाहिए और डेटाबेस अखंडता में रुचि नहीं होने पर उन्हें सीधे छोड़ दें।
स्मटजे

1
क्या एक घटिया त्रुटि संदेश। इसे पहले देखा था लेकिन मुझे पूरी तरह से बंद कर दिया था कि अब यह सोचकर कि कुछ भ्रष्ट हो गया है
सिमोन_विवर

42

यह क्वेरी मेरे लिए बहुत उपयोगी थी। यह उन सभी मूल्यों को दिखाता है जिनका कोई मिलान नहीं है

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

37

इस समाधान का प्रयास करें:

आपकी तालिका में एक डेटा आइटम है जिसका संबद्ध मूल्य उस तालिका में मौजूद नहीं है जिसे आप प्राथमिक कुंजी तालिका के रूप में उपयोग करना चाहते हैं। अपनी तालिका को खाली करें या संबंधित मूल्य को दूसरी तालिका में जोड़ें।


29

NOCHECK के साथ ALTER TABLE टैबलेन का उपयोग करके विदेशी कुंजी बनाना संभव है ..., जो डेटा को विदेशी कुंजी का उल्लंघन करने की अनुमति देगा।

"NOCHECK के साथ ALTER TABLE टैबलेन ..." FK को जोड़ने का विकल्प - इस समाधान ने मेरे लिए काम किया।


17
विदित हो कि इस तरह के उल्लंघन की अनुमति देना विदेशी प्रमुख बाधा के उद्देश्य को हरा देता है।
सुधार हुआ

खतरनाक...!!! यदि आप वर्तमान में तालिका में डेटा को ढीला नहीं करना चाहते हैं, तो इसका केवल उपयोग किया जाना चाहिए। लेकिन फिर भी, एक बैकअप क्यों नहीं किया जाता है और फिर अमान्य आईडीएस को हटा दें।
आंद्रेई बाजानोव

मुझे जावा / स्प्रिंग / कोड के माध्यम से कार्यान्वित करने की आवश्यकता है, न कि सीधे SQL क्वेरी के माध्यम से, किसी भी विचारधारा को निम्न कोड के साथ कैसे करना है: @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.DETACH) @JoinTable(name = "tbUsuariosTipoOcorrencia", joinColumns = { @JoinColumn(name = "idUsuario") }, inverseJoinColumns = { @JoinColumn(name = "idTipoOcorrencia") }) और मैंने ऐसा किया डेटाबेस डेटाबेस क्वेरी के माध्यम से हल किया:alter table tbUsuariosTipoOcorrencia WITH NOCHECK add constraint FKnbxg3ua7b8c5d53wps69q6jh foreign key (idUsuario) references tbUsuarios
फ्रांसिस्को सूजा

11

मुझे लगता है, एक विदेशी कुंजी तालिका में एक स्तंभ मान प्राथमिक कुंजी तालिका के स्तंभ मूल्य के साथ मेल खाना चाहिए। यदि हम दो तालिकाओं के बीच एक विदेशी कुंजी बाधा बनाने की कोशिश कर रहे हैं, जहां एक कॉलम के अंदर मान (विदेशी कुंजी होने जा रहा है) प्राथमिक कुंजी तालिका के स्तंभ मूल्य से अलग है तो यह संदेश फेंक देगा।

इसलिए हमेशा विदेशी कुंजी कॉलम में उन मूल्यों को सम्मिलित करने की सिफारिश की जाती है जो प्राथमिक कुंजी तालिका कॉलम में मौजूद होते हैं।

पूर्व के लिए। यदि प्राथमिक टेबल कॉलम में मान 1, 2, 3 हैं और विदेशी कुंजी कॉलम में डाले गए मान भिन्न हैं, तो क्वेरी निष्पादित नहीं की जाएगी क्योंकि यह मानों को 1 और 3 के बीच होने की उम्मीद करता है।


11

इससे पहले कि आप तालिका में विदेशी कुंजी जोड़ें, निम्न कार्य करें

  1. सुनिश्चित करें कि तालिका खाली होनी चाहिए या स्तंभ डेटा से मेल खाना चाहिए।
  2. सुनिश्चित करें कि यह अशक्त नहीं है।
  3. यदि तालिका में डिज़ाइन और परिवर्तन नहीं है, तो इसे मैन्युअल रूप से करें।

    तालिका तालिका 1 में परिवर्तन करें विदेशी कुंजी (कॉलम नाम) संदर्भ तालिका 2 (कॉलम नाम) जोड़ें

    तालिका तालिका 1 में परिवर्तन करें स्तंभ स्तंभ नाम बदलें विशेषता शून्य नहीं है


10

अपने टेबल से अपना डेटा साफ़ करें और फिर उनके बीच संबंध बनाएं।


धन्यवाद, अधिकतम। यह मेरे लिए काम किया है अगर उनके पास भी डेटा है तो रिश्ते सही हैं अपडेट-डेटाबेस कमांड काम नहीं करेगा।
रोबर्ट जेबाकुमार 2

किसी भी डेटा को हटाने के लिए आवश्यक नहीं है जब तक कि वे बनाई गई विदेशी कुंजी के अनुसार मान्य न हों।
जंक्सोज़िजी

7

DELETEसे वर्तमान डेटा का प्रयास करें tblDomare.PersNR। क्योंकि मूल्यों में tblDomare.PersNRसे किसी के साथ मेल नहीं खाते tblBana.BanNR


@agenc क्या मैंने आपके प्रश्न का उत्तर दिया?
विचारक बेल

3

मेरे पास यह त्रुटि भी थी क्योंकि स्मूत्ज़ ने यह सुनिश्चित किया कि आपके बेस फॉरेन की टेबल के विदेशी कुंजी कॉलम में कोई वैल्यू नहीं है जो आपके संदर्भ तालिका में नहीं है यानी आपके बेस फॉरेन की-टेबल में हर वैल्यू (एक कॉलम का मूल्य जो है) विदेशी कुंजी) आपके संदर्भ तालिका कॉलम में भी होनी चाहिए) अपनी आधार विदेशी कुंजी तालिका को पहले खाली करने के लिए अच्छा है फिर विदेशी कुंजी सेट करें


2

आपके द्वारा तालिका में दर्ज किया गया डेटा (tbldomare) आपके द्वारा प्राथमिक कुंजी तालिका असाइन किए गए डेटा से मेल नहीं खाता है। tbldomare के बीच लिखें और इस शब्द को जोड़ें (nocheck के साथ) फिर अपने कोड को निष्पादित करें।

उदाहरण के लिए आपने इस डेटा में एक तालिका tbldomar दर्ज की है

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

और आपने foreign keyकेवल स्वीकार करने के लिए एक तालिका सौंपी 1,2,3

आपके पास दो समाधान हैं एक आपके द्वारा तालिका में दर्ज किए गए डेटा को हटा दें फिर कोड निष्पादित करें। एक और इस शब्द को लिखा गया है (nocheck के साथ) इसे अपने टेबल नाम के बीच रखें और इस तरह जोड़ें

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

2

यह मेरे साथ होता है, जब से मैं अपना डेटाबेस डिजाइन कर रहा हूं, मैं देखता हूं कि मैं अपने मुख्य टेबल पर अपना बीज बदलता हूं, अब रिलेशनल टेबल में मुख्य टेबल पर कोई विदेशी कुंजी नहीं है।

इसलिए मुझे दोनों तालिकाओं को अलग करने की आवश्यकता है, और यह अब काम करता है!


2

आपको यह देखना चाहिए कि आपकी तालिकाओं में कोई डेटा है या नहीं। यदि "हाँ" तो तुम काटना चाहिए तालिका (रों) या फिर आप उन पर डेटा की एक ही नंबर के लिए कर सकते हैं tblDomare.PersNRकरने के लिए tblBana.BanNRऔर शिकंजा-कविता।


2

स्मटजे सही है और चाड हेजकॉक ने एक महान आम आदमी का उदाहरण पेश किया। आईडी उन रिकॉर्ड्स को खोजने / हटाने का एक तरीका पेश करके चाड के उदाहरण पर निर्माण करना पसंद करती है। हम बच्चे के रूप में ग्राहक का उपयोग अभिभावक और आदेश के रूप में करेंगे। CustomerId सामान्य क्षेत्र है।

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

यदि आप इस सूत्र को पढ़ रहे हैं ... तो आपको परिणाम मिलेंगे। ये अनाथ बच्चे हैं। चयन करें * से ऑर्डर चाइल्ड लेफ्ट ने चाइल्ड पर कस्टमर पैरेंट को ज्वाइन किया।

सत्यापित करें कि आप इन पंक्तियों को हटाने के लिए जा रहे हैं, जिसकी आपको आवश्यकता है, w / wome!

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

पहले थोड़ा चलाएं। उस पंक्ति की जाँच करें = जो आपने अपेक्षित किया था

ट्रान्स करें

commit tran 

सावधान रहे। किसी की मैला प्रोग्रामिंग आपको इस झंझट में डाल गई। सुनिश्चित करें कि आप अनाथों को हटाने से पहले क्यों समझते हैं। शायद माता-पिता को बहाल करने की आवश्यकता है।


उत्तर के लिए धन्यवाद। मैं stackoverflow डेटाबेस के साथ खेल रहा हूँ (वास्तव में gamedev) और दो NULLs मिला जब मैं उपयोगकर्ताओं के साथ बैज शामिल करता हूं। कोई आश्चर्य नहीं कि बाधाओं ने काम नहीं किया ...
निकोलस हम्फ्री

1

मेरे परिदृश्य में, मौजूदा डेटा पर इस नई विदेशी कुंजी को बनाने की कोशिश करने पर, ईएफ का उपयोग करते हुए, मैं गलत तरीके से डेटा बनाने (लिंक बनाने) को विदेशी कुंजी बनाने की कोशिश कर रहा था।

यह फ़र्क विदेशी कुंजी बनाने से पहले आपके डेटा को आबाद करने के लिए है क्योंकि यह उन सभी को देखने के लिए जाँचता है कि क्या लिंक वास्तव में वैध हैं। यदि आप इसे अभी तक आबाद नहीं करते हैं तो यह संभवतः काम नहीं कर सकता है।


1

मैं अपनी परियोजना में कुछ समस्या का सामना करता हूं।

यहां छवि विवरण दर्ज करें

चाइल्ड टेबल में, कोई भी रिकॉर्ड आईडी 1 और 11 नहीं है

दाना

मैंने Deal_ITEM_THIRD_PARTY_PO तालिका सम्मिलित की, जो Id 1 और 11 के बराबर है तो मैं FK बना सकता हूं



0

जब आप तालिका A की प्राथमिक कुंजी को संदर्भित करते हुए तालिका B में एक विदेशी कुंजी परिभाषित करते हैं, तो इसका मतलब है कि जब कोई मान B में है, तो यह A. में होना चाहिए। यह तालिकाओं में असंगत संशोधनों को रोकने के लिए है।

आपके उदाहरण में, आपकी तालिकाएँ हैं:

tblDomare के साथ PRIMARY KEY (PersNR):

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

tblBana:

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

यह वाक्य:

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

कहते हैं कि tblDomareकुंजी के साथ किसी भी लाइन में कुंजी पर PersNRतालिका में एक पत्राचार होना चाहिए । आपकी त्रुटि है क्योंकि आपके पास बिना किसी पत्राचार के साथ सम्मिलित लाइनें हैं ।tblBanaBanNRtblDomaretblBana

अपने मुद्दे को ठीक करने के लिए 2 समाधान : - या तो tblDomare tblBana` (लेकिन आपकी तालिका खाली होगी) के tblBanaसाथ लाइनें जोड़ेंBanNR in (6811034679, 7606091347, 8508284163) - or remove all lines inthat have no correspondance in

सामान्य सलाह : तालिकाओं को आबाद करने से पहले आपके पास फॉरेन की बाधा होनी चाहिए। टेबल की उपयोगकर्ता को विसंगतियों से भरने से रोकने के लिए विदेशी कुंजियाँ यहाँ हैं।


-3

और सिर्फ FYI करें, यदि आप अपने सभी डेटा संदर्भ जांच करते हैं और कोई बुरा डेटा नहीं पाते हैं ... तो जाहिर है कि दो तालिकाओं और उन क्षेत्रों के बीच एक विदेशी कुंजी बाधा पैदा करना संभव नहीं है, जहां वे क्षेत्र दोनों तालिकाओं में प्राथमिक कुंजी हैं! मुझे यह मत पूछो कि मुझे यह कैसे पता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.