none
Mettre à jour une BDD access à partir d'un dataAdaptater RRS feed

  • Question

  • Bonjour,

    Je suis novice de la programmation avec liaison à une base de données.

    Je rencontre une erreur (La propriété DataAdapter.SelectCommand doit être initialisée.) lorsque j'éxecute mon code en mode debug.

    Je vous donne mon code :

    dlg_ajoutJoueur.vb

    Imports System.Windows.Forms
    Imports System
    Imports System.Data
    Imports System.Data.OleDb
    Imports Microsoft.VisualBasic
    
    Public Class dlg_AjoutJoueur
    
        Private Sub OK_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK_Button.Click
            If VerifExistanceJoueur() = False Then
                Me.DialogResult = System.Windows.Forms.DialogResult.OK
                dlg_NewGame.InitialisationCbox_Joueur()
                Me.Close()
            End If
        End Sub
    
        Private Sub Cancel_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Cancel_Button.Click
            Me.DialogResult = System.Windows.Forms.DialogResult.Cancel
            Me.Close()
        End Sub
    
        Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles txt_Prenom.TextChanged
            ValidationDonnees()
        End Sub
    
        Private Sub txt_Nom_TextChanged(sender As Object, e As EventArgs) Handles txt_Nom.TextChanged
            ValidationDonnees()
        End Sub
    
        Private Sub ValidationDonnees()
            If txt_Prenom.Text <> "" And txt_Nom.Text <> "" Then
                OK_Button.Enabled = True
            Else
                OK_Button.Enabled = False
            End If
        End Sub
    
        Public Sub New()
    
            ' Cet appel est requis par le concepteur.
            InitializeComponent()
    
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
    
            'Chargement de la table joueur dans le dataset
            OuvertureConnexion()
            dtAdapt_Joueur = New OleDbDataAdapter
            LancerRequete(requete(1), dtAdapt_Joueur, "Joueur")
            FermetureConnection()
    
        End Sub
    
        Private Function VerifExistanceJoueur() As Boolean
            Dim LigneTrouve() As Data.DataRow
            Dim NouvelleLigne As Data.DataRow = ds_BDD.Tables("Joueur").NewRow()
    
            LigneTrouve = ds_BDD.Tables("Joueur").Select("Nom = '" & txt_Nom.Text & "' AND Prenom = '" & txt_Prenom.Text & "'")
    
            If LigneTrouve.Length <> 0 Then
                MsgBox("Le joueur est déjà enregistré dans la liste des joueurs")
                Return True
            Else
                NouvelleLigne("Nom") = txt_Nom.Text
                NouvelleLigne("Prenom") = txt_Prenom.Text
                ds_BDD.Tables("Joueur").Rows.Add(NouvelleLigne)
                commandBuilder = New OleDbCommandBuilder(dtAdapt_Joueur)
                'Erreur à l'éxécution à la ligne suivante
                dtAdapt_Joueur.UpdateCommand = commandBuilder.GetUpdateCommand()
                dtAdapt_Joueur.Update(ds_BDD, "Joueur")
                ds_BDD.Clear()
                dtAdapt_Joueur.Fill(ds_BDD, "Joueur")
                dt_Joueur = ds_BDD.Tables("Joueur")
    
                Return False
            End If
    
        End Function
    
        Private Sub TextBox1_TextChanged_1(sender As Object, e As EventArgs)
    
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim essai As Boolean
    
            essai = VerifExistanceJoueur()
    
        End Sub
    End Class
    

    Module_BDD.vb

    'Imports System
    'Imports System.Data
    Imports System.Data.OleDb
    
    Module Module_BDD
    
        'Déclaration de la variable pour la connectionstring      
        Public connectionString As String = "provider = Microsoft.ACE.OLEDB.12.0 ; data source = C:\Users\jduchesne\Documents\Visual Studio 2012\Projects\ApplicationBDD\ApplicationBDD\Test1.accdb;"
        'Déclaration de la variable pour la requête      
        Public requete() As String
        'Déclaration de la variable pour le dataset      
        Public ds_BDD As New DataSet
    
    
        'Déclaration des tables  la variable pour la datatable
        Public dt_Joueur As DataTable
        Public dt_Req_NomCompletJoueur As DataTable
    
        'Déclaration de la variable pour le dataadapter
        Public dtAdapt_Joueur As OleDbDataAdapter
        Public dtAdapt_Req_NomCompletJoueur As OleDbDataAdapter
    
        'Déclaration de la variable pour la connection      
        Public connection As OleDbConnection
        'Déclaration de la variable pour la commande       
        Public command As OleDbCommand
    
        'Déclaration de la variable pour le datarow      
        Public dataRow As DataRow
        'Déclaration de la variable pour le Nº de l'enregistrement       
        Public rowNum As Integer
        'Déclaration de la variable pour le commandbuilder      
        Public commandBuilder As OleDbCommandBuilder
    
        Public Sub CreationRequete()
            ReDim requete(2)
            requete(0) = "select Req_NomComplet.* from Req_NomComplet"
            requete(1) = "select joueur.* from joueur"
    
        End Sub
    
        Public Sub OuvertureConnexion()
            'ouverture de la connection (à partir du répertoire de l'application) ,sur la même ligne      
            connection = New OleDbConnection
            connection.ConnectionString = connectionString
            connection.Open()
            'MsgBox("Connection ouverte")
        End Sub
    
        Public Sub LancerRequete(requete As String, dataAdaptater As OleDbDataAdapter, nomTable As String)
            'Création de la commande et on l'instancie (sql)       
            Command = New OleDbCommand(requete)
            'Création du dataadapter (dta) et on l'instancie (cmd)      
            dataAdaptater = New OleDbDataAdapter(Command)
            'On instancie la commande (cmd) à la connection (cnx)       
            Command.Connection() = connection
            'On charge le dataset (dts) grâce à la propriété fill du dataadapter (dta)      
            dataAdaptater.Fill(ds_BDD, nomTable)
            'On charge la datatable (dtt) grâce à la propriété tables du dataset (dts)
            dt_Joueur = ds_BDD.Tables(nomTable)
            'MsgBox("Données chargées")
        End Sub
        Public Sub FermetureConnection()
            connection.Dispose()
            'MsgBox("Connection fermée")
        End Sub
    End Module
    

    Merci d'avance à ceux qui pourront m'aider à corriger cette erreur.
    vendredi 11 avril 2014 21:20

