IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VBA Access Discussion :

injecter une syntaxe dans une requete SQL direct avec ADO [AC-2010]


Sujet :

VBA Access

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Janvier 2005
    Messages
    629
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 629
    Par défaut injecter une syntaxe dans une requete SQL direct avec ADO
    Bonjour,

    J'ai besoin de vos conseils car même si j'ai déjà écrit des posts sur DAO/ADO, j'ai encore de grandes difficultés à comprendre à quoi ça correspond. Mon objectif final est d'injecter ma syntaxe SQL écrite en partie en VBA dans une requête SQL direct.

    Jusque là, mon programme fonctionnait à peu près car il se pouvait que, de façon aléatoire, il y ait parfois un message indiquant que l'appel à ODBC avait échoué. Comme j'avais déjà eu ce problème, j'ai voulu changer DAO en ADO en pensant que ça allait résoudre la situation...

    Voici le code où j'utilise un recordset DAO et où parfois j'ai une erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    Public Sub ComputeQueries(SQLWhere As String, db As DAO.Database)
     
        On Error GoTo err
        Dim RstTable As DAO.Recordset
        Dim strSQLModele As String
        Dim strNomRqt As String
     
        Set RstTable = db.OpenRecordset("SELECT QueryName, QueryCode FROM QUERIES where TypeV='TYPE1'")
        RstTable.MoveFirst
        While Not RstTable.EOF
            strNomRqt = RstTable.Fields("QueryName").Value
            strSQLModele = RstTable.Fields("QueryCode")
            db.QueryDefs(strNomRqt).SQL = strSQLModele ' cette ligne injecte la syntaxe SQL contenue dans strSQLModele dans ma requête SQL direct déjà existante au nom strNomRqt
            RstTable.MoveNext
        Wend
        RstTable.Close
        Set RstTable = Nothing
     
        Exit Sub
    err:
        MsgBox "Une erreur est survenue" & vbCrLf & err.Description, vbCritical, "ComputeQueries"
    End Sub
    Voici le code où j'utilise un recordset ADO qui semble marcher mais j'ai peur de tout mélanger en mixant du code DAO et ADO (j'ai laissé db as DAO.database) donc j'aimerai avoir votre avis sur ce code: suis-je en train de faire n'importe quoi ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    Public Sub ComputeQueriesADO(SQLWhere As String, db As DAO.Database)
     
        On Error GoTo err
     
        Dim oCn As ADODB.Connection
        Dim oRS As ADODB.Recordset
        Dim sSql As String
        Dim strSQLModele As String
        Dim strNomRqt As String
     
        Set oCn = Application.CurrentProject.Connection
        Set oRS = New ADODB.Recordset
        Set oRS.ActiveConnection = oCn
        sSql = "SELECT QueryName, QueryCode FROM QUERIES where TypeV='TYPE1'"
        oRS.Open sSql, , adOpenForwardOnly, adLockReadOnly, adCmdText
     
        oRS.MoveFirst
        While Not oRS.EOF
            strNomRqt = oRS.Fields("QueryName").Value
            strSQLModele = oRS.Fields("QueryCode")
            db.QueryDefs(strNomRqt).SQL = strSQLModele
            oRS.MoveNext
        Wend
        oRS.Close
        Set oRS = Nothing
        oCn.Close
        Set oCn = Nothing
     
        Exit Sub
    err:
        MsgBox "Une erreur est survenue" & vbCrLf & err.Description, vbCritical, "ComputeQueriesADO"
    End Sub
    Pouvez-vous me dire si je m'y prends bien ?
    J'ai fait des tests en utilisant command et catalogue ADOX mais je ne m'en suis pas sortie donc je suis revenue à QueryDefs ...
    Merci !

  2. #2
    Expert confirmé
    Avatar de LedZeppII
    Homme Profil pro
    Maintenance données produits
    Inscrit en
    Décembre 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Maintenance données produits
    Secteur : Distribution

    Informations forums :
    Inscription : Décembre 2005
    Messages : 4 485
    Par défaut
    Bonjour,

    La première sub (ComputeQueries) me semble parfaite.
    La seconde (ComputeQueriesADO) ne fait rien de plus qu'utiliser un recordset ADO au lieu d'un recordset DAO pour parcourir la table QUERIES.

    Je ne crois pas que tes erreurs ODBC viennent de la façon dont tu changes le code sql de la requête SQL-Direct.
    Sans le message erreur provenant du pilote ODBC c'est difficile de se faire une opinion.
    Le message d'erreur que cites vient d'Access et il est incomplet.
    Il faudrait peut-être, quand le problème se produit, essayer d'ouvrir un recordset sur la requête SQL-Direct.
    DAO devrait fournir un message plus explicite.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    Sub TestSQLDirect()
    Dim db As DAO.Database, rs As DAO.Recordset
    Dim errX As DAO.Error, strErrMsg As String
     
    On Error GoTo ErrH
     
    Set db = Application.CurrentDb
    Set rs = db.OpenRecordset("select * from [nom requête sql-direct]")
     
    rs.Close
     
    ExitS:
        Set rs = Nothing
        Set db = Nothing
        If Len(strErrMsg) <> 0 Then MsgBox strErrMsg
        Exit Sub
     
     
    ErrH:
        strErrMsg = "Erreur N° " & CStr(Err.Number) & " : " & Err.Description
        strErrMsg = strErrMsg & vbCrLf & vbCrLf & _
           ">>> Erreurs DAO :" & vbCrLf & _
           "======================"
        'Récupérations Erreur(s) DAO
        For Each errX In DBEngine.Errors
            strErrMsg = strErrMsg & vbCrLf & Format(errX.Number, "00000") & " : " & errX.Description
        Next
     
        Resume ExitS
     
    End Sub
    A+

  3. #3
    Expert confirmé
    Avatar de LedZeppII
    Homme Profil pro
    Maintenance données produits
    Inscrit en
    Décembre 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Maintenance données produits
    Secteur : Distribution

    Informations forums :
    Inscription : Décembre 2005
    Messages : 4 485
    Par défaut
    Bonjour,
    Citation Envoyé par debdev Voir le message
    J'ai fait des tests en utilisant command et catalogue ADOX mais je ne m'en suis pas sortie donc je suis revenue à QueryDefs ...
    J'ai mis du temps à trouver, mais finalement je crois avoir trouvé.
    Je mets mon code juste pour information, car je pense qu'ADOX n'apporte rien de plus que DAO (si ce n'est plus de lignes de code).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    Public Sub ComputeQueriesAdoX(SQLWhere As String, db As DAO.Database)
        Dim RstTable As DAO.Recordset
        Dim strSQLModele As String
        Dim strNomRqt As String
        Dim oCat As Object, oProc As Object, oCmd As Object
     
        On Error GoTo ErrH:
     
        ' Créer Catalogue ADOX sur la base en cours
        Set oCat = CreateObject("ADOX.Catalog")
        Set oCat.ActiveConnection = Application.CurrentProject.Connection
     
        Set RstTable = db.OpenRecordset("SELECT QueryName, QueryCode FROM QUERIES where TypeV='TYPE1'")
        RstTable.MoveFirst
        While Not RstTable.EOF
            strNomRqt = RstTable.Fields("QueryName").Value
            strSQLModele = RstTable.Fields("QueryCode")
            ' Référencer la requête SQL-Direct
            ' (elle est vue comme une procédure et non comme une Vue à cause de son type SQL-Direct)
            Set oProc = oCat.Procedures(strNomRqt)
            ' Référencer la commande
            Set oCmd = oProc.Command
            ' Modifier le SQL de la commande
            oCmd.CommandText = strSQLModele
            ' Actualiser la requête
            Set oProc.Command = oCmd
            oCat.Procedures.Refresh
            ' Enregistement suivant
            RstTable.MoveNext
        Wend
        RstTable.Close
        Set RstTable = Nothing
        Set oCmd = Nothing
        Set oProc = Nothing
        Set oCat = Nothing
        Exit Sub
     
    ErrH:
        MsgBox "Une erreur est survenue" & vbCrLf & err.Description, vbCritical, "ComputeQueriesAdoX"
    End Sub
    L'astuce pour que ça fonctionne se trouve ligne 26.
    Sans cette ligne, les modifications ne sont pas enregistrées.

    A+

  4. #4
    Membre éclairé
    Inscrit en
    Janvier 2005
    Messages
    629
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 629
    Par défaut
    Salut !

    Merci pour tes réponses LedZeppII. Avant d'envoyer ce message, j'ai procédé à des tests. Et j'ai été confrontée à un problème réseau indépendant du code VBA (pb de driver), du coup, j'ai mis du temps à répondre...

    J'ai testé ton code pour injecter la syntaxe SQL dans une requête SQL direct avec ADOX Nickel, comme ça j'ai les 2 façons de faire DAO et ADOX.
    Par contre, avec ADOX, mon programme met 2 fois plus de temps à s'exécuter.

    Je vais donc garder DAO pour le momenet et la prochaine fois que je rencontre l'erreur ODBC, je vais tester ton code pour décrypter l'erreur. Mais j'ai une question: le code que tu m'as mis, je peux l'exécuter après coup ? C'est-à-dire que si mon programme plante, je peux l'arrêter, repérer sur quelle requête SQL il a planté et lancer ton code pour avoir une erreur plus détaillée ? Ou bien il faut que j'insère ton code dans le mien et qu'il s'exécute en même temps ?

    Cette nuit, j'ai lancé mon programme intégral, tout a fonctionné.
    En ce moment même, je retourne mon programme intégral, j'attends...

    Un grand merci pour ton aide !

  5. #5
    Expert confirmé
    Avatar de LedZeppII
    Homme Profil pro
    Maintenance données produits
    Inscrit en
    Décembre 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Maintenance données produits
    Secteur : Distribution

    Informations forums :
    Inscription : Décembre 2005
    Messages : 4 485
    Par défaut
    Bonjour,

    Je pense que DAO est la bibliothèque la plus appropriée pour modifier une requête SQL-Direct.
    Je ne pense pas que ce soit db.QueryDefs(strNomRqt).SQL = strSQLModele qui soit à l'origine du problème.
    C'est pour cette raison que je t'ai proposé ma procédure TestSQLDirect(), pour tester la requête SQL-Direct.
    Son but est de tester l'exécution de la requête, en l'ouvrant avec un recordset, et d'afficher un message d'erreur plus détaillé.
    Donc, oui il faut connaître le nom de la requête SQL-Direct qui est à l'origine de l'erreur ODBC.

    Voila ce à quoi je pensais...:
    Admettons que ta table QUERIES contienne dix requêtes nommées R_SQLDIRECT_001 à R_SQLDIRECT_010.
    Tu exécutes ton code ComputeQueries qui va modifier le code SQL de ces dix requêtes.
    (Je ne m'attends pas à ce qu'une quelconque erreur ODBC soit levée à ce niveau).
    Je suppose qu'ensuite ces requêtes sont exploitées/exécutées d'une manière ou d'une autre.
    Si une erreur ODBC est levée, il faut déterminer sur quelle requête ou quelle requête est impliquée.
    Supposons que tu détermines que c'est R_SQLDIRECT_006.
    Tu modifies cette ligne de mon code...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Set rs = db.OpenRecordset("select * from [nom requête sql-direct]")
    ...en...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Set rs = db.OpenRecordset("select * from [R_SQLDIRECT_006]")
    ... tu exécutes mon code (il faudra certainement arrêter le débogueur au préalable).
    Et là, je m'attends à ce que ma procédure donne un message plus complet.
    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Erreur N° 3146 : ODBC -- l'appel a échoué.
    
    >>> Erreurs DAO :
    ======================
    01064 : [MySQL][ODBC 5.2(w) Driver][mysqld-5.1.41-community-log]You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'all tables' at line 1
    03146 : ODBC -- l'appel a échoué.
    L'erreur 3146 est l'erreur générique reportée par VBA.Err.
    L'erreur 1064 est plus spécifique et provient du pilote ODBC.

    A+

  6. #6
    Membre éclairé
    Inscrit en
    Janvier 2005
    Messages
    629
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 629
    Par défaut
    Merci pour toutes tes explications

    J'ai remis DAO pour parcourir le recordset initial.

    J'ai lancé plusieurs fois de suite mon code et il n'a pas planté mais dès que ça recommence, j'utiliserai ta méthode permettant d'avoir un message d'erreur plus explicite.

    Merci +++

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2007] Afficher une checkbox dans une feuille si une checkbox d'une autre feuille est cochée
    Par JessieCoutas dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 18/08/2009, 13h35
  2. portée d'une variable dans une fonction dans une méthode
    Par laurentg2003 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 29/06/2009, 19h05
  3. [POO] dans une classe, appeler une fonction dans une méthode
    Par arnaudperfect dans le forum Langage
    Réponses: 3
    Dernier message: 26/08/2007, 23h04
  4. Envoyer une formulaire dans une page dans une Frame
    Par zooffy dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 29/06/2007, 10h13
  5. Recherche une valeur d'une cellule dans une colonne d'une autre feuille
    Par kourria dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 21/06/2007, 13h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo