क्या MySql का LAST_INSERT_ID () फ़ंक्शन सही होने की गारंटी है?


36

जब मैं INSERTकिसी तालिका के लिए एक एकल पंक्ति करता AUTO_INCREMENTहूं जिसमें एक कॉलम होता है तो मैं उस पंक्ति के लिए संग्रहीत LAST_INSERT_ID()नए AUTO_INCREMENT'एड वैल्यू' को वापस करने के लिए फ़ंक्शन का उपयोग करना चाहता हूं ।

कई Microsoft SQL सर्वर devs और मानते हैं कि कोई शक नहीं SQL सर्वर ( SCOPE_IDENTITYऔर @@IDENTITY) में इसकी कार्यक्षमता के बिना समान कार्यक्षमता के बारे में पता नहीं है

मुझे पता है कि MySQL डॉक्स स्टेट:

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

(स्रोत)

और यहां तक ​​कि कहने के लिए यहां तक ​​जाएं:

कई क्लाइंट्स का एक साथ उपयोग LAST_INSERT_ID()और AUTO_INCREMENTकॉलम पूरी तरह से मान्य है।

(स्रोत)

क्या कोई ज्ञात जोखिम या परिदृश्य LAST_INSERT_ID()हैं जो सही मूल्य वापस नहीं कर सकते हैं ?

मैं CentOS 5.5 x64 पर MySQL 5.5 और Fedora 16 x64 और InnoDB इंजन का उपयोग कर रहा हूं।

जवाबों:


35

उपयोग करते समय एक दंपती चेतावनी देना चाहूंगा LAST_INSERT_ID:

  1. मुझे पता है कि आपने एकल-पंक्ति आवेषण का उल्लेख किया है। लेकिन कई-पंक्ति आवेषण करते समय, सम्मिलित LAST_INSERT_ID()पहली पंक्ति का मान लौटाएगा (अंतिम नहीं)।

  2. यदि सम्मिलित विफल हुआ, LAST_INSERT_ID()तो अपरिभाषित होगा। लेन-देन के स्वत: रोलबैक (त्रुटियों के कारण) के लिए भी यही सच है।

  3. यदि आप एक लेनदेन में सम्मिलित करते हैं जो सफल होता है, और आप अभी भी एक जारी करते हैं ROLLBACK, LAST_INSERT_ID()तो इसे छोड़ दिया जाएगा क्योंकि यह रोलबैक से पहले था।

  4. उपयोग करते समय और स्टेटमेंट-आधारित प्रतिकृति में कुछ युगल होते हैं । ट्रिगर या फंक्शन में इस्तेमाल होने पर सबसे पहले। दूसरा कम-सामान्य परिदृश्य होना जहाँ आपका ऑटो_इन्क्रीमेंट कॉलम एक कम्पोज़िट प्राथमिक कुंजी का हिस्सा है और कुंजी में पहला कॉलम नहीं है।AUTO_INCREMENTLAST_INSERT_ID


7

DTest द्वारा दिए गए उत्तर में बिंदु संख्या 2 पर और विस्तार करने के लिए:

MySQL के संस्करण है कि मैं का इस्तेमाल किया है, यह एक अच्छा विचार करने के लिए है स्पष्ट रूप LAST_INSERT_ID का मूल्य कोड के प्रत्येक ब्लॉक में जहां आपके पास डालने प्रदर्शन करने की योजना से पहले रीसेट।

यह इस तरह किया जा सकता है:

-- initialize the LAST_INSERT_ID to some flag value:
SELECT LAST_INSERT_ID( some_flag_init_value_of_your_choice );
-- perform the insert  
INSERT INTO ttt (ccc) VALUES (vvv);
-- retrieve the id of the inserted row:  
SELECT LAST_INSERT_ID();

उपरोक्त कथनों की श्रृंखला निष्पादित होने के बाद, आपको पता चलेगा कि क्या LAST_INSERT_ID जाँच के अंत में "some_flag_init_value_of_your_choice" पर सेट है या नहीं यह जाँचने से पता चलता है कि क्या डालने का कोई प्रभाव था।

अन्यथा, आप निम्नलिखित समस्याग्रस्त स्थिति को हवा दे सकते हैं:

INSERT INTO ttt ( ccc ) VALUES ( 'a' );    -- assume this succeeds.
SELECT LAST_INSERT_ID();                   -- this will return the unique id of the new row with value 'a'.
INSERT INTO ttt ( ccc ) VALUES ( 'b' );    -- assume this FAILS.
SELECT LAST_INSERT_ID();                   -- this will STILL RETURN the unique id of the row with 'a'.

क्योंकि दूसरा इंसर्ट विफल हो गया है, आप उम्मीद कर रहे होंगे कि LAST_INSERT_ID को दूसरा कॉल या तो NULL लौटा देगा या वह खाली परिणाम सेट (शून्य पंक्तियाँ) का उत्पादन करेगा। यह तथ्य कि यह अभी भी एक वैध पूर्णांक पहचानकर्ता लौटाता है, आपको यह सोचकर गुमराह कर सकता है कि जब यह नहीं था, तो दूसरा सम्मिलित करें।

जब आपको लगता है कि LAST_INSERT_ID अंतिम सफल यूनिक आईडी को संरक्षित करना और दोहराना जारी रखेगा, तो भी ईवीएन वीयर को प्राप्त होता है, भले ही बाद के असफल इंसर्ट स्टेटमेंट टेबल की तुलना में अलग-अलग तालिकाओं को लक्षित कर रहे हों, जो अंतिम सफल यूनिक आईडी का उत्पादन करती हैं। दूसरे शब्दों में, आप तालिका TA में सम्मिलित करते हैं और 5 की एक आईडी प्राप्त करते हैं, फिर आप टीबी में सम्मिलित करते हैं (लेकिन यह विफल रहता है), लेकिन आप अभी भी एक 5 देखते हैं। उसके आधार पर, आपको लगता है कि आपने TA में एक नई पंक्ति बनाई है 5 की आईडी के साथ और 5 की आईडी के साथ टीबी में एक नई पंक्ति, जबकि वास्तव में आईडी 5 के साथ टीबी में कोई भी पंक्ति मौजूद नहीं है, या ऐसी कोई पंक्ति मौजूद नहीं है, लेकिन इसका वास्तव में आपके किसी भी कोड से कोई लेना-देना नहीं है भाग गया।


2
पहली जगह में last_insert_id()अगर आप एक क्वेरी सफल रहा था तो न्यायाधीश के अस्तित्व का उपयोग नहीं करना चाहिए था। यह आखिरकार ईद है, जब आपको पहले से ही पता चल गया था कि मूल्यों की जरूरत है, तो आपको सफलता मिली।
पचेरियर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.