Réponses

  • Je prends un peu de temps pour mieux expliquer. 
    Le dataAdapter fonctionne avec un DataSet/DataTable.

    Le DataTable est une copie d'une table en mémoire.  dataAdapter.Fill est utilisé pour apporter les informations qui se trouvent dans la BD en mémoire (DataSet/DataTable). En effet dataAdapter.SelectCommand  sera exécuté.
    Apres modifier les informations dans le DataTable, on doit enregistrer les informations dans la BD.

    En exécutant dataAdapter.Update (DataTable),  pour chaque ligne dans le DataTable, on vérifie le type de modification   et on exécute la commande SQL qui se trouve dans DataAdapter.UpdateCommand, InsertCommand ou DeleteCommand selon le cas, pour la ligne.

    Pour faire le code plus facile à lire, après créer le DataAdapter, assurez-vous que les commandes pour Select/Insert/Update/Delete ont les bonnes valeurs et utilisez sans modifier ces propriétés de votre DataAdapter.
     Vous pouvez utiliser OleDbCommandBuilder http://msdn.microsoft.com/fr-fr/library/system.data.oledb.oledbcommandbuilder(v=vs.110).aspx
    Pour corriger l’erreur ci-dessus vous devez utiliser :
    dtAdapt_Joueur.SelectCommand  = new OleDbCommand(requete(1) , connection);

    Bien cordialement


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    • Marqué comme réponse Aurel Bera vendredi 18 avril 2014 06:08
    lundi 14 avril 2014 11:08

