सुरक्षित मोड के तहत mysql हटाएं


92

मेरे पास एक टेबल इंस्ट्रक्टर है और मैं उन रिकॉर्ड्स को हटाना चाहता हूं जिनमें वेतन एक सीमा में है। एक सहज तरीका इस प्रकार है:

delete from instructor where salary between 13000 and 15000;

हालांकि, सुरक्षित मोड के तहत, मैं एक प्राथमिक कुंजी (आईडी) प्रदान किए बिना रिकॉर्ड को हटा नहीं सकता।

इसलिए मैं निम्नलिखित एसक्यूएल लिखता हूं:

delete from instructor where ID in (select ID from instructor where salary between 13000 and 15000);

हालाँकि, एक त्रुटि है:

You can't specify target table 'instructor' for update in FROM clause

मैं उलझन में हूं क्योंकि जब मैं लिखता हूं

select * from instructor where ID in (select ID from instructor where salary between 13000 and 15000);

यह एक त्रुटि उत्पन्न नहीं करता है।

मेरा सवाल यह है कि:

  1. इस त्रुटि संदेश का वास्तव में क्या मतलब है और मेरा कोड गलत क्यों है?
  2. सुरक्षित मोड के तहत काम करने के लिए इस कोड को कैसे फिर से लिखना है?

धन्यवाद!


क्या आप सुरक्षित मोड चालू रखना चाहते हैं? और आप mySql कार्यक्षेत्र का उपयोग कर रहे हैं?
१it

आपके दोनों सवालों का जवाब हां में है। और मुझे आश्चर्य है कि जब मैंने पीके के बिना mysql डेटाबेस में रिकॉर्ड को हटाने के लिए jdbc का उपयोग किया, तो यह एक त्रुटि उत्पन्न नहीं करता है। तो सुरक्षित मोड केवल mysql कार्यक्षेत्र के लिए है?
रोलैंड लू

1
नहीं - मैं पूछ रहा था क्योंकि अगर आप इसे mySQL कार्यक्षेत्र में बंद करना चाहते थे, तो मैं आपको बता सकता था कि कैसे। व्यक्तिगत तौर पर मैं महान सुरक्षा बुद्धिमान इसे बंद के साथ काम ... पहचान पत्र के लिए हो रही है - लेकिन विकास बुद्धिमान, मैं इसे एक दर्द हो पाया
wribit

जवाबों:


233

चारों ओर घूमते हुए, लोकप्रिय उत्तर "बस सुरक्षित मोड को बंद करना" प्रतीत होता है :

SET SQL_SAFE_UPDATES = 0;
DELETE FROM instructor WHERE salary BETWEEN 13000 AND 15000;
SET SQL_SAFE_UPDATES = 1;

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

तो, आपकी दूसरी क्वेरी निशान के करीब है, लेकिन एक और समस्या हिट करती है: MySQL उपश्रेणियों पर कुछ प्रतिबंध लागू करता है, और उनमें से एक यह है कि आप किसी तालिका को उप-वर्ग में से चयन करते समय संशोधित नहीं कर सकते।

MySQL मैनुअल से उद्धरण, उपश्रेणियों पर प्रतिबंध :

सामान्य तौर पर, आप किसी तालिका को संशोधित नहीं कर सकते हैं और किसी उपश्रेणी में उसी तालिका से चयन कर सकते हैं। उदाहरण के लिए, यह सीमा निम्नलिखित रूपों के कथनों पर लागू होती है:

DELETE FROM t WHERE ... (SELECT ... FROM t ...);
UPDATE t ... WHERE col = (SELECT ... FROM t ...);
{INSERT|REPLACE} INTO t (SELECT ... FROM t ...);

अपवाद: पूर्ववर्ती निषेध लागू नहीं होता है यदि आप FROM खंड में संशोधित तालिका के लिए एक उपश्रेणी का उपयोग कर रहे हैं। उदाहरण:

UPDATE t ... WHERE col = (SELECT * FROM (SELECT ... FROM t...) AS _t ...);

यहां FROM क्लॉज में उपश्रेणी से परिणाम एक अस्थायी तालिका के रूप में संग्रहीत किया जाता है, इसलिए t से संबंधित पंक्तियों को पहले ही चुना जा चुका होता है जब तक कि अपडेट t नहीं होता है।

