1452 मैसूर त्रुटि - चाइल्ड रो को जोड़ना या अपडेट नहीं करना: एक विदेशी कुंजी बाधा


237

मुझे थोड़ी अजीब समस्या हो रही है। मैं एक टेबल पर एक विदेशी कुंजी जोड़ने की कोशिश कर रहा हूं जो दूसरे का संदर्भ देता है, लेकिन यह किसी कारण से विफल हो रहा है। MySQL के मेरे सीमित ज्ञान के साथ, केवल एक चीज जो संभवतः संदिग्ध हो सकती है वह यह है कि एक अलग तालिका पर एक विदेशी कुंजी है जिसे मैं संदर्भित करने की कोशिश कर रहा हूं।

मैंने SHOW CREATE TABLEदोनों तालिकाओं पर एक प्रश्न किया है , sourcecodes_tagsविदेशी कुंजी के साथ तालिका sourcecodesहै, संदर्भित तालिका है।

CREATE TABLE `sourcecodes` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `user_id` int(11) unsigned NOT NULL,
 `language_id` int(11) unsigned NOT NULL,
 `category_id` int(11) unsigned NOT NULL,
 `title` varchar(40) CHARACTER SET utf8 NOT NULL,
 `description` text CHARACTER SET utf8 NOT NULL,
 `views` int(11) unsigned NOT NULL,
 `downloads` int(11) unsigned NOT NULL,
 `time_posted` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 PRIMARY KEY (`id`),
 KEY `user_id` (`user_id`),
 KEY `language_id` (`language_id`),
 KEY `category_id` (`category_id`),
 CONSTRAINT `sourcecodes_ibfk_3` FOREIGN KEY (`language_id`) REFERENCES `languages` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `sourcecodes_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `sourcecodes_ibfk_2` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1

CREATE TABLE `sourcecodes_tags` (
 `sourcecode_id` int(11) unsigned NOT NULL,
 `tag_id` int(11) unsigned NOT NULL,
 KEY `sourcecode_id` (`sourcecode_id`),
 KEY `tag_id` (`tag_id`),
 CONSTRAINT `sourcecodes_tags_ibfk_1` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1

यह वह कोड है जो त्रुटि उत्पन्न करता है:

ALTER TABLE sourcecodes_tags ADD FOREIGN KEY (sourcecode_id) REFERENCES sourcecodes (id) ON DELETE CASCADE ON UPDATE CASCADE

2
क्या आप अपना इन्सर्ट / अपडेट कमांड भी पोस्ट कर सकते हैं जिसके परिणामस्वरूप त्रुटि हुई है?
ज़ेड

64
जब आप इस विदेशी कुंजी को जोड़ते हैं तो आपकी टेबल खाली होती हैं?
जेड

12
इस क्वेरी को यह देखने के लिए चलाने का प्रयास करें कि क्या कोई सोर्सकोड_आईडी है जो वास्तविक आईडी नहीं है: sourcecodes_tags से स्रोत sourcecode_id का चयन करें जहां sourcecode_id में नहीं (INmp से सेलेक्ट आईडी से स्रोत चुनें);
जेड

11
धन्यवाद जेड, यह एक समस्या थी जिसमें एक तालिका में डेटा था। इसके बारे में सोचने से अब समझ में आता है कि यह विफल हो रहा था क्योंकि ऐसी चीजें थीं जो गैर-मौजूदा वस्तुओं को संदर्भित कर रही थीं, लेकिन मैंने कभी भी इसका अनुमान नहीं लगाया होगा। धन्यवाद!
ज़िम

2
यदि तालिका खाली है तो यह विफल क्यों होता है?
theblackpearl

जवाबों:


226

काफी संभावना है कि आपकी sourcecodes_tagsतालिका में वे sourcecode_idमान हैं जो अब आपकी sourcecodesतालिका में मौजूद नहीं हैं । आपको पहले उन लोगों से छुटकारा पाना होगा।

यहां एक क्वेरी है जो उन आईडी को पा सकती है:

SELECT DISTINCT sourcecode_id FROM 
   sourcecodes_tags tags LEFT JOIN sourcecodes sc ON tags.sourcecode_id=sc.id 
WHERE sc.id IS NULL;

UPDATE sourcecodes_tags SET sourcecode_id = NULL WHERE sourcecode_id NOT IN (SELECT id FROM sourcecodes)उन आईडी से छुटकारा पाने में मदद करनी चाहिए। या यदि अंदर nullअनुमति नहीं है sourcecode_id, तो उन पंक्तियों को हटा दें या उन लापता मूल्यों को sourcecodesतालिका में जोड़ें।
naXa

मैं भी यही सोच रहा था, लेकिन मेरे लिए SELECT Tchild.id FROM Tchild INNER JOIN Tmain ON Tmain.id = Tchild.fk_id WHERE Tmain.id IS NULLकुछ भी वापस नहीं आया, इसलिए समस्या कहीं और है?
मेलमन

मेरे लिए यही समस्या थी। मैं चलाने की कोशिश कर रहा था UPDATE `homestead`.`automations` SET `deleted_at`=NULL WHERE deleted_at IS NOT NULL;, जिसमें एक विदेशी कुंजी शामिल नहीं थी, इसलिए मैं भ्रमित था। लेकिन तथ्य यह है कि मेरी संपर्क तालिका कुछ रिकॉर्ड गायब थी कि ऑटोमेशन टेबल ने इसे "त्रुटि कोड: 1452" फेंकने के लिए संदर्भित किया। चाइल्ड रो को जोड़ना या अपडेट नहीं किया जा सकता: एक विदेशी कुंजी बाधा विफल "।
रयान

99

मेरे MySQL डेटाबेस के साथ भी यही मुद्दा था लेकिन आखिरकार, मुझे एक समाधान मिला जिसने मेरे लिए काम किया।
चूँकि मेरी तालिका में mysql के दृष्टिकोण से सब कुछ ठीक था (दोनों तालिकाओं को InnoDB इंजन का उपयोग करना चाहिए और प्रत्येक कॉलम का डेटा टाइप उसी प्रकार का होना चाहिए जो विदेशी कुंजी बाधा में भाग लेता है)।
केवल एक चीज जो मैंने की थी वह विदेशी कुंजी जांच को अक्षम करना और बाद में विदेशी कुंजी ऑपरेशन करने के बाद इसे सक्षम करना था।
मेरे द्वारा उठाए गए कदम:

SET foreign_key_checks = 0;
alter table tblUsedDestination add constraint f_operatorId foreign key(iOperatorId) references tblOperators (iOperatorId); Query
OK, 8 rows affected (0.23 sec) Records: 8  Duplicates: 0  Warnings: 0
SET foreign_key_checks = 1;

49
Foreign_key_checks एक कारण से हैं। यदि आप विदेशी कुंजी नहीं जोड़ सकते हैं क्योंकि यह बाधा का उल्लंघन करता है, तो आपको पहले डेटा को सही करना चाहिए। चेक को बंद करना फिर आपको असंगत स्थिति में छोड़ देता है। विदेशी कुंजी चेक ओवरहेड जोड़ते हैं, यदि आप उन्हें उपयोग नहीं करना चाहते हैं, तो इसके बजाय मायसम का उपयोग करें।
cs_alumnus

5
@AbuSadatMohammedYasin नहीं यह नहीं करना चाहिए: सवाल "क्या चल रहा है" और यह जवाब बस इसे समझाने का प्रयास नहीं करता है। जैसा कि cs_alumnus ने उल्लेख किया है, एक बड़ी समस्या है: सभी नए मान जो अन्य तालिका में एक और मान संदर्भित करना चाहिए (जैसा कि एक विदेशी कुंजी को करना चाहिए) असंगत स्थिति पैदा करने के लिए कुछ भी नहीं कह सकता है। केटानो की संक्षिप्त और प्रभावी व्याख्या आपको यह जानने की अनुमति देती है कि आपको बाधाएं बनाने से पहले किन मूल्यों को अपडेट करना चाहिए ताकि आप उन प्रश्नों से आश्चर्यचकित न हों जो उन मूल्यों को वापस करना चाहिए जो मौजूद होना चाहिए!
आर्मफूट

55

का प्रयोग करें NOT INजहां की कमी कर रहे हैं खोजने के लिए बाधित :

SELECT column FROM table WHERE column NOT IN 
(SELECT intended_foreign_key FROM another_table)

इसलिए, विशेष रूप से:

SELECT sourcecode_id FROM sourcecodes_tags WHERE sourcecode_id NOT IN 
(SELECT id FROM sourcecodes)

EDIT: INऔर NOT INऑपरेटरों को ऑपरेटरों की तुलना में बहुत तेजी से जाना जाता है JOIN, साथ ही साथ निर्माण और दोहराने में बहुत आसान है।


1
इसलिए, अगर मैं इसे सही ढंग से समझ पाऊं, तो हम एक विदेशी कुंजी को उस तालिका में जोड़ सकते हैं जिसमें पहले से ही डेटा है, लेकिन केवल तभी जब माता-पिता की तालिका में प्रत्येक पंक्ति के लिए एक बाल पंक्ति मौजूद हो? यदि मूल तालिका में प्रत्येक पंक्ति के लिए कोई चाइल्ड रो नहीं हैं (जो कि आपकी क्वेरी को पता चलता है) तो विदेशी कुंजी स्क्रिप्ट विफल हो जाएगी।
विंसेंट

@ मूल तालिका से अगर आप मतलब है कि तालिका संदर्भित हो रही है, तो हाँ! इसलिए केटानो के चयन के साथ आपको नई बाधा (FK) जोड़ने से पहले आपको अपनी "चाइल्ड" टेबल से अपडेट / हटाने की जरूरत है। एक बार जब वे सभी "other_table" में मूल्यों की ओर इशारा करते हैं तो आप जाने के लिए अच्छे हैं!
आर्मफुट

23

तालिकाओं को काटें और फिर FK बाधा को जोड़ने का प्रयास करें

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


4
हर चीज को छांटने की जरूरत नहीं है। "UPDATE sourcecodes_tags SET sourcecode_id = NULL WHERE sourcecode_id IN (सेलेक्ट आईडी से सोर्स नहीं)" पर्याप्त होना चाहिए। या यदि "sourcecode_id" में नल की अनुमति नहीं है, तो उन पंक्तियों को हटा दें या उन लापता मानों को "सोर्सकोड" तालिका में जोड़ें।
Torben

1
कभी-कभी, यदि डेटा ऑटोकरेमेंट पीके बढ़ाता है, तो यह आपको कम करने के लिए मजबूर करता है।
फ्रांस्वा ब्रेटन

2
@ShankarDamodaran यह सुनिश्चित नहीं किया गया है कि टेबल क्यों काम कर रही है लेकिन इस समाधान ने मेरे लिए अच्छा काम किया है। मैं अपने रिश्तों को काम करने में सक्षम था ... धन्यवाद!
मिज़किटा

@ मिज़किटा यह काम करता है क्योंकि यह उन पंक्तियों को हटा देता है जिनका दूसरी तालिका में कोई संगत मूल्य नहीं है, जिससे नया अवरोध पैदा हो सकता है। यदि आप बस उन पंक्तियों को पाते हैं और उन्हें अपडेट करते हैं या उन्हें हटाते हैं (जैसे केतनो का सुझाव ), तो आपको अन्य पंक्तियों को हटाने की आवश्यकता नहीं है ...
आर्मफूट

@Armfoot - विदेशी कुंजी के साथ तालिका में पहली पंक्ति जोड़ते समय मुझे यह समस्या थी। इसलिए मुझे खोजने के लिए कोई पंक्तियाँ नहीं थीं।
Krewetka

16

मेरे लिए, यह समस्या जांच और हल करने के लिए थोड़ी अलग और सुपर आसान थी।

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

    SHOW TABLE STATUS WHERE Name =  't1';

    ALTER TABLE t1 ENGINE=InnoDB;

14

यह भी तब होता है जब एक विदेशी कुंजी को पैरेंट को सेट किया जाता है। बच्चे के लिए। यदि बच्चे के पास पहले से ही 0 का मान है और किसी भी माता-पिता का मूल्य 0 नहीं है।

आपको यह सुनिश्चित करने की आवश्यकता होगी कि प्रत्येक चाइल्ड.कैल्यूमन NULL है या इसका मान पेरेंट में मौजूद है

और अब जब मैंने पढ़ा कि कथन nos लिखा है, तो वह वही है जो मान्य कर रहा है।


14

मुझे आज भी यही समस्या थी। मैंने चार चीजों के लिए परीक्षण किया, उनमें से कुछ पहले से ही यहां उल्लिखित हैं:

  1. क्या आपके चाइल्ड कॉलम में कोई मान हैं जो पेरेंट कॉलम में मौजूद नहीं हैं (NULL के अलावा, अगर चाइल्ड कॉलम नॉबल है)

  2. क्या बच्चे और माता-पिता के स्तंभों में समान डेटाटाइप है?

  3. क्या आपके द्वारा संदर्भित मूल स्तंभ पर कोई अनुक्रमणिका है? MySQL को प्रदर्शन कारणों से इसकी आवश्यकता प्रतीत होती है ( http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html )

  4. और इस एक ने मेरे लिए इसे हल किया: क्या दोनों तालिकाओं में समान समतुल्य है?

मेरे पास UTF-8 में एक टेबल थी और दूसरी में कुछ था। यह काम नहीं किया। आइसो-टेबल को UTF-8 कोलेशन में बदलने के बाद बाधाओं को बिना किसी समस्या के जोड़ा जा सकता है। मेरे मामले में, phpMyAdmin ने विदेशी कुंजी बाधा बनाने के लिए ड्रॉपडाउन में iso-एन्कोडिंग में चाइल्ड टेबल भी नहीं दिखाया।


7

ऐसा लगता है कि कॉलम लाइन 0 के लिए कुछ अमान्य मान है जो एक वैध विदेशी कुंजी नहीं है इसलिए MySQL इसके लिए एक विदेशी कुंजी बाधा निर्धारित नहीं कर सकता है।

आप इन चरणों का पालन कर सकते हैं:

  1. उस स्तंभ को छोड़ दें जिसके लिए आपने FK बाधा निर्धारित करने का प्रयास किया है।

  2. इसे फिर से जोड़ें और इसके डिफ़ॉल्ट मान को NULL के रूप में सेट करें।

  3. फिर से इसके लिए एक विदेशी कुंजी बाधा निर्धारित करने का प्रयास करें।


5

मैं एक ही समस्या हूँ, मैंने अपनी तालिकाओं की पंक्तियों की जाँच की और पाया कि खेतों की कीमत के साथ कुछ असंगति थी जिसे मैं एक विदेशी कुंजी परिभाषित करना चाहता था। मैंने उन मानों को ठीक किया, फिर से कोशिश की और समस्या हल हो गई।


4

मैं अपनी तालिका के सभी डेटा को हटाता हूं, और फिर से परिवर्तन चलाता हूं। यह काम करता हैं। शानदार एक नहीं है, लेकिन यह बहुत समय बचाता है, खासकर आपका एप्लिकेशन अभी भी बिना किसी ग्राहक डेटा के विकास के चरण में है।


4

इसे इस्तेमाल करे

SET foreign_key_checks = 0;

ALTER TABLE sourcecodes_tags ADD FOREIGN KEY (sourcecode_id) REFERENCES sourcecodes (id) ON DELETE CASCADE ON UPDATE CASCADE

SET foreign_key_checks = 1;

2

मुझे लगभग तीन अलग-अलग समयों में यही समस्या थी। प्रत्येक उदाहरण में ऐसा इसलिए था क्योंकि मेरे रिकॉर्ड में से एक (या अधिक) नई विदेशी कुंजी के अनुरूप नहीं था। आप कुंजी जोड़ने की कोशिश करने से पहले विदेशी कुंजी के वाक्यविन्यास बाधाओं का पालन करने के लिए अपने मौजूदा रिकॉर्ड को अपडेट करना चाह सकते हैं। निम्नलिखित उदाहरण को आम तौर पर समस्या रिकॉर्ड को अलग करना चाहिए:

SELECT * FROM (tablename)
    WHERE (candidate key) <> (proposed foreign key value) 
        AND (candidate key) <> (next proposed foreign key value)

AND (candidate key) <> (next proposed foreign key value)विदेशी कुंजी में प्रत्येक मान के लिए अपनी क्वेरी के भीतर दोहराएं ।

यदि आपके पास एक टन रिकॉर्ड है, तो यह मुश्किल हो सकता है, लेकिन यदि आपकी तालिका यथोचित रूप से छोटी है तो इसे बहुत लंबा नहीं होना चाहिए। मैं SQL सिंटैक्स में सुपर अद्भुत नहीं हूं, लेकिन इसने हमेशा मेरे लिए समस्या को अलग कर दिया है।


2

अपने दोनों तालिकाओं के डेटा को खाली करें और कमांड चलाएं। यह काम करेगा।


VHanded ने 3 साल पहले भी यही जवाब दिया था। चलो उम्मीद करते हैं कि तालिकाओं में कोई महत्वपूर्ण डेटा नहीं था ...
xlecoustillier

2

लारवेल और वाक्पटु का उपयोग करते समय मुझे यह त्रुटि हो रही थी, एक विदेशी कुंजी लिंक बनाने की कोशिश करने से 1452 हो जाएगा। समस्या तालिका में डेटा की कमी थी।

एक उदाहरण के लिए कृपया यहाँ देखें: http://mstd.eu/index.php/2016/12/02/laravel-eloquent-integrity-constraint-violation-1452-foreign-key-constraint/


1

मैं इस समाधान को तैयार कर रहा था और इस उदाहरण से मदद मिल सकती है।

मेरे डेटाबेस में उनकी आईडी के लिए प्राथमिक कुंजी के साथ दो टेबल (ईमेल और क्रेडिट_कार्ड) हैं। एक अन्य तालिका (क्लाइंट) इस तालिका को विदेशी कुंजी के रूप में संदर्भित करती है। मेरे पास क्लाइंट डेटा के अलावा ईमेल होने का एक कारण है।

पहले मैं संदर्भित तालिकाओं (ईमेल, credit_card) के लिए पंक्ति डेटा सम्मिलित करता हूं फिर आपको प्रत्येक के लिए आईडी मिलता है, तीसरे तालिका (क्लाइंट) में उन आईडी की आवश्यकता होती है।

यदि आप संदर्भित तालिकाओं में पहली पंक्तियाँ सम्मिलित नहीं करते हैं, तो जब आप विदेशी कुंजियों का संदर्भ देते हैं तो तीसरी तालिका में एक नई पंक्ति सम्मिलित करने पर MySQL अभिप्रेरित नहीं कर पाएंगे।

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

उम्मीद है की यह मदद करेगा।


mysql> ईमेल (ईमेल) मान ('xxx@yyy.com') में डालें; mysql> ndtc (ndtc, year, month) मानों ('1111222233334444', '2000', '01') में डालें; mysql> ग्राहक (घुमंतू, एपेलिडोस, टेलीफोनो, idNDTC, idEmail) मूल्यों ('myname', 'myapp', '5555555555', 1,1) में डालें;
SubstanceMX

1

सुनिश्चित करें कि मान दूसरी तालिका में है अन्यथा आपको यह त्रुटि दी जाएगी, इसी निर्दिष्ट कॉलम में।

इसलिए यदि इसे असाइन किया गया कॉलम किसी अन्य तालिका की पंक्ति आईडी को सौंपा गया है, तो सुनिश्चित करें कि कोई पंक्ति है जो तालिका में है अन्यथा यह त्रुटि दिखाई देगी।


1

आप इस निर्वासन की कोशिश कर सकते हैं

 START TRANSACTION;
 SET foreign_key_checks = 0;
 ALTER TABLE `job_definers` ADD CONSTRAINT `job_cities_foreign` FOREIGN KEY 
 (`job_cities`) REFERENCES `drop_down_lists`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
 SET foreign_key_checks = 1;
 COMMIT;

नोट: यदि आप phpmyadmin का उपयोग कर रहे हैं तो विदेशी कुंजी चेक सक्षम करें को अनचेक करें

के रूप में उदाहरण यहां छवि विवरण दर्ज करें

आशा है कि यह एकांत आपकी समस्या को ठीक करेगा :)


1

आपको बस एक प्रश्न का उत्तर देने की आवश्यकता है:

क्या आपकी तालिका में पहले से ही डेटा संग्रहीत है? (विशेष रूप से तालिका में विदेशी कुंजी शामिल है।)

यदि जवाब हां है, तो आपको केवल एक चीज की जरूरत है सभी रिकॉर्ड को हटाने के लिए, फिर आप अपनी तालिका में किसी भी विदेशी कुंजी को जोड़ने के लिए स्वतंत्र हैं।

निर्देश हटाएँ: बच्चे से (जिसमें विदेशी कुंजी तालिका शामिल है) मूल तालिका में।

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

यदि उत्तर नहीं है, तो अन्य निर्देशों का पालन करें।


0
UPDATE sourcecodes_tags
SET sourcecode_id = NULL
WHERE sourcecode_id NOT IN (
  SELECT id FROM sourcecodes);

उन आईडी से छुटकारा पाने में मदद करनी चाहिए। या यदि अंदर nullअनुमति नहीं है sourcecode_id, तो उन पंक्तियों को हटा दें या उन लापता मूल्यों को sourcecodesतालिका में जोड़ें।


0

मेरे पास एक ही समस्या थी और समाधान मिला, विदेशी कुंजी कॉलम पर रखने के NULLबजाय NOT NULL। यहाँ एक प्रश्न है:

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;

MySQL ने इस क्वेरी को अंजाम दिया है!


0

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

इसने मेरे लिए काम किया।

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