This example is implemented in the middle tier, but you can modify for the client side.
' Class method Public Function getRoutines(ByVal pWhereClause As String, _ Optional ByVal withUpdatableId As Boolean = False) As ADODB.Recordset gError.push "getRoutines" On Error GoTo getRoutines_Err ' return disconnect rs for local updates Dim lSql As String Dim rs As ADODB.Recordset Set rs = New ADODB.Recordset lSql = "Select * from Routines" If Trim(pWhereClause) <> "" Then lSql = lSql & " Where " & pWhereClause End If lSql = lSql & " order by Description" rs.Open lSql, cn, adOpenStatic, adLockBatchOptimistic, adCmdText Set rs.ActiveConnection = Nothing If withUpdatableId Then Set getRoutines = getRsWithUpdatableIdent(rs) Else Set getRoutines = rs End If gError.pop Exit Function getRoutines_Err: gError.processError Err If gError.waitForBlockedResource() Then Resume gError.pop Err.Raise gError.Number, "Routines.getRoutines", gError.Description End Function ' Module Public Function getRsWithUpdatableIdent(pRs As ADODB.Recordset) As ADODB.Recordset Dim k As Long Dim rsNew As ADODB.Recordset Set rsNew = New ADODB.Recordset For k = 0 To pRs.Fields.Count - 1 rsNew.Fields.Append _ pRs.Fields(k).Name, _ pRs.Fields(k).Type, _ pRs.Fields(k).DefinedSize, _ pRs.Fields(k).Attributes If pRs(k).Properties("ISAUTOINCREMENT") = True Then rsNew.Fields(k).Attributes = (rsNew.Fields(k).Attributes Or adFldUpdatable) End If Next rsNew.Open , , adOpenStatic, adLockBatchOptimistic While Not pRs.EOF rsNew.AddNew For k = 0 To pRs.Fields.Count - 1 rsNew(k).Value = pRs(k).Value Next pRs.MoveNext Wend rsNew.UpdateBatch Set getRsWithUpdatableIdent = rsNew End Function You can read messages from the DOTNET archive, unsubscribe from DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com.