2010-06-25 11 views
2

Je veux accéder aux enregistrements individuels dans un jeu d'enregistrements ADO classique sans énumérer sur l'ensemble du jeu d'enregistrements en utilisant .MoveNext. Je suis conscient d'utiliser AbsolutePosition ainsi que .Filter =. Quelle est la meilleure façon?Quel est le moyen le plus efficace pour accéder à un seul enregistrement dans un jeu d'enregistrements ADO?

Je vais probablement accéder plusieurs fois au jeu d'enregistrements en extrayant des enregistrements individuels qui correspondent à une liste d'enregistrements dans un champ particulier. Par exemple, j'ai un jeu d'enregistrements avec des enregistrements dont les valeurs vont de 1 à 100. Je pourrais avoir un tableau séparé contenant seulement {34, 64, 72}, et je veux faire quelque chose aux enregistrements du jeu d'enregistrements dont les ID sont contenus dans le tableau.

+0

Vous prévoyez juste saisir un enregistrement, une fois? ou un tas de disques, un tas de fois? combien d'enregistrements saisissez-vous par rapport au nombre d'enregistrements de votre jeu d'enregistrements? –

+0

@Peter J'ai ajouté plus de détails ci-dessus –

Répondre

1

je fini par réécrire ma réponse en raison de nouvelles informations, donc:

Ma suggestion est de définir la propriété Filter à ce que vous voulez, puis énumérer le sous-ensemble résultant et affecter la valeur Bookmark de chaque enregistrement dans le sous-ensemble à une variable que vous pouvez facilement faire correspondre avec les ID (vous devriez donc les mettre dans un tableau dans l'ordre dans lequel leurs ID sont dans le tableau d'ID que vous mentionnez).

1

Si vous utilisez des curseurs côté serveur, la meilleure méthode dépend du fournisseur OLE DB sous-jacent que vous utilisez. Il est tout à fait possible que chaque accès de l'enregistrement entraîne un autre déplacement sur le serveur pour lire les données.

Si vous pouvez utiliser un curseur côté client, alors je suppose que AbsolutePosition sera la meilleure méthode pour passer à chaque enregistrement à plusieurs reprises. Je crois que l'utilisation d'un filtre avec un curseur côté client nécessiterait qu'il tourne à travers chaque enregistrement correspondant à la condition de filtre.

+0

Quelle est la garantie que l'ordre des ID sera croissant, consécutif, et commencer à 1? Si ce n'est pas le cas, alors vous devrez trouver les positions ordinales des enregistrements que vous voulez avant de pouvoir utiliser AbsolutePosition pour vous y référer, n'est-ce pas? – JAB

+0

Tout cela est côté client. La position absolue devrait fonctionner pour ma situation. –

+0

@JAB: Correct. Mais le PO a dit qu'il y accèderait plusieurs fois. Une fois trouvés et les positions notées via la propriété AbsolutePosition, il serait rapide de revenir vers eux via la même propriété. –

0

Utilisez la fonction Filtre sur l'objet Recordset.

rs.Filter = "ID = '" & strID & "'" 
0

J'utilise cette fonction tout le temps

Public Function InitIndexCollection(_ 
      rs As Recordset, _ 
      sFld As String, _ 
      Optional sFld2 As String, _ 
      Optional sFld3 As String, _ 
      Optional ByVal HasDuplicates As Boolean) As Collection 
    Const FUNC_NAME  As String = "InitIndexCollection" 
    Dim oFld   As ADODB.Field 
    Dim oFld2   As ADODB.Field 
    Dim oFld3   As ADODB.Field 

    On Error GoTo EH 
    Set InitIndexCollection = New Collection 
    If Not IsRecordsetEmpty(rs) Then 
     Set oFld = rs.Fields(sFld) 
     If LenB(sFld2) <> 0 Then 
      Set oFld2 = rs.Fields(sFld2) 
     End If 
     If LenB(sFld3) <> 0 Then 
      Set oFld3 = rs.Fields(sFld3) 
     End If 
     If HasDuplicates Then 
      On Error Resume Next 
     End If 
     With rs 
      If oFld2 Is Nothing Then 
       .MoveFirst 
       Do While Not .EOF 
        InitIndexCollection.Add .Bookmark, C_Str(oFld.Value) 
        .MoveNext 
       Loop 
      ElseIf oFld3 Is Nothing Then 
       .MoveFirst 
       Do While Not .EOF 
        InitIndexCollection.Add .Bookmark, C_Str(oFld.Value) & "#" & C_Str(oFld2.Value) 
        .MoveNext 
       Loop 
      Else 
       .MoveFirst 
       Do While Not .EOF 
        InitIndexCollection.Add .Bookmark, C_Str(oFld.Value) & "#" & C_Str(oFld2.Value) & "#" & C_Str(oFld3.Value) 
        .MoveNext 
       Loop 
      End If 
     End With 
    End If 
    Exit Function 
EH: 
    RaiseError FUNC_NAME 
    Resume Next 
End Function 
+0

Merci d'avoir fourni la fonction. Vous pourriez peut-être ajouter pourquoi vous pensez que cette fonction est plus performante que d'autres méthodes pour accéder à un seul enregistrement dans un jeu d'enregistrements ADO. Cela pourrait aider à mettre un peu en contexte. –

+0

Ceci est la suggestion de JAB mais avec une collection au lieu d'un tableau. La collection de VB utilise une table de hachage en interne et est très performant. Accéder à un enregistrement en utilisant une double indirection est le moyen le plus rapide de rechercher dans les curseurs côté client, par ex. 'rs.Bookmark = cIndex (rs2! User_ID &" # "& rs2! Author_ID)' est un ordre de grandeur plus rapide que la méthode 'Find', peu importe si vous avez' rs! User_ID.Properties ("OPTIMIZE"). ensemble d'index en mémoire. Et la performance de 'Filter' n'est pas près de' Find' ... – wqw