2009-10-27 17 views
31

मेरे पास एक प्राथमिक संख्या के रूप में ऑटो-नंबर वाला एक जेईटी टेबल है, और मैं जानना चाहता हूं कि मैं पंक्ति को डालने के बाद इस नंबर को कैसे पुनर्प्राप्त कर सकता हूं। मैंने उच्चतम मूल्य के साथ पंक्ति को पुनर्प्राप्त करने के लिए MAX() का उपयोग करने का विचार किया है, लेकिन मुझे यकीन नहीं है कि यह कितना विश्वसनीय होगा। कुछ नमूना कोड:अंतिम सम्मिलित पंक्ति का ऑटोनंबर मान - एमएस एक्सेस/वीबीए

Dim query As String 
Dim newRow As Integer 
query = "INSERT INTO InvoiceNumbers (date) VALUES (" & NOW() & ");" 
newRow = CurrentDb.Execute(query) 

अब मुझे पता है कि यह, काम नहीं है, क्योंकि Execute() प्राथमिक कुंजी का मूल्य वापस नहीं होगा, लेकिन यह मूल रूप से मैं देख रहा हूँ कोड की तरह है। मुझे दूसरी पंक्ति में कई पंक्तियों को अपडेट करने के लिए नई पंक्ति की प्राथमिक कुंजी का उपयोग करने की आवश्यकता होगी।

ऐसा करने का सबसे सरल/सबसे पठनीय तरीका क्या होगा?

उत्तर

32

डीएओ

RS.Move 0, RS.LastModified 
lngID = RS!AutoNumberFieldName 

का उपयोग करते हैं एडीओ

cn.Execute "INSERT INTO TheTable.....", , adCmdText + adExecuteNoRecords 
Set rs = cn.Execute("SELECT @@Identity", , adCmdText) 
Debug.Print rs.Fields(0).Value 

का उपयोग करते हैं एक वैध ADO कनेक्शन किया जा रहा cn, @@Identity पिछले Identity (Autonumber) इस संबंध पर डाला वापस आ जाएगी।

ध्यान दें कि @@Identity परेशानी हो सकती है क्योंकि पिछले उत्पन्न मूल्य एक आप में रुचि रखते हैं नहीं हो सकता। एक्सेस डेटाबेस इंजन के लिए, एक VIEW कि दो तालिकाओं मिलती है, जो दोनों के IDENTITY संपत्ति है आप INSERT INTO पर विचार करें, और VIEW। SQL सर्वर के लिए, विचार करें कि ट्रिगर्स हैं जो बदले में रिकॉर्ड को किसी अन्य तालिका में सम्मिलित करते हैं जिसमें IDENTITY संपत्ति भी होती है।

बीटीडब्ल्यू डीएमएक्स काम नहीं करेगा जैसे कि कोई रिकॉर्ड रिकॉर्ड करने के बाद कोई और रिकॉर्ड रिकॉर्ड करता है लेकिन आपके डीमैक्स फ़ंक्शन को समाप्त करने से पहले आपको उनका रिकॉर्ड प्राप्त होगा।

+14

डीएओ का चयन कर सकते हैं @@ पहचान भी - आप ADO जरूरत नहीं है। मैं यह हर समय करता हूं: lngID = db.OpenRecordset ("SELECT @@ पहचान") (0), जहां "डीबी" एक ही डेटाबेस वैरिएबल है जिसका उपयोग सम्मिलित करने के लिए किया गया था। मैं अब रिकॉर्डसेट खोलता हूं और इसके लिए जोड़ता हूं। –

41

आपके उदाहरण में, क्योंकि आप अपने INSERT को निष्पादित करने के लिए CurrentDB का उपयोग करते हैं, आपने इसे अपने लिए कठिन बना दिया है। इसके बजाय, यह काम करेगा:

Dim query As String 
    Dim newRow As Long ' note change of data type 
    Dim db As DAO.Database 

    query = "INSERT INTO InvoiceNumbers (date) VALUES (" & NOW() & ");" 
    Set db = CurrentDB 
    db.Execute(query) 
    newRow = db.OpenRecordset("SELECT @@IDENTITY")(0) 
    Set db = Nothing 

मैं ऐसा करने के लिए इस्तेमाल एक AddOnly recordset खोलने और वहाँ से आईडी उठा द्वारा कहते हैं, लेकिन यह एक बहुत अधिक कुशल है। और, ध्यान दें, टोनी, कि उसे एडीओ की आवश्यकता नहीं है।

+2

और यह तब भी काम करता है जब रिकॉर्डसेट एक SQL सर्वर से जुड़ी तालिका है! आश्चर्यजनक ! –

+0

आप निष्पादन के विकल्प के रूप में dbFailOnError भी जोड़ सकते हैं। अन्यथा पहुंच विफल होने पर कुछ भी नहीं कहेंगे। ----- डीबी।क्वेरी निष्पादित करें, dbFailOnError – JustJohn

+0

@iDevlop SQL सर्वर [SELECT @@ पहचान 'वाक्यविन्यास का समर्थन करता है] (https://msdn.microsoft.com/en-us/library/ms187342.aspx)। यह देखना दिलचस्प होगा कि एक्सेल या अन्य आरडीबीएमएस जैसे ओरेकल या माईएसक्यूएल जैसे अन्य लिंक किए गए टेबल प्रकारों में क्या होता है। –

3

यह आपके लिए मेरे कोड से एक अनुकूलन है। मैं developpez.com से प्रेरित था (इसके लिए पृष्ठ में देखें: "डालें इनरर डेस डोनियस, vaut-il mieux passer par un recordSet ou par une requête de type INSERT?")। वे समझाते हैं (थोड़ा फ्रांसीसी के साथ)। इस तरह एक ऊपरी से बहुत तेज है। उदाहरण में, इस तरह 37 गुना तेजी से था। कोशिश करो।

Const tableName As String = "InvoiceNumbers" 
Const columnIdName As String = "??" 
Const columnDateName As String = "date" 

Dim rsTable As DAO.recordSet 
Dim recordId as long 

Set rsTable = CurrentDb.OpenRecordset(tableName) 
Call rsTable .AddNew 
recordId = CLng(rsTable (columnIdName)) ' Save your Id in a variable 
rsTable (columnDateName) = Now()  ' Store your data 
rsTable .Update 

recordSet.Close 

LeCygne

+3

क्या आप कृपया पहचान सकते हैं कि यह किस विशेष उदाहरण से "37 गुना तेज" है? –

1
Private Function addInsert(Media As String, pagesOut As Integer) As Long 


    Set rst = db.OpenRecordset("tblenccomponent") 
    With rst 
     .AddNew 
     !LeafletCode = LeafletCode 
     !LeafletName = LeafletName 
     !UNCPath = "somePath\" + LeafletCode + ".xml" 
     !Media = Media 
     !CustomerID = cboCustomerID.Column(0) 
     !PagesIn = PagesIn 
     !pagesOut = pagesOut 
     addInsert = CLng(rst!enclosureID) 'ID is passed back to calling routine 
     .Update 
    End With 
    rst.Close 

End Function 
+1

मैं यह देखने में असफल रहा कि यह मूल प्रश्न का उत्तर कैसे देता है। यह देखने के लिए संदर्भ जोड़ें कि यह कैसे फिट बैठता है? – GPI

+1

यह उत्तर अस्पष्ट है। कृपया स्पष्टीकरण जोड़ें। हम सभी को वीबीए के बारे में ** सबकुछ ** नहीं पता है। – MJH

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