एक MySQL तालिका या अद्यतन में सम्मिलित करता है, तो मौजूद है


875

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

उदाहरण के लिए:

insert into table (id, name, age) values(1, "A", 19)

मान लीजिए कि अद्वितीय कुंजी है id, और मेरे डेटाबेस में , एक पंक्ति है id = 1। उस स्थिति में, मैं इन मूल्यों के साथ उस पंक्ति को अपडेट करना चाहता हूं। आम तौर पर यह एक त्रुटि देता है।
अगर मैं इसका उपयोग insert IGNOREकरता हूं तो यह त्रुटि को नजरअंदाज करेगा, लेकिन यह अभी भी अपडेट नहीं होगा।


5
SQL को इस उपयोग के मामले के लिए एक आधिकारिक सिंटैक्स की आवश्यकता है जो सिंटैक्स में मूल्यों के दोहराव को मजबूर नहीं करता है और प्राथमिक कुंजी को संरक्षित करता है।
पीट एल्विन

प्रभावित आईडी को MySQL ON DUPLICATE KEY में
क्रिस रूफ

कैविएट: संस्करण 5.7 के रूप में यह दृष्टिकोण INSERT / UPDATE ऑपरेशन के भाग के रूप में सीधे क्लॉज का समर्थन नहीं करता है। इसके अलावा, एक अद्यतन वास्तव में दो अलग-अलग कार्यों (DELETE और INSERT) के रूप में गिना जाता है ... उस मामले में जो ऑडिट उद्देश्यों के लिए मायने रखता है। (Learnbit)
dreftymac

जवाबों:


1599

उपयोग INSERT ... ON DUPLICATE KEY UPDATE

: QUERY

INSERT INTO table (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE    
name="A", age=19

86
+1 जो मैंने पाया है, यह विधि ऑटो-इंक्रीमेंट कुंजी और REPLACE INTO की तुलना में अन्य विशिष्ट कुंजी टकरावों के लिए कम समस्याग्रस्त है, और यह अधिक कुशल है।
एंड्रयू एन्सले

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

7
मैं क्यों आश्चर्य affected row countमें परिणाम 2जब सफलतापूर्वक (डुप्लिकेट कुंजी पर) एकल पंक्ति को अद्यतन करने के? किसी और को यह परिणाम था? (डेटा को सही ढंग से अपडेट किया गया है: जिसका अर्थ है केवल 1 पंक्ति अपडेट की गई है)
दिमित्री के

14
यह थोड़ी देर हो चुकी है, लेकिन वैसे भी है: यह में कहा गया है मैनुअल कि में अपडेट ON DUPLICATE KEY UPDATEवृद्धि 2. द्वारा प्रभावित पंक्तियों यह रिपोर्ट 0 अगर कुछ वास्तव में अद्यतन किया जाता है (नियमित रूप में एक ही UPDATE)।
वटव

61
यह भी ध्यान दें कि आप वैल्यू (नाम) का उपयोग उस मूल्य के संदर्भ में कर सकते हैं जिसे आप सम्मिलित करने का प्रयास करते हैं जैसे INSERT INTO टेबल (आईडी, नाम, आयु) VALUES (1, "A", 19) ON DUPLICATE KEY , उम्र = मान (आयु)
जिज्ञासु सैम

246

बाहर की जाँच करें

http://dev.mysql.com/doc/refman/5.0/en/replace.html

REPLACE into table (id, name, age) values(1, "A", 19)

11
@Piontek क्योंकि यह छोटा और समझने में आसान है और किसी ने भी यह नहीं बताया कि "डुप्लिकेट पर सम्मिलित" क्यों बेहतर है।
Mr_Chimp

77
यह रिकॉर्ड की आईडी को बदल देता है और इस प्रकार विदेशी संदर्भों को नष्ट कर सकता है।
बोह

102
जांच REPLACE के साथ अन्य समस्या यह है कि आप है चाहिए सभी क्षेत्रों के लिए मान निर्दिष्ट ... अन्यथा क्षेत्रों खो दिया है या मूलभूत मूल्यों के साथ प्रतिस्थापित कर दिया जाएगा। REPLACE जांच अनिवार्य रूप से हटा देता है पंक्ति अगर यह मौजूद है, और नई पंक्ति सम्मिलित करता है। उदाहरण में, यदि आपने REPLACE INTO table (id, age) मान (1, 19) किया है तो नाम फ़ील्ड सुस्त हो जाएगा।
डेल

33
यह वास्तव में पूरी पंक्ति DELETE है और नए INSERT का प्रदर्शन करता है।
mjb

8
@mjb इसलिए आप हटाना विशेषाधिकार होना करने के लिए है, जो यह अगर तुम उन्हें जरूरत नहीं है के लिए नहीं सबसे अच्छा है की जरूरत है। मेरे पर्यावरण के डेटाबेस उपयोगकर्ता केवल सम्मिलित करें और अद्यतन अनुमतियाँ, तो काम नहीं करेगा REPLACE है।
ndm13

54

जब बैच का उपयोग कर सम्मिलित निम्न सिंटैक्स का उपयोग:

INSERT INTO TABLE (id, name, age) VALUES (1, "A", 19), (2, "B", 17), (3, "C", 22)
ON DUPLICATE KEY UPDATE
    name = VALUES (name),
    ...

बहुत उपयोगी है अगर आप नए मूल्य में हेरफेर करना चाहते हैं
भूख

अगर VALUES(name)नहीं काम करता है, तो आप कोशिश कर सकते हैंname = 'name_value',...;
बेटा फाम

26

इसे आज़माएं:

INSERT INTO table (id, name, age) VALUES (1, 'A', 19) ON DUPLICATE KEY UPDATE id = id + 1;

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


6
वास्तव में मुझे नए मानों को नई आईडी के साथ किसी अन्य पंक्ति में जोड़ने की आवश्यकता नहीं है, बल्कि मैं इस मूल्यों के साथ आईडी = 1 के मौजूदा मूल्यों को बदलना चाहता हूं। (जैसा कि मैं समझता हूं कि यह आईडी बढ़ाता है और डेटा जोड़ता है)
केशन

49
मुझे नहीं लगता कि वह डुप्लिकेट पर एक के बाद एक आईडी बढ़ाना चाहता है।
डॉनी

7
"ट्रांसजेंडर" वह शब्द नहीं है जिसकी आप तलाश कर रहे हैं :) दुर्भाग्य से, अब मैंने "
ट्रांसजेंडर

