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

Accès aux données Discussion :

Comment fait on un update d'une db avec une datatable modifié?


Sujet :

Accès aux données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mai 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 24
    Par défaut Comment fait on un update d'une db avec une datatable modifié?
    Bonjour,

    Je rempli ma datatable avec le contenu d'une table de ma database.
    Je modifie le contenu de la datatable et ensuite je fais l'update.
    Mon problème est que l update ne se fait pas si j ai supprimé des records dans la datatable.

    Voici une partie de mon code:

    cmd = GetDbCommand()
    dbAdap = GetDbDataAdapter()
    cmd = connectionDb.CreateCommand
    cmd.CommandType = CommandType.TableDirect
    cmd.CommandText = "SYS_HISTORY"

    dbAdap.SelectCommand = cmd
    dbAdap.Fill(dataT)

    dataT.Rows.Clear()

    dbAdap.Update(dataT)

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 764
    Par défaut
    1/ ne pas oublier les balises [CODE]

    2/ décrire l'erreur ("l'update ne se fait pas" : il y a une exception ? ou bien ça a l'air de marcher mais en fait il n'y a pas d'effet dans la base ?)

    3/ donner du code pertinent ? il n'y a aucun moyen ici de savoir ce qu'il y a dans le DataAdapter : quelle est cette fonction GetDbDataAdapter ?


    Déjà, si tu vides la DataTable avec Rows.Clear(), il est normal que rien ne se passe au moment de l'update : la table a été vidée, elle ne contient plus aucune ligne, il n'y a donc aucune ligne à mettre à jour.
    Il faut supprimer les lignes avec la méthode Delete() des objets DataRow : ainsi les lignes ne sont pas supprimées, elles restent dans la table mais dans l'état DataRowState.Deleted. Lors de l'update le DataAdapter peut repérer ces lignes, utiliser la commande DeleteCommand, et mettre à jour la base pour chacune de ces lignes.


    De plus :
    Je *pense* que GetDbDataAdapter est une fonction qui crée un DataAdapter "vide" (càd comme le constructeur sans arguments...) (mais je peux me tromper, c'est une intuition par rapport au code présenté ici)
    Dans ce cas la commande DeleteCommand du DataAdapter n'a pas été initialisée et donc l'update ne pourra de toutes façons pas marcher (d'ailleurs pour bien faire il faudrait également affecter les propriétés InsertCommand et UpdateCommand)

  3. #3
    Membre averti
    Inscrit en
    Mai 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 24
    Par défaut
    Le fait que j'utilise clear ou delete n'a aucun effet sur la table de la db.

    J'ai modifié le code pour l'update, cette fois-ci j ai une exception:

    Dynamic SQL generation for the DeleteCommand is not supported against a SelectCommand that does not return any key column information.

    Premier essai
    Voila mon code:

    Dim dbCommandBuilder As System.Data.Common.DbCommandBuilder = Nothing
    Dim dbAdap As Data.Common.DbDataAdapter
    Dim dataT As New DataTable
    Dim cmd As Data.Common.DbCommand
    Dim newRow As DataRow = Nothing

    dbAdap = GetDbDataAdapter()
    dbCommandBuilder = GetDbCommandBuilder(dbAdap)

    cmd = GetDbCommand()
    cmd = connectionDb.CreateCommand
    cmd.CommandType = CommandType.TableDirect
    cmd.CommandText = "SYS_HISTORY"

    dbAdap.SelectCommand = cmd

    dbAdap.Fill(dataT)
    dataT.Rows(0).Delete()

    newRow = dataT.NewRow

    newRow("fop_date") = "hello"
    dataT.Rows.Add(newRow)

    dbAdap.Update(dataT.Select(Nothing, Nothing, DataViewRowState.Deleted))
    dbAdap.Update(dataT.Select(Nothing, Nothing, DataViewRowState.ModifiedCurrent))
    dbAdap.Update(dataT.Select(Nothing, Nothing, DataViewRowState.Added))


    #Region "DB driver specific"

    Private Function GetDbCommand() As Data.Common.DbCommand
    Return New OleDb.OleDbCommand
    End Function

    Private Function GetDbCommand(ByVal aQuery As String, ByRef aConnection As OleDb.OleDbConnection) As Data.Common.DbCommand
    Return New OleDb.OleDbCommand(aQuery, aConnection)
    End Function

    Private Function GetDbConnection(ByVal aConnectionString As String) As Data.Common.DbConnection
    Return New OleDb.OleDbConnection(aConnectionString)
    End Function

    Private Function GetDbDataAdapter() As Data.Common.DataAdapter
    Return New OleDb.OleDbDataAdapter()
    End Function

    Private Function GetDbDataAdapter(ByRef aDbCommand As OleDb.OleDbCommand) As Data.Common.DataAdapter
    Return New OleDb.OleDbDataAdapter(aDbCommand)
    End Function

    Private Function GetDbCommandBuilder(ByVal dbDataAdapter As Data.Common.DbDataAdapter) As Data.Common.DbCommandBuilder
    Return New OleDb.OleDbCommandBuilder(dbDataAdapter)
    End Function

    Private Function GetDbCommandBuilder() As Data.Common.DbCommandBuilder
    Return New OleDb.OleDbCommandBuilder()
    End Function
    #End Region


    2ieme essai:


    Dim dbCommandBuilder As System.Data.Common.DbCommandBuilder = Nothing
    Dim dbAdap As Data.Common.DbDataAdapter
    Dim dataT As New DataTable
    Dim cmd As Data.Common.DbCommand
    Dim newRow As DataRow = Nothing

    dbAdap = GetDbDataAdapter()
    dbCommandBuilder = GetDbCommandBuilder(dbAdap)

    cmd = GetDbCommand()
    cmd = connectionDb.CreateCommand
    cmd.CommandType = CommandType.TableDirect
    cmd.CommandText = "SYS_HISTORY"

    dbAdap.SelectCommand = cmd


    -> dbAdap.DeleteCommand = dbCommandBuilder.GetDeleteCommand()
    dbAdap.InsertCommand = dbCommandBuilder.GetInsertCommand()
    dbAdap.UpdateCommand = dbCommandBuilder.GetUpdateCommand()

    dbAdap.Fill(dataT)
    dataT.Rows(0).Delete()

    newRow = dataT.NewRow

    newRow("fop_date") = "hello"
    dataT.Rows.Add(newRow)

    dbAdap.Update(dataT.Select(Nothing, Nothing, DataViewRowState.Deleted))
    dbAdap.Update(dataT.Select(Nothing, Nothing, DataViewRowState.ModifiedCurrent))
    dbAdap.Update(dataT.Select(Nothing, Nothing, DataViewRowState.Added))

    -> Produit cette exception:

    Dynamic SQL generation for the DeleteCommand is not supported against a SelectCommand that does not return any key column information.

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 764
    Par défaut
    GAAAAAAAH !!!

    les balises [code] stp !

  5. #5
    Membre averti
    Inscrit en
    Mai 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 24
    Par défaut
    Ok, le problème était tout simplement la table de la db. Elle n'a pas de Primary key.

    Welby

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 764
    Par défaut
    Dynamic SQL generation for the DeleteCommand is not supported against a SelectCommand that does not return any key column information.
    Ben voilà, elle est là la réponse : il faut une SelectCommand qui renvoie des infos sur les clés pour que le CommandBuilder puisse générer la DeleteCommand. Il faut donc croire que la commande de type CommandType.TableDirect ne renvoie pas les informations sur les clés de la table...

    Essaie un "SELECT * FROM SYS_HISTORY", je *pense* que ça devrait mieux marcher (mais je n'ai jamais utilisé de CommandBuilder, je ne suis pas sûre de leur fonctionnement).
    Et bien sûr, il faut que la table SYS_HISTORY ait bien une clé primaire. <== ah ben voilà c'était ça (edit après avoir vu le message précédent envoyé pendant la rédaction du mien...)

    (et *peut-être* qu'il faudra mettre la propriété MissingSchemaAction du DataAdapter à AddWithKey, mais essaie déjà sans la modifier pour voir)

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 13/04/2015, 11h17
  2. [XL-2002] Macro de comparaison d'une cellule d'une feuille avec une cellule d'une autre feuille.
    Par steelydan dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 08/09/2010, 12h59
  3. 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
  4. Insérer une légende dans une image avec une police plus petite
    Par Paulinho dans le forum Tableaux - Graphiques - Images - Flottants
    Réponses: 3
    Dernier message: 29/04/2006, 14h19
  5. [Regex]Match d'une regexp avec une chaîne avec caractères spéciaux
    Par gdawirs dans le forum Collection et Stream
    Réponses: 13
    Dernier message: 25/11/2005, 12h24

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