2015-08-28 2 views
0

Je suis en train de METTRE À JOUR lignes de la table de base de données à l'aide SQLCommandBuilder avec des lignes DataTable en utilisant le code de test suivant. Une table avec une colonne de clé primaire et une datable pour la garder simple.SqlCommandBuilder - MISE À JOUR de DataTable que « ajoute » Base de données Tableau

En utilisant le code suivant, la table dbo.Dogs2 est « en annexe » avec les lignes DataTable - donc doubler le nombre de lignes plutôt que juste mettre à jour la ligne modifiée (s)

Si j'ajouter le code table.AcceptChanges() juste avant la Dim builder As New SqlCommandBuilder(adapter), la table de base de données dbo.Dogs2 reste inchangée.

Si j'ajoute le code table.AcceptChanges() juste avant le adapter.Update(table), la table de base de données dbo.Dogs2 reste inchangée.

Public Class Form1 

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 

     ' dbo.Dogs2 database table columns are exactly like datatable columns with exception of dog names 
     ' only UPDATING the "Name" field (no Inserts or deletes) 
     ' orginal dog names "Name" in Dogs2.dbo are Sharpy, Bully, Shep, Charlie, and Yorky 
     ' new dog names "Name" in Dogs2.dbo are June, Tucker, Maggie, Charles, and Candy 
     ' Dex_Row_Id is the primary key with Identity Increment set to 1 

     ' Create a DataTable with five columns. 
     ' 
     Dim table As New DataTable() 
     table.Columns.Add("Weight", GetType(Integer)) 
     table.Columns.Add("Name", GetType(String)) 
     table.Columns.Add("Breed", GetType(String)) 
     table.Columns.Add("Size", GetType(Char)) 
     table.Columns.Add("Date", GetType(DateTime)) 
     table.Columns.Add("Dex_Row_Id", GetType(Integer)) 
     ' 
     ' Add data to the DataTable 
     ' 
     AddDogRow(table, 57, "June", "Shar Pei") 
     AddDogRow(table, 130, "Tucker", "Bullmastiff") 
     AddDogRow(table, 92, "Maggie", "Anatolian Shepherd Dog") 
     AddDogRow(table, 25, "Charles", "Cavalier King Charles Spaniel") 
     AddDogRow(table, 7, "Candy", "Yorkshire Terrier") 

     ShowResult(table) 'displays datatable correctly (this is a DevExpress.com Reference/Extension) 
     ' 
     ' Create new SqlConnection, SqlDataAdapter, and builder. 
     ' 
     Dim cnString As String = "<<<SQLConnectionString>>>" 
     ' 
     Using cnSQL1 As New SqlConnection 
      cnSQL1.ConnectionString = cnString 

      Using adapter = New SqlDataAdapter("SELECT * FROM Dogs2", cnSQL1) 

       ShowResult(table) 'displays datatable 

       Dim builder As New SqlCommandBuilder(adapter) 
       adapter.UpdateCommand = builder.GetUpdateCommand() 
       builder.RefreshSchema() 

       Using New SqlCommandBuilder(adapter) 
        ' 
        ' Fill the DataAdapter with the values in the DataTable. 
        ' 
        adapter.Fill(table) 

        ShowResult(table) 'displays datatable + original table data 

        ' Open the connection to the SQL database. 
        ' 
        cnSQL1.Open() 

        ' Update the SQL database table with the values. 
        ' 
        adapter.Update(table) 

        ' dbo.Dogs2 now has 10 rows (the 5 rows from the dataset + the original 5 rows) 

       End Using 

      End Using 

     End Using 

    End Sub 

Répondre

0

Vous utilisez incorrectement l'adaptateur. Vous devez d'abord charger les lignes de la base de données, puis mettre à jour les lignes récupérées et enfin appeler la mise à jour.

' REMOVE THE CODE BEFORE THIS ' 
' Create new SqlConnection, SqlDataAdapter, and builder.' 

Dim cnString As String = "<<<SQLConnectionString>>>" 
Dim table = New DataTable() ' Leave it emtpy and without schema' 
Using cnSQL1 As New SqlConnection 
    cnSQL1.ConnectionString = cnString 
    Using adapter = New SqlDataAdapter("SELECT * FROM Dogs2", cnSQL1) 
     Dim builder As New SqlCommandBuilder(adapter) 
     adapter.UpdateCommand = builder.GetUpdateCommand() 
     ' no need of this -> builder.RefreshSchema()' 
     Using New SqlCommandBuilder(adapter) 
      adapter.Fill(table) 
      ShowResult(table) 'displays original table data' 

      ' no need of this -> cnSQL1.Open()' 
      ' NOW YOU COULD CHANGE THE ROWS, FOR EXAMPLE' 
      table.Rows(0)("Weight") = 99 

      ' Update the SQL database table with the values.' 
      adapter.Update(table) 
     End Using 
    End Using 
End Using 

Lorsque vous passez une table existante à la méthode de remplissage de l'adaptateur, l'enregistrement existant ne sont pas supprimés et donc votre table est remplie avec les données de la base de données et de votre création manuelle de la table (Bien sûr, la construire adaptateur pour vous les colonnes de la table. de plus, les lignes ajoutées manuellement à votre table sont marqués par la DataRowState.Added tandis que la ligne modifiée par votre code sera marqué avec le DataRowState.Changed. Cet état permet la commande de mise à jour pour décider de l'action à effectuer sur tous les ligne présente dans le tableau (bien sûr les lignes qui ne sont pas modifiées maintiennent l'initiale DataRowState.Unchanged

Enfin, calling AcceptChanges ne signifie pas que les lignes seront mises à jour sur la table de base de données. Seul le drapeau DataRowState est remis à la DataRowState.Unchanged

+0

Steve, je vous remercie pour les informations utiles. J'ai modifié mon code de test par réponse, et la table de base de données se met à jour correctement. – TCIslandTime

+0

Dans mon application du monde réel, je génère un DataTable via l'extension de feuille de calcul DevExpress.com dans VS2013. Donc, pour ce cas, j'ai mes données (datatable) à utiliser dans la mise à jour de la table de la base de données. En d'autres termes, mon datatable est rempli avant la ligne de code "Dim cnString As String = connectionString". Ai-je raison de supposer que la seule façon de réussir est d'utiliser des paramètres? – TCIslandTime

+0

Désolé mais ce n'est pas clair du tout. Si votre table a déjà des lignes sans utiliser un adaptateur pour le remplir et que vous voulez les modifier et écrire vos modifications, vous devez faire une boucle sur vos lignes, vérifier DataRowState pour chaque ligne et appliquer directement une commande UPDATE sans utiliser la méthode Fill. . Vous pouvez obtenir le UpdateCommand du constructeur et de l'utiliser en remplissant les paramètres requis – Steve