वह आखिरी बिट आपका उत्तर है। एक अस्थायी तालिका में लक्ष्य आईडी का चयन करें, फिर उस तालिका में आईडी संदर्भित करके हटाएं:

DELETE FROM instructor WHERE id IN (
  SELECT temp.id FROM (
    SELECT id FROM instructor WHERE salary BETWEEN 13000 AND 15000
  ) AS temp
);

SQLFiddle डेमो


6
आपके समझाने के लिए धन्यवाद! हालाँकि, मैंने mysql कार्यक्षेत्र में आपके कोड की कोशिश की और फिर भी यह कहा कि "आप सुरक्षित अपडेट मोड का उपयोग कर रहे हैं और आपने एक WHERE के बिना एक टेबल को अपडेट करने का प्रयास किया है जो एक कुंजी स्तंभ का उपयोग करता है"।
रोलैंड लूओ

यह अप्रत्याशित है। क्या आपकी प्राथमिक कुंजी किसी भिन्न नाम से है? मुझे लगता है कि आपका प्रश्न यह बताता है कि IDमेरा नाम उपयोग करता है id
रट

हां, मैं इसे आईडी में बदल देता हूं और यह काम नहीं करता है। मैं प्रशिक्षक से हटाने की कोशिश की जहां आईडी = '1' और यह काम करता है तो आईडी प्राथमिक कुंजी है
रॉलेंड लुओ

1
@rolandluo मुझे पता है कि यह एक लंबा समय रहा है, लेकिन अगर आप कभी भी एक समाधान निकालते हैं तो मैं उत्सुक हूं। स्पष्ट रूप से इस पद्धति ने अन्य परिस्थितियों में काम किया है, इसलिए मुझे आश्चर्य है कि आपका मामला अलग क्यों है। आपके सर्वर या संस्करण के लिए कुछ विशिष्ट, शायद?
रटर

19

आप MySQL को सोच में डाल सकते हैं कि आप वास्तव में एक प्राथमिक कुंजी कॉलम निर्दिष्ट कर रहे हैं। यह आपको सुरक्षित मोड को "ओवरराइड" करने की अनुमति देता है।

मान लें कि आपके पास एक ऑटो-इन्क्रिमिंग संख्यात्मक प्राथमिक कुंजी के साथ एक तालिका है, तो आप निम्न कार्य कर सकते हैं:

DELETE FROM tbl WHERE id <> 0

12

मैसूर कार्यक्षेत्र में सुरक्षित मोड को बंद करना 6.3.4.0

संपादन मेनू => वरीयताएँ => SQL संपादक: अन्य अनुभाग: "सुरक्षित अपडेट" पर क्लिक करें ... विकल्प को अनचेक करने के लिए

कार्यक्षेत्र वरीयताएँ


2
"कैसे सुरक्षित मोड के तहत काम करने के लिए इस कोड को फिर से लिखना है ?" ==> आपका जवाब बताता है कि सुरक्षित मोड को कैसे निष्क्रिय करना है?)
बाइटॉम्पी

2
क्षमा करें, मैंने प्रश्न को पूरी तरह गलत समझा। मुझे यह विषय तब मिला जब मैं माईसकल कार्यक्षेत्र के साथ तालिकाओं से हटाने में सक्षम नहीं था, और mysql कार्यक्षेत्र के साथ एक टिप्पणी में एक समान प्रश्न था, लेकिन मैं टिप्पणी नहीं बना सकता। मैंने सोचा, कि यह भविष्य के संदर्भ के लिए इसे यहाँ लिखने के लिए एक अच्छी जगह होगी ...
पीटर बी

0

मेरे पास एक और अधिक सरल समाधान है, यह मेरे लिए काम कर रहा है; यह एक वर्कअराउंड भी है, लेकिन उपयोग करने योग्य हो सकता है और आपको अपनी सेटिंग नहीं बदलनी होगी। मुझे लगता है कि आप उस मूल्य का उपयोग कर सकते हैं जो कभी नहीं होगा, फिर आप अपने WHERE क्लॉज पर इसका उपयोग करते हैं

MyTield से DELETE यहां से करें MyField IS_NOT_EQUAL AnyValueNoItemOnMyFieldWillEverHave

मुझे वह समाधान बहुत पसंद नहीं है, इसीलिए मैं यहां हूं, लेकिन यह काम करता है और जो इसका उत्तर दिया गया है, उससे बेहतर लगता है

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