बोगस विदेशी कुंजी बाधा विफल


110

मुझे यह त्रुटि संदेश मिला:

ERROR 1217 (23000) लाइन 40 पर: पेरेंट रो को डिलीट या अपडेट नहीं कर सकता: विदेशी कुंजी बाधा विफल रहती है

... जब मैं एक तालिका छोड़ने की कोशिश करता हूं:

DROP TABLE IF EXISTS `area`;

... इस तरह परिभाषित:

CREATE TABLE `area` (
  `area_id` char(3) COLLATE utf8_spanish_ci NOT NULL,
  `nombre_area` varchar(30) COLLATE utf8_spanish_ci NOT NULL,
  `descripcion_area` varchar(100) COLLATE utf8_spanish_ci NOT NULL,
  PRIMARY KEY (`area_id`),
  UNIQUE KEY `nombre_area_UNIQUE` (`nombre_area`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci;

मजेदार बात यह है कि मैंने पहले ही स्कीमा में अन्य सभी तालिकाओं को गिरा दिया है जिनके पास विदेशी कुंजी है area। दरअसल, areaतालिका को छोड़कर डेटाबेस खाली है ।

यदि डेटाबेस में कोई अन्य ऑब्जेक्ट नहीं है तो संभवतः यह चाइल्ड रो कैसे हो सकता है? जहां तक ​​मुझे पता है, InnoDB अन्य स्कीमाओं पर विदेशी कुंजी की अनुमति नहीं देता है, क्या यह है?

(मैं भी एक RENAME TABLE area TO something_elseकमांड चला सकते हैं : -?)


क्या यह संभव है कि तालिका किसी अन्य स्कीमा में एक संदर्भ-अखंडता संबंध का एक हिस्सा है?
राज मोर

मेरे पास ऐप की कुछ अन्य प्रतियां हैं, इसलिए यह हमेशा संभव है। हालाँकि, मैं जिस वाक्य रचना का उपयोग करता हूं वह मूल रूप से है CONSTRAINT fk_servicio_area1 FOREIGN KEY (area_id) REFERENCES area (area_id), अर्थात, तालिका संदर्भ पर कोई स्कीमा नाम नहीं: -?
अल्वारो गोंजालेज

जवाबों:


101

दो संभावनाएँ:

  1. एक अन्य स्कीमा (mysql शब्दावली में "डेटाबेस") के भीतर एक तालिका है जिसमें एक FK संदर्भ है
  2. सहज आंतरिक डेटा शब्दकोश mysql एक के साथ सिंक से बाहर है।

आप यह देख सकते हैं कि ड्रॉप फेल होने के बाद "SHOW Engine INNODB STATUS" को किस तालिका में रखा गया था।

यदि यह बाद का मामला है, तो मैं डंप कर दूंगा और यदि आप कर सकते हैं तो पूरे सर्वर को पुनर्स्थापित करें।

MySQL 5.1 और इसके बाद के संस्करण आपको त्रुटि संदेश में FK के साथ तालिका का नाम देगा।


1
मैं अब इस मुद्दे को पुन: पेश नहीं कर सकता। सिंक डिक्शनरी के बाहर एक संभावित कारण के रूप में खड़ा है। मैं इसका दिन परीक्षण करूंगा और देखूंगा कि क्या SHOW ENGINE INNODB STATUSरिपोर्ट आती है।
अल्वारो गोंजालेज

3
इस उत्तर के लिए धन्यवाद! मेरे पास एक बहुत-से-कई टेबल अभी भी संदर्भित तालिका है जिसे हम नहीं छोड़ सकते हैं, इसलिए मुझे पहले उस तालिका को छोड़ना पड़ा।
क्रिस्चियन अवार्ड

5
SHOW इंजन INNODB STATUS "LATEST FOREIGN KEY ERROR" के तहत अंतिम विदेशी कुंजी त्रुटि को सूचीबद्ध करता है। यह एक टाइमस्टैम्प है।
बब्रनाम

विषय तालिका के संदर्भ कुंजी रखने वाली तालिका अभी भी हो सकती है। यह इस तरह से मेरे मामले में था।
आरटी

बहुत समय बचाया। "सबसे नवीनतम कुंजी त्रुटि" के तहत db को गिरा दिया
Sand1512

121

मांग पर, अब जवाब के रूप में ...

MySQL Query Browser या phpMyAdmin का उपयोग करते समय, ऐसा प्रतीत होता है कि प्रत्येक क्वेरी ( Bugs.mysql.com/bug.php?id=8280 ) के लिए एक नया कनेक्शन खोला गया है , जिससे सभी क्वेरी स्टेटमेंट्स को एक क्वेरी में लिखना संभव हो जाता है, उदा।

SET FOREIGN_KEY_CHECKS=0; 
DROP TABLE my_first_table_to_drop; 
DROP TABLE my_second_table_to_drop; 
SET FOREIGN_KEY_CHECKS=1; 

जहां SET FOREIGN_KEY_CHECKS=1एक अतिरिक्त सुरक्षा उपाय के रूप में कार्य करता है ...


2
PhpMyAdmin का उपयोग करके डंप बनाने वालों के लिए, एक विकल्प "विदेशी कुंजी चेक अक्षम करें" है जो स्वचालित रूप SET FOREIGN_KEY_CHECKS=0;से डंप की शुरुआत में जोड़ देगा ।
माइक

ऐसा लगता है कि phpMyAdmin ने इस प्यारे फीचर को लागू कर दिया है, अब मैं mysqlWorkbench का इंतजार कर रहा हूं! :)
कार्लिस रोड

@CodeMed FYI करें, मैंने MarkR के उत्तर को स्वीकार कर लिया क्योंकि यह उस मुद्दे के लिए एक स्पष्टीकरण प्रदान करता है जो समझ में आता है- हालांकि मैं मानता हूं कि मैं इसे सत्यापित नहीं कर सका क्योंकि मैंने अगले 6 वर्षों में इस मुद्दे का सामना नहीं किया, एक बार भी नहीं। यह और पहले के उत्तर एक वर्कअराउंड प्रदान करते हैं (उस अच्छे के लिए महान) लेकिन वास्तव में स्वयं प्रश्न को संबोधित न करें और चूंकि आप केवल एक उत्तर को स्वीकार कर सकते हैं जो मुझे चुनना था।
अल्वारो गोंजालेज

1
चेतावनी: यह एक समाधान नहीं है, लेकिन केवल आलसी आदमी का समाधान है। इसका उपयोग करने के बाद (कुछ अन्य टेबल पर रिकॉर्ड किए गए टेबल की ओर इशारा करते हुए) के साथ, आप विदेशी कुंजियों को लटकाने का अनुभव करेंगे, जो आपके डेटाबेस की स्थिरता ( एसीआईडी में सी ) को तोड़ देती है और आपके आवेदन सभी जगह अपवादों को फेंकना शुरू कर देंगे। आपको चेतावनी दी गई थी।
bekce

हालाँकि मुझे यकीन है कि बाक़ी की चेतावनी को समझा जाना चाहिए और ध्यान दिया जाना चाहिए, इस समाधान ने मेरे लिए काम किया, ऐसी स्थिति में जब मुझे विश्वास था कि मैं उन सभी तालिकाओं को भी छोड़ रहा हूँ जो परेशान विदेशी प्रमुख बाधाओं के साथ तालिकाओं की ओर इशारा कर रहे थे।
user1147171

47

विदेशी कुंजी जाँच अक्षम करें

SET FOREIGN_KEY_CHECKS=0

62
सही कमांड प्रतीत होता है SET FOREIGN_KEY_CHECKS=0और यह त्रुटि संदेश को ठीक करता है। क्या आपके पास इस बारे में कोई विचार है कि इसकी आवश्यकता क्यों है? क्या टेबल के चले जाने के बाद भी विदेशी चाबियों को कैश किया जाता है?
अल्वारो गोंजालेज

1
सच कहने के लिए, मुझे नहीं पता कि ऐसी समस्या क्यों उत्पन्न होती है, लेकिन सुनिश्चित करें कि हर बार जब आप कुछ बड़े बदलाव या अपडेट करते हैं, तो आप कुंजी जाँच को अक्षम कर दें। यह मेरे साथ कई बार हुआ है, मुझे नींद के बिना दिनों के लिए छोड़ रहा है।
फ्लैक्रॉन ब्युटीकी जूल

55
SET FOREIGN_KEY_CHECKS=1;आपके द्वारा किए जाने के बाद सुनिश्चित करें !
पेड्रो_लैंडलैंड

5
MySQL Query Browser या phpMyAdmin का उपयोग करते समय, ऐसा प्रतीत होता है कि प्रत्येक क्वेरी ( Bugs.mysql.com/bug.php?id=8280 ) के लिए एक नया कनेक्शन खोला गया है , जिससे सभी क्वेरी स्टेटमेंट्स को एक क्वेरी में लिखना संभव हो जाता है, उदा। SET FOREIGN_KEY_CHECKS=0; DROP TABLE my_first_table_to_drop; DROP TABLE my_second_table_to_drop; SET FOREIGN_KEY_CHECKS=1; जहाँ SET FOREIGN_KEY_CHECKS = 1 एक अतिरिक्त सुरक्षा उपाय के रूप में कार्य करता है ...
कार्लिस रोडे

1
@KarlisRode, phpMyAdmin पर टिप्पणी के लिए ब्रावो। यदि आप इसे एक उत्तर के रूप में रखना चाहते हैं, तो मैं इसे +1 करूंगा।
सेबलफोस्टे

28

से इस ब्लॉग :

आप अस्थायी रूप से विदेशी कुंजी जांच अक्षम कर सकते हैं:

SET FOREIGN_KEY_CHECKS=0;

जब भी आप गड़बड़ कर रहे हों, बस उन्हें पुनर्स्थापित करना सुनिश्चित करें:

SET FOREIGN_KEY_CHECKS=1;

जैसा कि मैंने स्थानीय में विकसित किया था अच्छा जवाब :)
एडेलिन

