2011-07-04 44 views
4

我真的用這個拉我的頭髮。我有一個VBScript,我試圖在Access數據庫中插入幾十萬條記錄。使用Vbscript批量插入Access的記錄

很明顯,如果我一次只做一個,真的很慢,所以我想我可能可以通過某種事務批量插入它們。於是,我試着寫這樣的:

set rs = CreateObject("ADODB.recordset") 
rs.Open "table", objConn,, 4 

For counter = 1 to 100000 
    rs.AddNew 
    rs("username") = "Value" 
Next 

    rs.UpdateBatch 

(objConn是數據庫連接)。

問題是,我得到一個錯誤說:

「與掛起的更改的行數超出限制」

,我得到的是,當有多個待定變化。

我想我沒有正確設置我的交易,但我有點卡住了。不要以爲有人可以指出我的方式錯誤?非常感謝。

+0

你從哪裏得到記錄?外部來源(文件?)?或者你在內存中生成它們? –

+0

它們在內存中生成。如果你認爲這會有所幫助,我可以先將它們寫入一個文件,但這並不是解決這種問題的正確方法。 – Simon

回答

9

要主張我的建議在交易中使用的命令,我寫了 此腳本:

Dim sAct  : sAct  = "trout" 
    If goWAN.Exists("a") Then sAct = goWAN("a") 
    Dim nRecs  : nRecs  = 10 
    If goWAN.Exists("n") Then nRecs = CLng(goWAN("n")) 
    Dim sMFSpec : sMFSpec = goFS.GetAbsolutePathName("..\data\ut.mdb") 
    Dim oConn  : Set oConn = CreateObject("ADODB.Connection") 
    Dim oRs  : Set oRs = CreateObject("ADODB.Recordset") 

    Dim nRec, oCmd, nRA, aData, oParm 

    oConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & sMFSpec 
    Set oRs.ActiveConnection = oConn 

    oConn.Execute("DELETE FROM tLines") 
    WScript.Echo "#Recs:", oConn.Execute("SELECT COUNT(SampleText) FROM tLines").Fields(0) 

    WScript.Echo sAct 
    Select Case sAct 
    Case "trout" 
    Case "bob" 
     oRs.CursorLocation = adUseClient 
     oRs.CursorType = adOpenKeySet 
     oRs.LockType = adLockBatchOptimistic  
    Case "eh" 
    End Select 
    WScript.Echo "oRs.CursorLocation: ", oRs.CursorLocation 
    WScript.Echo "oRs.CursorType: ", oRs.CursorType 
    WScript.Echo "oRs.LockType: ", oRs.LockType 
    Select Case sAct 
    Case "trout", "bob" 
     oRs.Open "tLines", oConn, , adLockBatchOptimistic 
     For nRec = 1 to nRecs 
      oRs.AddNew 
      oRs("SampleText") = "This is line " & nRec 
     Next 
     oRs.UpdateBatch 
     oRs.Close 
    Case "eh" 
     oConn.BeginTrans 
     Set oParm = CreateObject("ADODB.Parameter") 
     With oParm 
     .Name  = "A" 
     .Type  = adVarChar 
     .Value  = "" 
     .Direction = adParamInput 
     .Size  = 100 
     End With 
     Set oCmd = CreateObject("ADODB.Command") 
     With oCmd 
     Set .ActiveConnection = oConn 
      .CommandText  = "INSERT INTO tLines (SampleText) VALUES (?)" 
      .CommandType  = adCmdText 
      .Parameters.Append oParm 
     End With 

     ReDim aData(0) 
     For nRec = 1 to nRecs 
      aData(0) = "This is line " & nRec 
      oCmd.Execute nRA, aData, adExecuteNoRecords + adCmdText 
     Next 
     oConn.CommitTrans 
    End Select 

    WScript.Echo "#Recs:", oConn.Execute("SELECT COUNT(SampleText) FROM tLines").Fields(0) 
    WScript.Echo "First:", oConn.Execute("SELECT TOP 1 * FROM tLines").Fields(0) 

    oConn.Close 

調用/ N:200和/ A:鱒魚它顯示:

#Recs: 0 
    trout 
    oRs.CursorLocation: 2 
    oRs.CursorType: 0 
    oRs.LockType: 1 
    ... xpl.vbs(246, 11) Provider: Number of rows with pending changes exceeded the limit. 

所以我認爲,我正確地重現了你的問題。對於/ A:鮑勃:

#Recs: 0 
    bob 
    oRs.CursorLocation: 3 
    oRs.CursorType: 1 
    oRs.LockType: 4 
    #Recs: 200 
    First: This is line 1 
    xpl.vbs: Erfolgreich beendet. (0) [ 19.74219 secs ] 

所以設置

oRs.CursorLocation = adUseClient 
    oRs.CursorType = adOpenKeySet 
    oRs.LockType = adLockBatchOptimistic  

鮑勃(微軟)諫是一個解決您的問題。爲了得到一些速度,我把一個 指令到交易:

oConn.BeginTrans 
    Set oCmd = CreateObject("ADODB.Command") 
    ... 
    ReDim aData(0) 
    For nRec = 1 to nRecs 
     aData(0) = "This is line " & nRec 
     oCmd.Execute nRA, aData, adExecuteNoRecords + adCmdText 
    Next 
    oConn.CommitTrans 

結果:

#Recs: 0 
eh 
oRs.CursorLocation: 2 
oRs.CursorType: 0 
oRs.LockType: 1 
#Recs: 200 
First: This is line 1 
xpl.vbs: Erfolgreich beendet. (0) [ 1.47656 secs ] 

月20日至2秒(不帶任何屬性擺弄)似乎沒有對我不好。

+0

哦,那太棒了!非常感謝。真的很感謝你爲此付出的努力。我的腳本已經消耗了很長時間,我可以喝一杯茶然後回來,它仍然會跑到大約5秒鐘。 – Simon

1

如果您正在使用OLEDB,那麼你需要設置CursorLocation屬性爲adUseClient按照下面的知識庫文章:http://support.microsoft.com/kb/261297

你也可以考慮在小批量運行,如果它的速度慢,在一個時間做100K

編輯:是的,adUseClient需要被定義爲= 3,或者只是在它的位置使用數字3。

+0

所以我碰到那篇文章,我嘗試添加:rs.CursorLocation = adUseClient,但我得到一個錯誤,說「參數是錯誤的類型,超出了可接受的範圍,或者相互衝突」,而我無法弄清楚是什麼原因造成的。 – Simon

+0

其實,我認爲這可能是答案,但由於某些原因「rs.CursorLocation = adUseClient」不起作用,而不得不使用「rs.CursorLocation = 3」 - 讓我試試這個...... – Simon

+0

它是儘管地獄仍然緩慢...上帝我討厭Access ... – Simon