1
क्या आप "ट्रैवर्स" या "कवर" की तलाश कर रहे थे?
क्रिस देव

4
@mwfearnley शब्द आप कल्पना करने के लिए कोशिश कर रहे थे "अतिक्रमण" है। केवल एक साल और डेढ़ :-) लिया गया
माइकल क्रेब्स

20

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

INSERT INTO table (id,name,age) VALUES('1','Mohammad','21') ON DUPLICATE KEY UPDATE name='Mohammad',age='21'

नोट:
यहां अगर आईडी प्राथमिक कुंजी है तो डालने के बाद id='1'हर बार प्रयास के बाद id='1'नाम और उम्र का अद्यतन होगा और पिछले नाम की उम्र बदल जाएगी।


मैं का उपयोग किए बिना काम करना चाहते हैं आईडी । क्या आपने प्राथमिक कुंजी के बिना कोशिश की है?
ersks

@ersks प्रश्न देखते हैं। उपयोगकर्ता ने पूछा कि एक अनोखी कुंजी कब है
रासेल

मुझे वह मिल गया है, लेकिन मैं अपनी समस्या को हल करने की कोशिश कर रहा हूं जिसमें ये केवल मूल्यों को जानते हैं। इसलिए, ऐसी स्थिति में मैंने उपरोक्त टिप्पणी को सही समाधान की उम्मीद करते हुए लिखा था।
३३:३३ पर

15
INSERT IGNORE INTO table (id, name, age) VALUES (1, "A", 19);