यह एक मान्य वर्कअराउंड है (मैं इसकी पुष्टि कर सकता हूं कि यह काम करता है) लेकिन लिंक की गई ब्लॉग प्रविष्टि वास्तव में इस प्रश्न के बारे में बात नहीं करती है (एक डेटाबेस जो पहले से ही एक टेबल के लिए खाली बचा है)।
अल्वारो गोंजालेज

6

उम्मीद है कि इसका काम है

SET विदेशी_की_चेक = 0; ड्रॉप टेबल table name; SET विदेशी_की_चेक = 1;


हाँ, यह काम करता है, जैसा कि पहले उल्लेख किया गया है ;-)
Gonlvaro González

1

पटरियों पर, एक निम्नलिखित का उपयोग कर सकता है rails console:

connection = ActiveRecord::Base.connection
connection.execute("SET FOREIGN_KEY_CHECKS=0;")

0

हो सकता है कि इस तालिका के साथ काम करने से पहले आपको एक त्रुटि मिली हो। आप तालिका का नाम बदल सकते हैं और इसे फिर से निकालने का प्रयास कर सकते हैं।

ALTER TABLE `area` RENAME TO `area2`;
DROP TABLE IF EXISTS `area2`;

0

मुझे एक आसान समाधान मिला, डेटाबेस निर्यात करें, इसे संपादित करें जिसे आप एक पाठ संपादक में संपादित करना चाहते हैं, फिर इसे आयात करें। किया हुआ


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

