2009-01-02 3 views
18

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

MySqlCommand comm = connect.CreateCommand(); 
comm.CommandText = insertInvoice; 
comm.CommandText += "\'" + invoiceDate.ToString("yyyy:MM:dd hh:mm:ss") + "\', " + bookFee + ", " + adminFee + ", " + totalFee + ", " + customerID + ")"; 
int id = Convert.ToInt32(comm.ExecuteScalar()); 

मेरी समझ के अनुसार, इस आईडी लौटना चाहिए कॉलम, लेकिन यह हर बार 0 देता है। कोई विचार?

संपादित करें:

जब मैं चलाएँ:

"INSERT INTO INVOICE (INVOICE_DATE, BOOK_FEE, ADMIN_FEE, TOTAL_FEE, CUSTOMER_ID) VALUES ('2009:01:01 10:21:12', 50, 7, 57, 2134);last_insert_id();" 

मैं:

{"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'last_insert_id()' at line 1"} 
+0

1. आप अंतिम CommandText निष्पादित हो जाता है कि पोस्ट कर सकते हैं? 2।क्या रिकॉर्ड वास्तव में डाले जा रहे हैं? –

+0

मैंने क्वेरी, त्रुटि, और हाँ पोस्ट की, पंक्तियां डाली जा रही हैं। – Elie

+0

ठीक है, "आखिरी_इनर्ट_आईडी() चुनें;" अतं मै? –

उत्तर

15

[संपादित करें: जोड़ा संदर्भ last_insert_id करने से पहले "का चयन करें"()]

आपके अंदरूनी के बाद "select last_insert_id();" चलाने के बारे में क्या टी?

MySqlCommand comm = connect.CreateCommand(); 
comm.CommandText = insertInvoice; 
comm.CommandText += "\'" + invoiceDate.ToString("yyyy:MM:dd hh:mm:ss") + "\', " 
    + bookFee + ", " + adminFee + ", " + totalFee + ", " + customerID + ");"; 
    + "select last_insert_id();" 

int id = Convert.ToInt32(comm.ExecuteScalar()); 

संपादित करें: duffymo उल्लेख रूप में, आप वास्तव में अच्छी तरह पैरामिट्रीकृत प्रश्नों like this का उपयोग कर दिखाए जाएँगे।


संपादित करें: जब तक आप एक पैरामिट्रीकृत संस्करण में परिवर्तन, आप String.Format के साथ शांति मिल सकती है:

comm.CommandText = string.Format("{0} '{1}', {2}, {3}, {4}, {5}); select last_insert_id();", 
    insertInvoice, invoiceDate.ToString(...), bookFee, adminFee, totalFee, customerID); 
+0

मैं इसके बिना क्वेरी का प्रयास करूंगा। क्या रिकॉर्ड वास्तव में डाले जा रहे हैं? –

+0

हां, रिकॉर्ड डाले जा रहे हैं। – Elie

+0

ठीक है, "आखिरी_इनर्ट_आईडी() चुनें;" अतं मै? –

0

यह मुझे परेशान किसी एक तिथि ले रहे हैं और एक में भंडारण को देखने के लिए एक स्ट्रिंग के रूप में डेटाबेस। कॉलम प्रकार वास्तविकता को प्रतिबिंबित क्यों नहीं करता है?

मैं स्ट्रिंग concatenation का उपयोग कर एक एसक्यूएल क्वेरी बनाने के लिए भी हैरान हूँ। मैं जावा डेवलपर हूं, और मुझे सी # बिल्कुल पता नहीं है, लेकिन मुझे आश्चर्य होगा कि पुस्तकालय में कहीं java.sql.PreparedStatement की लाइनों के साथ बाध्यकारी तंत्र नहीं था? एसक्यूएल इंजेक्शन हमलों के खिलाफ सुरक्षा के लिए सिफारिश की जाती है। एक अन्य लाभ संभव प्रदर्शन लाभ है, क्योंकि एसक्यूएल को पार्स किया जा सकता है, सत्यापित किया जा सकता है, एक बार कैश किया जा सकता है, और पुन: उपयोग किया जा सकता है।

+0

ओपी डीबी में दिनांक कॉलम का उपयोग कर सकता है-- हम उस भाग को नहीं देख सकते हैं। मैं मानता हूं कि आपको पैरामीटरयुक्त प्रश्नों का उपयोग करना चाहिए, हालांकि। शुक्र है कि ऐसा लगता है कि आप कोई भी टेक्स्ट डालने में इतनी सख्ती से बोल रहे हैं कि आप शायद इस पर सुरक्षित हैं (हालांकि प्रदर्शन बेहतर हो सकता है)। –

+0

कॉलम वास्तव में एक तारीख है, लेकिन यदि मैं सीधे डेट ऑब्जेक्ट डालने का प्रयास करता हूं, तो मुझे तारीख को 0s के सेट पर रीसेट करने में समस्याएं थीं। मैं सी # के लिए नया हूं, लेकिन मैं आपसे सहमत हूं, संभवतः सी # के लिए प्रीपेर्डस्टेटमेंट का एक संस्करण है, और मैं इसे बदल दूंगा। – Elie

+0

यदि कॉलम वास्तव में एक तिथि है, तो कोड में किए गए स्वरूपण पैटर्न के साथ "toString" कॉल क्या है? – duffymo

0

असल में, ExecuteScalar विधि डेटासेट की पहली पंक्ति के पहले कॉलम को वापस लौटाता है। आपके मामले में, आप केवल एक सम्मिलित कर रहे हैं, आप वास्तव में किसी भी डेटा से पूछताछ नहीं कर रहे हैं। आपके द्वारा डालने के बाद आपको scope_identity() से पूछताछ करने की आवश्यकता है (यह SQL सर्वर के लिए वाक्यविन्यास है) और फिर आपका जवाब होगा। यहाँ देखें:

Linkage

संपादित करें: ने माइकल को हरेन ने कहा, आप अपने टैग में उल्लेख किया है आप उपयोग कर रहे MySQL,) last_insert_id का उपयोग करें (; scope_identity() के बजाय;

+0

टैग के अनुसार, मेरे उत्तर में MySQL के लिए scope_identity संस्करण शामिल है। –

+0

ओह, मेरी गलती, मैंने MySQL टैग नहीं देखा। मैं अपनी पोस्ट संपादित करूंगा। – BFree

+0

कोई समस्या नहीं - मुझे उन्हें अक्सर याद आती है। –

32
MySqlCommand comm = connect.CreateCommand(); 
comm.CommandText = insertStatement; // Set the insert statement 
comm.ExecuteNonQuery();    // Execute the command 
long id = comm.LastInsertedId;  // Get the ID of the inserted item 
+4

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

+0

बहुत बढ़िया .. मैंने यह भी नहीं सोचा था कि माइस्क्लडाटा इसे प्रदान करेगा। महान। – Sami

+1

यह हो सकता है कि cmd.LastInsertedId थ्रेड सुरक्षित नहीं है ..... लेकिन मुझे लगता है कि आईडी को एक ही ExecuteNonQuery कॉल में पुनर्प्राप्त किया गया है, दो क्वेरी कॉल नहीं है क्योंकि आपको SELECT LAST_INSERT_ID() के साथ करना है। क्या किसी अन्य थ्रेड से दूसरी कॉल के लिए यह वास्तव में संभव है कि डाली गई पंक्ति के बीच में और आईडी को पुनर्प्राप्त किया जा सके। मुझे लगता है कि सर्वर यह काम करता है और इसलिए तुरंत करता है। क्या LAST_INSERT_ID धागा सुरक्षित है? – MrCalvin