2017-05-15 11 views
0

私はループ内でExcelで実行されているSQLクエリを持っています。配列が小さい間に動作します。しかし、配列は現在約4000項目になり、クラッシュすることになります。これを行うには良い方法はあります、私はあなたが単一のSQL文を提出し、バック単一の結果セットを取得する必要があります上記の私のコメントで述べたように、このexcel vbaは配列全体でsqlクエリを実行します

For k = 0 To ubound(sqlarray) 

Dim conn As ADODB.Connection 
Dim recst As ADODB.Recordset 
Dim sqlstring As String 

Set conn = New ADODB.Connection 
Set recst = New ADODB.Recordset 


conn.ConnectionString = "Driver={Client Access ODBC Driver (32- 
bit)};System=mysys ;NAM=1;CurrentSchema=myschema;" 
conn.Open 


Sql = "Select ACCOUNT_NBR, ASSIGNED_TO from prodlib.gr_exp_account where 
account_nbr in ('" & sqlarray(k) & "')" 

Set recst.ActiveConnection = conn 

recst.Open Sql, conn 
Sheets("recst").Range("A" & k).CopyFromRecordset recst 


conn.Close 

Application.ScreenUpdating = True 
Next k 

End Sub 
+0

なぜループですか?私はあなたを狩り、私がDBAだったらあなたに暴力行為を読ませてくれるでしょう。なぜ、SELECT ... FROM prodlib.gr_exp_account WHERE account_nbr IN( 'cust1'、 'cust2'、...。 'cust4000') 'そしてそれを1つの結果セットに戻してください。あなたはそれで狂ったことをする必要がある場合は、それをループします。 – JNevill

答えて

0

を行うには、いくつかの簡単な方法をしないのです。すべての顧客をルーピングしてSQLを提出するのは悪いです。 JOINの場合、配列の大きさに問題がある、またはデータベースは、あなたが、あなたが一度で送信しているアカウントの数文句を言っている)(

Sub whatever(sqlArray as string) 

    'initialize these outside your loop next time too 
    Dim conn As ADODB.Connection 
    Dim recst As ADODB.Recordset 
    Dim sqlstring As String 

    Set conn = New ADODB.Connection 
    Set recst = New ADODB.Recordset 


    conn.ConnectionString = "Driver={Client Access ODBC Driver (32- 
    bit)};System=mysys ;NAM=1;CurrentSchema=myschema;" 
    conn.Open 

    'All the accounts in one list in one statement. Use array function 'Join' 
    'to make the array a comma delimited string (or comma with quotes as a delim) 
    Sql = "Select ACCOUNT_NBR, ASSIGNED_TO from prodlib.gr_exp_account where 
    account_nbr in ('" & Join(sqlArray, "','") & "')" 

    Set recst.ActiveConnection = conn 

    recst.Open Sql, conn 

    'Drop the entire recordset in a sheet starting at "A1" 
    Sheets("recst").Range("A1").CopyFromRecordset recst 


    conn.Close 

    Application.ScreenUpdating = True 


End Sub 

は、次のようなものを考えてみましょうループする可能性がありますが、より大きなチャンクを使用することができます:

Sub whatever(sqlArray As String) 

    'initialize these outside your loop next time too 
    Dim conn As ADODB.Connection 
    Dim recst As ADODB.Recordset 
    Dim sqlstring As String 

    Set conn = New ADODB.Connection 



    conn.ConnectionString = "Driver={Client Access ODBC Driver (32-bit)};System=mysys ;NAM=1;CurrentSchema=myschema;" 
    conn.Open 

    Dim k As Integer 
    Dim chunk As Integer 

    'Set this to how many accout numbers you can squeeze through in a single request safely 
    chunk = 400 

    For k = 1 To UBound(sqlArray) Step chunk 

     'reset this object in the loop 
     Set recst = New ADODB.Recordset 

     'All the accounts in one list in one statement. Use array function 'Join' 
     'to make the array a comma delimited string (or comma with quotes as a delim) 
     Sql = "Select ACCOUNT_NBR, ASSIGNED_TO from prodlib.gr_exp_account where account_nbr in ('" & Join_With_Limit(sqlArray, "','", chunk, k) & "')" 

     Set recst.ActiveConnection = conn 

     recst.Open Sql, conn 

     Sheets("recst").Range("A" & k).CopyFromRecordset recst 

     'close this for the next loop 
     recst.close 


    Next k 
    conn.Close 
    Application.ScreenUpdating = True 


End Sub 

Function Join_With_Limit(inArray As Variant, strDelim As String, intLimit As Integer, intOffset As Offset) As String 
    Dim i As Integer 

    For i = intOffset To intOffset + intLimit 
     'make sure we are below the ubound of the array 
     if i > uBound(inArray) Then Exit For 

     'If this isn't the first thing we are adding, then stick the delimiter 
     'before dropping in the value 
     If i <> intOffset Then Join_With_Limit = Join_With_Limit + strDelim 

     'Add the next item 
     Join_With_Limit = Join_With_Limit + inArray(i) 
    Next i 

End Function 
+0

私は、ループが正しい方法ではないことを知っています。結合配列にしようとすると、長すぎると私に伝えます。 – mbillion

+0

問題に参加するか、4000口座番号を送信したときにデータベースでエラーが発生していますか? – JNevill

+0

私はこれを試してみる前に、それは私にそれが長すぎるというエラーを与えました、いいえ、それはパラメータ* Nの変数の変換エラーを言っていません。デバッガは、recst.open行で停止していることを示しています - 私は手動でクエリを行うことはできますが、IBM Iシリーズでは問題ありません。そのため、データベースが好きではないと思われます – mbillion

関連する問題