2013-02-12 13 views
5

मैं AUTO_INCREMENT का उपयोग कर रहा हूं और मैं डाली गई पंक्ति की उस आईडी को प्राप्त करना चाहता हूं ताकि मैं ID का उपयोग करके 2 टेबल के बीच सामान्य फ़ील्ड के रूप में एक और तालिका अपडेट कर सकूं।AUTO_INCREMENT और LAST_INSERT_ID

मुझे समझ में आया कि LAST_INSERT_ID अंतिम ID मिलेगा। हालांकि, मेरी चिंता यह है कि, डेटाबेस को कई उपयोगकर्ताओं द्वारा एक ही समय में एक्सेस किया जाता है। इसलिए, एक और प्रक्रिया तालिका में पहुंचा जा सकता है और एक ही समय में एक नई पंक्ति भी डाली जा सकती है।

क्या LAST_INSERT_ID उपयोग किए गए कनेक्शन के बावजूद केवल अंतिम आईडी लौटाता है, या केवल उस कनेक्शन के लिए अंतिम आईडी लौटाता है जिसका मैं उपयोग कर रहा हूं?

नोटिस, मैं tomcat सर्वर में कनेक्शन पूल का उपयोग कर mySQL डेटाबेस तक पहुंच रहा हूं।

संपादित करें: संक्षेप में, मुझे टेबल बी में पंक्ति को सम्मिलित करने की आवश्यकता के बजाय तालिका वृद्धि में एक पंक्ति डालने की आवश्यकता है, जिसे ऑटो वृद्धि मूल्य का उपयोग करके तालिका ए से लिंक करने की आवश्यकता है।

+0

कृपया अधिक जानकारी प्रदान करें तो यह उत्तर देने में सहायक होगा। लेकिन फिर भी आप KeyHolder का उपयोग कर सकते हैं। – psi

उत्तर

10
SELECT max(employeeid) FROM Employee; 

ऊपर क्वेरी कर्मचारी तालिका में आखिरी डाला रिकॉर्ड की EmployeeID का मान देता है क्योंकि EmployeeID एक ऑटो वेतन वृद्धि स्तंभ है। यह ठीक लगता है, लेकिन मान लीजिए कि दो धागे एक साथ सम्मिलित ऑपरेशन निष्पादित कर रहे हैं, एक मौका है कि आपको अंतिम सम्मिलित रिकॉर्ड की गलत आईडी मिलती है! चिंता न करें, MySQL एक फ़ंक्शन प्रदान करता है जो अंतिम सम्मिलित रिकॉर्ड के ऑटो वृद्धि कॉलम का मान देता है।

SELECT LAST_INSERT_ID(); 

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

+0

धन्यवाद .. क्या मुझे लेनदेन का उपयोग करने की आवश्यकता है - setAutocommit (false) - LAST_INSERT_ID को काम करने के लिए। या जब तक मैं एक ही कनेक्शन का उपयोग कर रहा हूं, तब तक इसे ठीक काम करना चाहिए। – user836026

+0

@ user836026 सुरक्षित होने के लिए, आप INSERT के बाद इस एसईटी को कॉल कर सकते हैं चाहे किसी लेनदेन में हों या नहीं, फिर लेनदेन का उल्लेख MAX मामले में अधिक रिलीज़ हो गया है जो किसी भी परिणाम में वांछित परिणाम उत्पन्न करने की अधिक संभावना है लेनदेन, फिर भी, LAST_INSERT_ID पसंदीदा है! – MediaVince

1

LAST_INSERT_ID वर्तमान सत्र के लिए अंतिम डालने आईडी लौटाएं। जब तक आप अपने वर्तमान कनेक्शन के साथ एक से अधिक प्रविष्टियों को सम्मिलित नहीं करते हैं, यह मान्य है।

इसके अलावा यहां जानकारी: https://dba.stackexchange.com/questions/21181/is-mysqls-last-insert-id-function-guaranteed-to-be-correct

(i mysql.com से लिंक होगा, लेकिन यह मेरे लिए नीचे वर्तमान में)

+0

'LAST_INSERT_ID' एक वैश्विक कॉल है? क्या किसी विशिष्ट तालिका के लिए 'LAST_INSERT_ID' नहीं है? – user961627

+2

@ user961627 किसी को हमेशा यह पता होना चाहिए कि वर्तमान सत्र में आखिरी बार कौन सी तालिका डाली गई है। – scones

2

LAST_INSERT_ID()संदर्भ में काम करते हैं, यह लेन-देन में या उपयोगकर्ता अंदर होना चाहिए परिभाषित संग्रहित प्रक्रियाओं या उपयोगकर्ता परिभाषित कार्यों।

+0

धन्यवाद ... जावा में, अगर मैंने गलत प्रतिबद्धता को गलत पर सेट किया, और बदलाव किया, तो उसे नौकरी करना चाहिए? – user836026

2

कनेक्शन विशिष्ट है। यह सच है, लेकिन अगर आप कनेक्शन पूलिंग का उपयोग करते हैं तो आपको सावधान रहना चाहिए। जब आप लूप में लगातार INSERT IGNORE कथन करते हैं तो यह समस्याग्रस्त हो सकती है और पूल आपको प्रत्येक पुनरावृत्ति पर एक ही कनेक्शन देता है।

उदाहरण के लिए; मान लें कि आप नीचे से प्रत्येक के लिए एक ही (खुला) कनेक्शन प्राप्त:

INSERT IGNORE ... some-new-id >>>LAST_INSERT_ID रिटर्न 100

INSERT IGNORE ... some-existing-id >>>LAST_INSERT_ID अभी भी रिटर्न 100

(पिछले ऑपरेशन के परिणाम) यह जांचना हमेशा अच्छा होता है कि INSERT ऑपरेशन ने वास्तव में LAST_INSERT_ID पर कॉल करने से पहले किसी भी पंक्ति को डाला है या नहीं।

संबंधित मुद्दे