1
मैं वास्तव में नहीं समझ पा रहा हूं कि आप क्या कर रहे हैं। डेटाबेस CREATE TABLEको डंप करना, कोड को हटाना और डंप को फिर से लोड करना ... MySQL को टेबल को हटाने नहीं देगा। और अगर आप का मतलब एक नए डेटाबेस में डंप को बहाल करना है ... यदि आप मेरी तरह सभी तालिकाओं को मिटा देना चाहते हैं, तो एक नया बनाया गया डेटाबेस पहले से ही खाली हो जाएगा। यदि आप कुछ तालिकाओं को रखना चाहते हैं, तो SET FOREIGN_KEY_CHECKS=0हर जगह उल्लिखित वर्कअराउंड ठीक काम करता है और सरल है; और आपको संभवतः डंप को संपादित करने की आवश्यकता नहीं है क्योंकि आपके डेटा की नई प्रतिलिपि में संभवतः एक आउट-ऑफ-सिंक डेटा शब्दकोश नहीं होगा।
अलवारो गोंजालेज

-1

नष्ट कर सकते हैं नहीं या एक माता पिता पंक्ति को अद्यतन: एक विदेशी कुंजी बाधा में विफल रहता है ( table1user_role, बाधा FK143BF46A8dsfsfds@#5A6BD60विदेशी कुँजी ( user_id) दें संदर्भ user( id))

मैंने दो सरल चरणों में क्या किया। पहले मैं चाइल्ड टेबल को चाइल्ड रो में डिलीट करता हूं जैसे

mysql> table2 से हटाएं जहां role_id = 2 && user_id = 20;

क्वेरी ठीक है, 1 पंक्ति प्रभावित (0.10 सेकंड)

और माता-पिता को हटाने के रूप में दूसरा कदम

तालिका 1 से हटाएं जहां आईडी = 20;

क्वेरी ठीक है, 1 पंक्ति प्रभावित (0.12 सेकंड)

इसके द्वारा मैं उस समस्या को हल करता हूं जिसका अर्थ है डिलीट चाइल्ड फिर डिलीट पैरेंट

आई होप आपको मिल गया। :)


कृपया प्रश्न फिर से पढ़ें। आप ऐसी तालिका नहीं निकाल सकते जो मौजूद नहीं है।
एल्वारो गोंजालेज

इस परिदृश्य में हम विदेशी कुंजी बाधा को हटा सकते हैं, फिर तालिका को हटाने का प्रयास करें। हम इस प्रकार की विदेशी कुंजी जैसे TABLE <TABLE_NAME> DROP CONSTRAINT <FOREIGN_KEY_NAME>
Aadil Masavir
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.