2012-09-17 15 views
6

मैं एसक्यूएल सर्वर, यानी, डीएओ + लिंक्ड टेबल पर क्लासिक एक्सेस एप्लिकेशन माइग्रेट कर रहा हूं।डीएओ और एसक्यूएल सर्वर से जुड़े लेनदेन

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

एक एमडीबी फाइलों में लिंक्ड टेबल का उपयोग कर मानक एमएस-एक्सेस व्यवहार अलग है। समय पर केवल एक ही लेनदेन है। प्रत्येक डीबी परिवर्तन किसी भी कोड द्वारा दिखाई देता है जो प्रतिबद्धता निष्पादित करने से पहले उसी DAO.Workspace में चलता है।

नियम बदल दिए गए हैं और क्लाइंट साइड लेनदेन का उपयोग कर मौजूदा डीएओ कोड विफल हो जाएगा।

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

नमूना प्रदान किए गए नमूने को निष्पादित करते हुए, एसक्यूएल प्रोफाइलर आपको दिखाएगा कि अलग-अलग लेन-देन आईडी के साथ अलग-अलग ऑपरेशन किए जाते हैं।

मैंने एडीओ का उपयोग करके इसका परीक्षण किया है और सबकुछ अच्छी तरह से काम करता है। लेकिन हजारों कोड लाइनें हैं।

क्या एडीओ का उपयोग कर कोड लिखने के अलावा कोई समाधान है?

क्या मैं मानक एक्सेस व्यवहार को संशोधित कर सकता हूं? (अनचाहे अलगाव स्तर पढ़ें, नए कनेक्शन खोलने के लिए निर्देश, ...)

नीचे कोड समस्या को पुन: उत्पन्न करता है। यह बहुत सरल है:

1.- ओपन पर एक recordset मौजूदा रिकॉर्ड
2.- नया रिकार्ड जोड़ें
3.- तो मैं में dbOpenDynaset का उपयोग हाल ही में जोड़ा रिकॉर्ड

पढ़ने की कोशिश करें (1), मैं (3) में नया रिकॉर्ड नहीं दिखाई देगा।

मैं एसीसी -2010, .accdb प्रारूप फ़ाइलें और Sql सर्वर 2008 R2

धन्यवाद उपयोग कर रहा हूँ।

Private Sub test0() 
    Dim bResult As Boolean 

    Dim bUseTrans As Boolean 'New record added in transaction 

    Dim rsExist As DAO.Recordset2 'Dummy recordset 
    Dim tRecordsetExist As DAO.RecordsetTypeEnum 'Dummy recordset type: 
                ' with dbOpenDynaset fail. 
                ' Any other works fine 

    Dim rs2Add As DAO.Recordset 

    Dim rs2Read As DAO.Recordset 'Used to read recently added record 
    Dim tRecordset2Read As DAO.RecordsetTypeEnum 'Recordset type used to read new record. Doesn't affect 

    Dim bTranInitiated As Boolean 'Track if we are in transaction 

    Dim lngExistingNumber As Long 
    Dim lngNewNumber As Long 
    Dim lngNewID As Long 
    Dim strSQL As String 
On Error GoTo HandleErr 

    'Invoices table definition in SS. Table is linked as [dbo_Invoices]: 
    ' CREATE TABLE [dbo].[Invoices](
    '  [IdInvoice] [int] IDENTITY(1,1) NOT NULL, 
    '  [InvoiceNumber] [int] NOT NULL, 
    '  [InvoiceDescription] [varchar](50) NOT NULL, 
    ' CONSTRAINT [PK_Invoices] PRIMARY KEY CLUSTERED 
    ' (
    '  [IdInvoice] Asc 
    ' )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
    ' ) ON [PRIMARY] 

    Set wks = DBEngine.Workspaces(0) 
    Set dbs = wks.Databases(0) 

    bUseTrans = True 'Without transaction everything works well 

    tRecordsetExist = dbOpenDynaset 'Dummy recordset type: 
            ' dbOpenDynaset makes fail. 
            ' Any other works fine 

    tRecordset2Read = dbOpenForwardOnly 'Does not affect 

    lngExistingNumber = 12001 
    lngNewNumber = -lngExistingNumber 

    'Clean previous runs of the test and make sure that referenced invoice exists. 
    dbs.Execute "Delete from dbo_Invoices Where InvoiceNumber = " & lngNewNumber, dbFailOnError Or dbSeeChanges 
    On Error Resume Next 
    strSQL = "Insert Into dbo_Invoices (InvoiceNumber, InvoiceDescription) " & _ 
      " Values (" & lngExistingNumber & ", 'Original invoice')" 
    dbs.Execute strSQL, dbFailOnError Or dbSeeChanges 
    On Error GoTo HandleErr 

    If bUseTrans Then 
     wks.BeginTrans 
     bTranInitiated = True 
    End If 

    strSQL = "Select IdInvoice, InvoiceNumber from dbo_Invoices " & _ 
      " Where InvoiceNumber = " & lngExistingNumber 
    If tRecordsetExist = dbOpenDynaset Then 
     Set rsExist = dbs.OpenRecordset(strSQL, dbOpenDynaset, dbSeeChanges) 
    Else 
     Set rsExist = dbs.OpenRecordset(strSQL, tRecordsetExist) 
    End If 
    If rsExist.BOF And rsExist.EOF Then 
     Err.Raise vbObjectError, , "Original invoice " & lngExistingNumber & " not found" 
    End If 

    Set rs2Add = dbs.OpenRecordset("Select * from dbo_Invoices", dbOpenDynaset, dbAppendOnly Or dbSeeChanges) 

    rs2Add.AddNew 
    rs2Add!InvoiceNumber = lngNewNumber 
    rs2Add!InvoiceDescription = "Invoice anulation, ref " & lngExistingNumber 
    rs2Add.Update 

    'After executing .Update rs2Add goes to .EOF. This action reposition the recordset on the new record 
    rs2Add.Move 0, rs2Add.LastModified 

    lngNewID = rs2Add!IdInvoice 
    Debug.Print "New record added: IdInvoice = " & rs2Add!IdInvoice & ", InvoiceNumber = " & rs2Add!InvoiceNumber 

    'Try to read the new record 
    strSQL = "Select * from dbo_Invoices Where IdInvoice = " & lngNewID 
    If tRecordset2Read = dbOpenDynaset Then 
     Set rs2Read = dbs.OpenRecordset(strSQL, dbOpenDynaset, dbSeeChanges) 
    Else 
     Set rs2Read = dbs.OpenRecordset(strSQL, tRecordset2Read) 
    End If 
    If (rs2Read.BOF And rs2Read.EOF) Then 
     Err.Raise vbObjectError, , "rs2Read: Not found using IdInvoice = " & lngNewID 
    End If 
    Debug.Print "New record found with IdInvoice = " & rs2Read!IdInvoice 
    rs2Read.Close 

    bResult = True 
