This example is a Visual Basic block insert that is significantly faster than a "parameterized" insert.
Block inserts allow you to:
See Block insert and block fetch C example for additional information.
Dim cbNTS(BLOCKSIZE - 1) As Long 'NTS array Dim lCustnum(BLOCKSIZE - 1) As Long 'Customer number array '2nd parm passed by actual length for demo purposes Dim szLstNam(7, BLOCKSIZE - 1) As Byte 'NOT USING NULL ON THIS PARM Dim cbLenLstNam(BLOCKSIZE - 1) As Long 'Actual length of string to pass Dim cbMaxLenLstNam As Long 'Size of one array element 'These will be passed as sz string so size must include room for null Dim szInit(3, BLOCKSIZE - 1) As Byte 'Size for field length + null Dim szStreet(13, BLOCKSIZE - 1) As Byte 'Size for field length + null Dim szCity(6, BLOCKSIZE - 1) As Byte 'Size for field length + null Dim szState(2, BLOCKSIZE - 1) As Byte 'Size for field length + null Dim szZipCod(5, BLOCKSIZE - 1) As Byte 'Size for field length + null Dim fCdtLmt(BLOCKSIZE - 1) As Single Dim fChgCod(BLOCKSIZE - 1) As Single Dim fBalDue(BLOCKSIZE - 1) As Single Dim fCdtDue(BLOCKSIZE - 1) As Single Dim irow As Long ' row counter for block errors Dim lTotalRows As Long ' ************ Total rows to send ************* Dim lNumRows As Long ' Rows to send in one block Dim lRowsLeft As Long ' Number of rows left to send Dim I As Long Dim J As Long Dim S As String Dim hStmt As Long ' This program needs QCUSTCDT table in your own collection. ' At the iSeries server command line type: '===> CRTLIB SAMPCOLL '===> CRTDUPOBJ OBJ(QCUSTCDT) FROMLIB(QIWS) ' OBJTYPE(*FILE) TOLIB(SAMPCOLL) NEWOBJ(*SAME) '===> CHGPF FILE(SAMPCOLL/QCUSTCDT) SIZE(*NOMAX) '===> CLRPFM FILE(SAMPCOLL/QCUSTCDT) '************** Start ***************************************************** S = "Number of records to insert into QCUSTCDT. " S = S & "Use menu option Table Mgmt, Create QCUSTCDT to " S = S & "create the table. Use Misc, iSeries Cmd and CLRPFM " S = S & "command if you wish to clear it" S = InputBox(S, gAppName, "500") If Len(S) = 0 Then Exit Sub lTotalRows = Val(S) 'Total number to insert rc = SQLAllocHandle(SQL_HANDLE_STMT, ghDbc, hStmt) If (Not (rc = SQL_SUCCESS Or rc = SQL_SUCCESS_WITH_INFO)) Then GoTo errBlockInsert rc = SQLPrepare(hStmt, _ "INSERT INTO QCUSTCDT ? ROWS VALUES (?,?,?,?,?,?,?,?,?,?,?)", _ SQL_NTS) If (Not (rc = SQL_SUCCESS Or rc = SQL_SUCCESS_WITH_INFO)) Then GoTo errBlockInsert rc = SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, _ 10, 0, lCustnum(0), 0, ByVal 0) If (rc = SQL_ERROR) Then _ Call DspSQLDiagRec(SQL_HANDLE_STMT, hStmt, "Problem: Bind Parameter") 'Pass first parm w/o using a null cbMaxLenLstNam = UBound(szLstNam, 1) - LBound(szLstNam, 1) + 1 rc = SQLBindParameter(hStmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, _ 8, _ 0, _ szLstNam(0, 0), _ cbMaxLenLstNam, _ cbLenLstNam(0)) If (rc = SQL_ERROR) Then _ Call DspSQLDiagRec(SQL_HANDLE_STMT, hStmt, "Problem: Bind Parameter") rc = SQLBindParameter(hStmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, _ 3, 0, szInit(0, 0), _ UBound(szInit, 1) - LBound(szInit, 1) + 1, _ cbNTS(0)) If (rc = SQL_ERROR) Then _ Call DspSQLDiagRec(SQL_HANDLE_STMT, hStmt, "Problem: Bind Parameter") rc = SQLBindParameter(hStmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, _ 13, 0, szStreet(0, 0), _ UBound(szStreet, 1) - LBound(szStreet, 1) + 1, _ cbNTS(0)) If (rc = SQL_ERROR) Then _ Call DspSQLDiagRec(SQL_HANDLE_STMT, hStmt, "Problem: Bind Parameter") rc = SQLBindParameter(hStmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, _ 6, 0, szCity(0, 0), _ UBound(szCity, 1) - LBound(szCity, 1) + 1, _ cbNTS(0)) If (rc = SQL_ERROR) Then _ Call DspSQLDiagRec(SQL_HANDLE_STMT, hStmt, "Problem: Bind Parameter") rc = SQLBindParameter(hStmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, _ 2, 0, szState(0, 0), _ UBound(szState, 1) - LBound(szState, 1) + 1, _ cbNTS(0)) If (rc = SQL_ERROR) Then _ Call DspSQLDiagRec(SQL_HANDLE_STMT, hStmt, "Problem: Bind Parameter") rc = SQLBindParameter(hStmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_NUMERIC, _ 5, 0, szZipCod(0, 0), _ UBound(szZipCod, 1) - LBound(szZipCod, 1) + 1, _ cbNTS(0)) If (rc = SQL_ERROR) Then _ Call DspSQLDiagRec(SQL_HANDLE_STMT, hStmt, "Problem: Bind Parameter") rc = SQLBindParameter(hStmt, 8, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_NUMERIC, _ 4, 0, fCdtLmt(0), 0, ByVal 0) If (rc = SQL_ERROR) Then _ Call DspSQLDiagRec(SQL_HANDLE_STMT, hStmt, "Problem: Bind Parameter") rc = SQLBindParameter(hStmt, 9, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_NUMERIC, _ 1, 0, fChgCod(0), 0, ByVal 0) If (rc = SQL_ERROR) Then _ Call DspSQLDiagRec(SQL_HANDLE_STMT, hStmt, "Problem: Bind Parameter") rc = SQLBindParameter(hStmt, 10, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_NUMERIC, _ 6, 2, fBalDue(0), 0, ByVal 0) If (rc = SQL_ERROR) Then _ Call DspSQLDiagRec(SQL_HANDLE_STMT, hStmt, "Problem: Bind Parameter") rc = SQLBindParameter(hStmt, 11, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_NUMERIC, _ 6, 2, fCdtDue(0), 0, ByVal 0) If (rc = SQL_ERROR) Then _ Call DspSQLDiagRec(SQL_HANDLE_STMT, hStmt, "Problem: Bind Parameter") lRowsLeft = lTotalRows 'Initialize row counter For J = 0 To ((lTotalRows - 1) \ BLOCKSIZE) For I = 0 To BLOCKSIZE - 1 cbNTS(I) = SQL_NTS ' init array to NTS lCustnum(I) = I + (J * BLOCKSIZE) 'Customer number = row number S = "Nam" & Str(lCustnum(I)) 'Last Name cbLenLstNam(I) = Len(S) rc = String2Byte2D(S, szLstNam(), I) 'Debug info: Watch address to see layout addr = VarPtr(szLstNam(0, 0)) 'addr = CharNext(szLstNam(0, I)) 'address of 1,I 'addr = CharPrev(szLstNam(0, I), szLstNam(1, I)) 'address of 0, I) 'addr = CharNext(szLstNam(1, I)) 'addr = CharNext(szLstNam(6, I)) 'should point to null (if used) 'addr = CharNext(szLstNam(7, I)) 'should also point to next row rc = String2Byte2D("DXD", szInit, I) 'Vary the length of the street S = Mid("1234567890123", 1, ((I Mod 13) + 1)) rc = String2Byte2D(S, szStreet, I) rc = String2Byte2D("Roches", szCity, I) rc = String2Byte2D("MN", szState, I) rc = String2Byte2D("55902", szZipCod, I) fCdtLmt(I) = I fChgCod(I) = 1 fBalDue(I) = 2 * I fCdtDue(I) = I / 2 Next I lNumRows = lTotalRows Mod BLOCKSIZE ' Number of rows to send in this block If (lRowsLeft >= BLOCKSIZE) Then _ lNumRows = BLOCKSIZE ' send remainder or full block irow = 0 lRowsLeft = lRowsLeft - lNumRows rc = SQLSetStmtAttr(hStmt, SQL_ATTR_PARAMSET_SIZE, lNumRows, 0) If (rc = SQL_ERROR) Then GoTo errBlockInsert rc = SQLSetStmtAttr(hStmt, SQL_ATTR_PARAMS_PROCESSED_PTR, irow, 0) If (rc = SQL_ERROR) Then GoTo errBlockInsert rc = SQLExecute(hStmt) If (rc = SQL_ERROR) Then S = "Error on Row: " & Str(irow) & Chr(13) & Chr(10) MsgBox S, , gAppName GoTo errBlockInsert End If Next J rc = SQLEndTran(SQL_HANDLE_DBC, ghDbc, SQL_COMMIT) If (Not (rc = SQL_SUCCESS Or rc = SQL_SUCCESS_WITH_INFO)) Then GoTo errBlockInsert rc = SQLFreeHandle(SQL_HANDLE_STMT, hStmt) Exit Sub errBlockInsert: rc = SQLEndTran(SQL_HANDLE_DBC, ghDbc, SQL_ROLLBACK) rc = SQLFreeHandle(SQL_HANDLE_STMT, hStmt) Public Function String2Byte2D(InString As String, OutByte() As Byte, RowIdx As Long) As Boolean 'VB byte arrays are layed out in memory opposite of C. The string would 'be by column instead of by row so must flip flop the string. 'ASSUMPTIONS: ' Byte array is sized before being passed ' Byte array is padded with nulls if > size of string Dim I As Integer Dim SizeOutByte As Integer Dim SizeInString As Integer SizeInString = Len(InString) SizeOutByte = UBound(OutByte, 1) 'Convert the string For I = 0 To SizeInString - 1 OutByte(I, RowIdx) = AscB(Mid(InString, I + 1, 1)) Next I 'If byte array > len of string pad If SizeOutByte > SizeInString Then 'Pad with Nulls For I = SizeInString To SizeOutByte - 1 OutByte(I, RowIdx) = 0 Next I End If 'ViewByteArray OutByte, "String2Byte" String2Byte2D = True End Function