Toutes les réponses

  • Bonjour,

    A quel ligne obtenez vous l'erreur suivante : "La propriété DataAdapter.SelectCommand doit être initialisée" ?

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte logiciel/Consultant/Formateur Freelance - P.O.S Informatique
    Blog : http://gilles.tourreau.fr - Suivez-moi sur Twitter
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5/4.0
    - MCSA : SQL Server 2012
    - MCITP : SQL Server 2008 Developper
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5/4.0 / TFS 2010 / Windows Azure

    dimanche 13 avril 2014 22:43
    Modérateur
  • Bonjour,

    Dans le fichier dlg_ajoutJoueur.vb, j'ai indiqué "Erreur à l'éxécution à la ligne suivante" dans la fonction "Private Function VerifExistanceJoueur() As Boolean".

    Cordialement.

    lundi 14 avril 2014 06:55
  • Bonjour

    Le code est assez difficile a comprendre.

    Veuillez essayer avec :

    ..........................

        dtAdapt_Joueur = New OleDbDataAdapter
    dtAdapt_Joueur.SelectCommand  = requete(1)

            LancerRequete(requete(1), dtAdapt_Joueur, "Joueur")
            FermetureConnection
    ()
    ..........................................

    Bien cordialement,


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    lundi 14 avril 2014 09:48
  • Merci pour votre réponse, j'ai essayé de rajouter :

    dtAdapt_Joueur.SelectCommand  = requete(1)

    mais j'ai l'erreur suivante : Impossible de convertir une valeur de type 'String' en 'System.Date.OleDb.OleDbCommand'

    Je vous acoue que comme suis novice, j'ai un peu de mal à structurer le code. J'ai essyé de faire un module pour ne pas récérire plusieurs fois les fonction, d'ouverture de connexion, lancement de requête... mais je ne sais si c'rest la bonne solution.

    Comment auriez-vous fait pour mieux structure le code ?

    je vous avoue que j'ai un peu de mal à comprendre le focntionenment des dataAdaptater. Un DataAdaptater doit-il être créé pour chaque requete, pour chaque tabe?

    lundi 14 avril 2014 10:39
  • Je prends un peu de temps pour mieux expliquer. 
    Le dataAdapter fonctionne avec un DataSet/DataTable.

    Le DataTable est une copie d'une table en mémoire.  dataAdapter.Fill est utilisé pour apporter les informations qui se trouvent dans la BD en mémoire (DataSet/DataTable). En effet dataAdapter.SelectCommand  sera exécuté.
    Apres modifier les informations dans le DataTable, on doit enregistrer les informations dans la BD.

    En exécutant dataAdapter.Update (DataTable),  pour chaque ligne dans le DataTable, on vérifie le type de modification   et on exécute la commande SQL qui se trouve dans DataAdapter.UpdateCommand, InsertCommand ou DeleteCommand selon le cas, pour la ligne.

    Pour faire le code plus facile à lire, après créer le DataAdapter, assurez-vous que les commandes pour Select/Insert/Update/Delete ont les bonnes valeurs et utilisez sans modifier ces propriétés de votre DataAdapter.
     Vous pouvez utiliser OleDbCommandBuilder http://msdn.microsoft.com/fr-fr/library/system.data.oledb.oledbcommandbuilder(v=vs.110).aspx
    Pour corriger l’erreur ci-dessus vous devez utiliser :
    dtAdapt_Joueur.SelectCommand  = new OleDbCommand(requete(1) , connection);

    Bien cordialement


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    • Marqué comme réponse Aurel Bera vendredi 18 avril 2014 06:08
    lundi 14 avril 2014 11:08
  • Merci pour votre car j'arrive désormais à mettre ma base de données à partir de mon dataset.

    Il me restait des erreurs car je mfermais ma connexion. A ce sujet, j'ai une question car je ne sais pas si je dois :

    ouvrir le aconnection, lancer la requete et fermer la connection pour chaque requete.

    ou

    ouvrir la connection à l'ouverture de mon programme, lance les requetes et femer la connection à la finn du programme.

    lundi 14 avril 2014 13:23
  • ouvrir la connection, lancer la requete et fermer la connection pour chaque requete.

    D'habitude je la préfère. Avec l'autre option pour chaque utilisateur qui a parti sans fermer l'application on aura une connexion ouverte. En plus c'est moins probable que le moteur DB ferme la connexion pendant l'exécution d'une requête qu'après un certain temps d'inactivité - ce qui nous fait penser à des mécanismes de vérification de l'état de connexion avant chaque exécution d’une commande.

    Bien cordialement,


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    lundi 14 avril 2014 13:38
  • Si j'ai bien compris, dans mon cas, je dois revoir les fonctions  OuvertureConnection(), LancerRequette() et FermetureConnection() dans mon module pour n'en faire qu'une seule?

    Lorsqu'on ferme une connexion, est ce que les variables liés à la connexion (dataAdaptater, CommandBuilder, ConnectionString...) sont détruites ?

    J'ai lu qu'il fallait utiliser les Try .... Catch  pour pour éviter les plantages du programme et gérer les erreurs. Savez-vous où et comment l'implanter?

    lundi 14 avril 2014 14:10
  • 1. Oui.

    2. Le Garbage Collector fait le nettoyage après une variable n'est plus utilisée. Un peu d'attention pour les objets définies comme IDisposable (Avec Dispose () on libère les ressources externes)

    3. Voir cet article:
    Meilleures pratiques pour la gestion des exceptions

    Je dirais de mettre le Fill dans un Try/Catch (Fill ne necessite une conexion ouverte, il l'ouvre tout seul et à la fin il la ferme si avant la connexion n'était pas ouverte).

    Aussi, je dirais de mettre l'appel d’Update dans un Try/Catch.

    Bien cordialement,


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    mardi 15 avril 2014 14:09