ExitHere: 
    If Not wks Is Nothing Then 
     If bTranInitiated Then 
      If bResult Then 
       wks.CommitTrans 
      Else 
       wks.Rollback 
      End If 
      bTranInitiated = False 
     End If 
    End If 
    On Error Resume Next 
    If Not rs2Add Is Nothing Then 
     rs2Add.Close 
     Set rs2Add = Nothing 
    End If 
    If Not rs2Read Is Nothing Then 
     rs2Read.Close 
     Set rs2Read = Nothing 
    End If 
    Exit Sub 
HandleErr: 
    Dim e As Object 
    If Err.Description Like "ODBC*" Then 
     For Each e In DBEngine.Errors 
      MsgBox e.Description, vbCritical 
     Next 
    Else 
     MsgBox Err.Description, vbCritical 
    End If 
    bResult = False 
    Resume ExitHere 
    Resume 
End Sub 

उत्तर

2

दुर्भाग्य से, माइक्रोसॉफ्ट राज्यों निम्नलिखित Workspace.IsolateODBCTrans के बारे में संपत्ति: http://msdn.microsoft.com/en-us/library/office/bb208483(v=office.12).aspx

जैसे Microsoft SQL सर्वर के रूप में कुछ ODBC सर्वर,, एक भी कनेक्शन पर एक साथ लेन-देन की अनुमति नहीं देते। यदि आपको ऐसे डेटाबेस के विरुद्ध लंबित समय में एक से अधिक लेन-देन की आवश्यकता है, तो जैसे ही आप इसे खोलते हैं, प्रत्येक कार्यक्षेत्र पर IsolateODBCTrans प्रॉपर्टी को सही पर सेट करें। यह प्रत्येक वर्कस्पेस के लिए एक अलग ओडीबीसी कनेक्शन को मजबूर करता है।

सुनिश्चित नहीं है कि इससे आपको यह तय करने में मदद मिलेगी कि क्या करना है।

+0

धन्यवाद। लेकिन मैं हार मानो। हमने फिर से लिखने का फैसला किया है। "IsolateODBCTrans" हल नहीं करता है। मैं एक से अधिक लेनदेन नहीं चाहता, बस ओइन। मुझे एक से अधिक कनेक्शन नहीं चाहिए। – ricardohzsz

+1

मैंने यही समस्या के बारे में भी सोचा था। अफ़सोस की बात है। कम से कम आप कोड थोड़ा ;-) – milivojeviCH

+0

आप केवल एक है जो इस समस्या का समाधान की पेशकश करने का प्रयास किया है, मैं इनाम के साथ पुरस्कार के लिए तय कर लिया है अनुकूलन करने के लिए एक बदलाव प्राप्त;) शायद यह एक है समाधान के बिना समस्या। फिर भी धन्यवाद। जब भी मैं इसका इस्तेमाल करने की जरूरत है – Jonathan

0

आप उन तालिकाओं के लिए दाओ का उपयोग जारी रख सकते हैं जो एमडीबी में रहते हैं। हालांकि sqlserver तालिकाओं (लिंक्ड टेबल) के लिए इस तरह: ग्लोबल objConn नई एडीओडीबी के रूप में।कनेक्शन

और दिनचर्या में:

Dim rst As ADODB.Recordset 
    DoCmd.SetWarnings False 
    If objConn.State <> adStateOpen Then 
     MsgBox ("Connection to SQL server has not been made. Please exit and resolve problem.") 
     Exit Sub 
    End If 

    Set rst = New ADODB.Recordset 

Dim stdocname As String 
rst.Open "tblbilling", objConn, adOpenDynamic, adLockPessimistic 

आदि आदि आदि .....

+1

कभी झूठी – Fionnuala

+0

@Fionnuala DoCmd.SetWarnings उपयोग करते हैं, मैं हमेशा यकीन है कि मैं एक है कि यह "सही" उप के अंत में सेट ... यह ठीक नहीं है लिखना है? – Ethan

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