Comment faire une boucle dans un update (SQL Server) depuis Access VBA

Résolu
V1ck1ng -  
 V1ck1ng -
Bonjour à tous,

J'utilise MS Access comme interface utilisateur, j'accède au serveur de données Server SQL via VBA.
Je souhaite mettre à jour un ensemble de lignes dans une table CANDIDAT_TESTS. Ce que je fais actuellement est de mettre à jour une par une et je boucle avec un for; cela fonctionne, mais ça prend trop de temps. J'aimerais donc réduire le temps d'exécution en faisant une boucle dans ma requête.
Ci-dessous mon code VBA

varSession = "2020"
Set cnx = getConnectionBD(varSession)

rsSCE.Open "SELECT DISTINCT LIBELLE_DEPARTEMENT, LIBELLE_SOUS_CENTRE, NUM_SOUS_CENTRE " _
& " FROM VIEW_CANDIDATS_SCE " _
& " WHERE NUM_REGION = " & Me.LIST_REGION & " AND NUM_EXAMEN = " & Me.LIST_EXAMEN _
& " ORDER BY LIBELLE_DEPARTEMENT, LIBELLE_SOUS_CENTRE", cnx, adOpenStatic, adLockOptimistic
varTabSCE = rsSCE.GetRows
'On initialise les jurys parce que les jurys sont par région
jury = 0

'On parcourt les sous-centres par départements
For j = 1 To rsSCE.RecordCount
rsSerie.Open "SELECT DISTINCT NUM_SERIE, ABREVIATION_SERIE " _
& " FROM VIEW_CANDIDATS_SCE " _
& " WHERE NUM_SOUS_CENTRE = " & varTabSCE(2, j - 1) & " AND NUM_EXAMEN = " & Me.LIST_EXAMEN _
& " ORDER BY ABREVIATION_SERIE", cnx, adOpenStatic, adLockOptimistic
varTabSerie = rsSerie.GetRows

'On parcourt les séries du sce j
For k = 1 To rsSerie.RecordCount
'on initialise le curseur à 0 étant donné que les numéros d'ordre sont par série
cursor = 0
rsCandidats.Open "SELECT ID FROM CANDIDAT_TESTS " _
& " WHERE NUM_SOUS_CENTRE = " & varTabSCE(2, j - 1) & " AND NUM_SERIE = " & varTabSerie(0, k - 1) _
& " ORDER BY NOMS, DATE_DE_NAISSANCE", cnx, adOpenStatic, adLockOptimistic
varTabCandidats = rsCandidats.GetRows

nbCanddidats = rsCandidats.RecordCount
nbJurys = RoundUp(nbCanddidats / 250)

'On parcourt les jurys de la série k du sce j
numJury = nbJurys
For l = 1 To nbJurys
jury = jury + 1

If numJury > 1 Then
'On parcourt les candidats du jury l pour leur attribuer le numéro d'ordre et le jury
For m = 250 * (l - 1) + 1 To 250 * (l - 1) + 250
cursor = cursor + 1
rsUpdate.Open "UPDATE CANDIDAT_TESTS " _
& " SET NUMERO_ORDRE = " & cursor & ", JURY = " & jury _
& " WHERE ID = " & varTabCandidats(0, m - 1), cnx, adOpenStatic, adLockOptimistic

Set rsUpdate = Nothing
Next m
ElseIf numJury = 1 Then
'On parcourt les candidats du dernier jury pour leur attribuer le numéro d'ordre et le jury
For m = 250 * (l - 1) + 1 To nbCanddidats
cursor = cursor + 1
rsUpdate.Open "UPDATE CANDIDAT_TESTS " _
& " SET NUMERO_ORDRE = " & cursor & ", JURY = " & jury _
& " WHERE ID = " & varTabCandidats(0, m - 1), cnx, adOpenStatic, adLockOptimistic

Set rsUpdate = Nothing
Next m
End If
numJury = numJury - 1

Next l

Set rsCandidats = Nothing
Set rsSerie = Nothing
Next k

Set rsSCE = Nothing
Next j

2 réponses

  1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 588
     
    je ne sais pas ce que tu penses en écrivant "en faisant une boucle dans ma requête".

    ce que tu peux faire, par exemple, c'est ceci, à partir du recordset rsCandidats:
    dim popjury as integer, jurynum as integer
    popjury=0
    jurynum=1
    Do Until rsCandidats.EOF
        cursor = cursor  + 1 
        popjury=popjury+1
        if popjury > 250 then
              popjury=1
              jurynum=jurynum+1
        end if
        rsCandidats.Edit
        rsCandidats!NUMERO_ORDRE = cursor
        rsCandidats!JURY = jurynum
        rsCandidats.Update
        rsCandidats.MoveNext
    Loop
    
    0
    1. V1ck1ng
       
      Déjà merci pour ton intervention, j'entends par là la possibilité de faire un update de plusieurs candidats à la fois au lieu de faire une requête à la fois et la répéter tel que c'est fait dans mon code.

      rsCandidats 
      contient n enregistrements, je dois faire un update de ces candidats mais en bloc de 250. Du 1er au 250ème enrégistrement, NUMERO_ORDRE va aller de 1 à 250 et c'est un numéro de jury; du 251ème au 500ème NUMERO_ORDRE va de 1 à 250 et le numéro de jury incrémente, ainsi de suite.

      Plus concrètement, disons que
      rsCandidats 
      a 600 lignes :
      - De 1 à 250 : NUMERO_ORDRE de 1 à 250 et
      JURY = JURY + 1 
      ;
      - De 250 à 500 : NUMERO_ORDRE de 1 à 250 et
      JURY = JURY + 1 
      ;
      - De 501 à 600 : NUMERO_ORDRE de 1 à 100 et
      JURY = JURY + 1 
      .
      J'aimerais donc ne pouvoir faire que 3 requêtes pour chacun de ces cas, ce de façon générique, étant donné que le nombre d'enregistrements de
      rsCandidats 
      varie.

      Merci.
      0
      1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588 > V1ck1ng
         
        as-tu essayé ma suggestion?
        0
      2. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588 > V1ck1ng
         
        ton code ne fait pas ce que tu décris, car tu incrémentes toujours cursor.
        0
      3. V1ck1ng > yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention  
         
        Oui tu as raison désolé, dans mon exemple NUMERO_ORDRE dans mon exemple va aller de 1 à 500, c'est JURY qui va incrémenter pour chaque 250 lignes. Ceci dit, je vais implémenter ta suggestion et te revenir. Merci
        0
    2. V1ck1ng
       
      Ce bout de code est parfait ! le contrôle sur le popjury et la petite astuce de retour à 1 du même popjury resolvent mon problème de bloc de 250. Merci beaucoup yg_be ! Merci pour la promptitude et la disponibilité !
      0