INSERT INTO TABLE (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE NAME = "A", AGE = 19;

REPLACE INTO table (id, name, age) VALUES(1, "A", 19);

ये सभी समाधान आपके प्रश्न के संबंध में काम करेंगे।

यदि आप इन विवरणों के संबंध में विवरण जानना चाहते हैं तो इस लिंक पर जाएं


REPLACEलिंक किए गए दस्तावेज़ में प्रलेखित नहीं है।
रे बैक्सटर

टाइपो से भरे एसक्यूएल प्रश्न, आपके उदाहरण काम नहीं करेंगे। यह INSERT INTO TABLE (इनटू टेबल नहीं है) और DUPLICATE KEY UPDATE पर है (DUPLICATE UPDATE SET पर नहीं)। यकीन नहीं हो रहा है कि यह किसका उत्थान है
रॉबर्ट सिनक्लेयर

1
टाइपोस त्रुटि के लिए क्षमा करें। मुझे सही करने के लिए धन्यवाद
दिलराज सिंह

11

SQLite का उपयोग करते समय:

REPLACE into table (id, name, age) values(1, "A", 19)

बशर्ते कि idप्राथमिक कुंजी है। या फिर यह सिर्फ एक और पंक्ति सम्मिलित करता है। देखें सम्मिलित करें (SQLite)।


क्या replace intoकरता है "मौजूदा में डालें या अपडेट करें"। @ ओवल
डॉनसॉन्ग

+1 (1 का 1) मुझे अपनी स्थिति के लिए काम करने के लिए यह मिला - मुझे एक मौजूदा पंक्ति को एक अनूठी कुंजी के साथ बदलने की आवश्यकता है या यदि नहीं है तो पंक्ति जोड़ें। सबसे सरल उपाय यहाँ।

(2 का 3) मेरी क्वेरी:CREATE TRIGGER worklog_update AFTER INSERT ON worklog FOR EACH ROW REPLACE INTO support_time_monthly_hours ( ProjectID, monthTotalTime, Year, Month ) SELECT jiraissue.PROJECT, SUM(worklog.timeworked), YEAR(CURRENT_DATE()), MONTH(CURRENT_DATE()) FROM worklog, jiraissue WHERE worklog.issueid = jiraissue.ID AND jiraissue.PROJECT = (SELECT PROJECT FROM jiraissue WHERE NEW.issueid = jiraissue.ID ) AND worklog.startdate BETWEEN DATE_FORMAT(NOW() ,'%Y-%m-01 00:00:00') AND NOW();
therobyouknow

(3 का 3) संबंधित प्रश्न / उत्तर stackoverflow.com/questions/41767517/…
therobyouknow

2
Mysql में इसके साथ समस्या यह है कि प्रतिस्थापित न किए जाने की स्थिति में अन्य मान हटा दिए जाएंगे। हालाँकि @
फैबियानो

11

सिर्फ इसलिए कि मैं यहां इस समाधान की तलाश कर रहा था, लेकिन एक अन्य पहचान-योग्य तालिका से अद्यतन करने के लिए (मेरे मामले में वेबसाइट DB के रहने के लिए DB का परीक्षण करें):

INSERT  live-db.table1
SELECT  *
FROM    test-db.table1 t
ON DUPLICATE KEY UPDATE
        ColToUpdate1 = t.ColToUpdate1,
        ColToUpdate2 = t.ColToUpdate2,
        ...

जैसा कि कहीं और उल्लेख किया गया है, केवल उन कॉलमों को जिन्हें आप अपडेट करना चाहते हैं, को बाद में शामिल करने की आवश्यकता है ON DUPLICATE KEY UPDATE

में स्तंभों की सूची की आवश्यकता नहीं है INSERTया SELECTहै, हालांकि मैं मानता हूँ कि यह शायद बेहतर व्यवहार है।


4

उस स्थिति में जब आप किसी non-primaryफ़ील्ड को मापदंड / शर्त के रूप में बनाना चाहते थे ON DUPLICATE, आप UNIQUE INDEXट्रिगर को ट्रिगर करने के लिए उस तालिका पर एक कुंजी बना सकते हैं DUPLICATE

ALTER TABLE `table` ADD UNIQUE `unique_index`(`name`);

और यदि आप तालिका पर अद्वितीय बनाने के लिए दो क्षेत्रों को संयोजित करना चाहते हैं, तो आप अंतिम पैरामीटर पर अधिक जोड़कर इसे प्राप्त कर सकते हैं।

ALTER TABLE `table` ADD UNIQUE `unique_index`(`name`, `age`);

ध्यान दें, बस उन सभी डेटा को हटाना सुनिश्चित करें जिनके पास समान है nameऔर ageअन्य पंक्तियों में मान है।

DELETE table FROM table AS a, table AS b WHERE a.id < b.id 
AND a.name <=> b.name AND a.age <=> b.age;

उसके बाद, उसे ON DUPLICATEघटना को ट्रिगर करना चाहिए ।

INSERT INTO table (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE    
name = VALUES(name), age = VALUES(age)

2

मेरे मामले में मैंने प्रश्नों के नीचे बनाया है, लेकिन पहली क्वेरी में यदि id1 पहले से मौजूद है और उम्र पहले से ही है, तो उसके बाद यदि आप ageमूल्य के बिना पहली क्वेरी बनाते हैं तो ageकोई नहीं होगा

REPLACE into table SET `id` = 1, `name` = 'A', `age` = 19

उपरोक्त समस्या से बचने के लिए नीचे की तरह क्वेरी बनाएं

INSERT INTO table SET `id` = '1', `name` = 'A', `age` = 19 ON DUPLICATE KEY UPDATE `id` = "1", `name` = "A",`age` = 19

यह आपकी मदद करेगा ...


2
क्या किसी को पता है कि हमें दो बार मान क्यों देना चाहिए? MySQL हमें सभी असाइनमेंट स्टेटमेंट को डुप्लिकेट किए बिना DUPLICATE KEY UPDATE पर क्वेरी को समाप्त करने की अनुमति क्यों नहीं देता है? कुछ डेटाबेस टेबल में कई कॉलम होते हैं, और यह बेमानी / गंभीर लगता है। मैं समझता हूं कि हमारे पास वैकल्पिक असाइनमेंट का विकल्प क्यों है, लेकिन उनके पास भी इसे छोड़ने का विकल्प क्यों नहीं है? अगर किसी को पता है तो बस उत्सुक।
ब्लू वाटर

2

यदि आप पुराना क्षेत्र रखना चाहते हैं (उदाहरण के लिए: नाम)। क्वेरी होगी:

INSERT INTO table (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE    
name=name, age=19;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.