Partager via


Mettre à jour une base de données SQL Server à l’aide de l’objet SqlDataAdapter dans Visual C++

Cet article explique comment utiliser l’objet SqlDataAdapter pour mettre à jour une base de données SQL Server dans Microsoft Visual C++.

Version du produit d’origine : Visual C++
Numéro de la base de connaissances d’origine : 308510

Résumé

L’objet SqlDataAdapter sert de pont entre un objet ADO.NET DataSet et une base de données SQL Server. Il s’agit d’un objet intermédiaire que vous pouvez utiliser pour effectuer les opérations suivantes :

  • Remplissez un ADO.NET DataSet avec les données récupérées à partir d’une base de données SQL Server.
  • Mettez à jour la base de données pour refléter les modifications (insertions, mises à jour, suppressions) apportées aux données à l’aide du DataSet. Cet article fournit des exemples de code .NET Visual C++ pour montrer comment l’objet SqlDataAdapter peut être utilisé pour mettre à jour une base de données SQL Server avec des modifications de données exécutées sur un DataSet objet rempli avec des données d’une table de la base de données.

Cet article fait référence à l’espace de noms de la Bibliothèque de classes .NET Framework System::Data::SqlClient.

Objet et propriétés SqlDataAdapter

Les propriétés InsertCommand, UpdateCommand et DeleteCommand de l'objet SqlDataAdapter sont utilisées pour mettre à jour la base de données avec les modifications de données exécutées sur un objet DataSet. Chacune de ces propriétés est un objet SqlCommand qui spécifie les commandes respectives INSERT, UPDATE, et DELETE TSQL utilisées pour publier les DataSet modifications apportées à la base de données cible. Les SqlCommand objets affectés à ces propriétés peuvent être créés manuellement dans le code, ou peuvent être générés automatiquement à l’aide de l’objet SqlCommandBuilder .

Le premier exemple de code de cet article montre comment l’objet SqlCommandBuilder peut être utilisé pour générer automatiquement la UpdateCommand propriété de l’objet SqlDataAdapter . Le deuxième exemple utilise un scénario dans lequel la génération automatique de commandes ne peut pas être utilisée, et montre donc le processus par lequel vous pouvez créer et utiliser manuellement un SqlCommand objet comme UpdateCommand propriété d’un SqlDataAdapter objet.

Créer l’exemple de table SQL Server

Pour créer un exemple de table SQL Server à utiliser dans les exemples de code .NET Visual C++ documentés dans cet article, procédez comme suit :

  1. Ouvrez SQL Server Query Analyzer, puis connectez-vous à une base de données dans laquelle vous souhaitez créer l’exemple de table. Les exemples de code de cet article utilisent la base de données Northwind fournie avec SQL Server.

  2. Exécutez les instructions T-SQL suivantes pour créer un exemple de table appelé CustTest, puis insérez un enregistrement dans celui-ci.

    Create Table CustTest
    (
        CustID int primary key,
        CustName varchar(20)
    )
    Insert into CustTest values(1,'John')
    

Exemple de code 1 : Commandes générées automatiquement

Si l’instruction SELECT permettant de récupérer les données utilisées pour remplir une DataSet table de base de données est basée sur une table de base de données unique, vous pouvez tirer parti de l’objet CommandBuilder pour générer automatiquement les propriétés et DeleteCommand les InsertCommandUpdateCommandpropriétés de l’objet DataAdapter. Cela simplifie et réduit le code requis pour effectuer INSERT, UPDATEet DELETE les opérations.

Pour que la génération automatique de commandes fonctionne, vous devez au minimum définir la propriété SelectCommand. Le schéma de table récupéré par SelectCommand détermine la syntaxe des instructions INSERT, UPDATE et DELETE générées automatiquement.

SelectCommand doit aussi retourner au moins une clé primaire ou une colonne unique. Si aucun n’est présent, une exception InvalidOperation est générée et les commandes ne sont pas générées.

Pour créer un exemple d'application console Visual C++ .NET qui montre comment utiliser l'objet SqlCommandBuilder pour générer automatiquement les propriétés InsertCommand, DeleteCommand et UpdateCommand SqlCommand pour un objet SqlDataAdapter, procédez comme suit :

  1. Démarrez Visual Studio .NET, puis créez une application C++ managée. Nommez-le updateSQL.

  2. Copiez et collez le code suivant dans updateSQL.cpp (en remplaçant son contenu par défaut) :

    #include "stdafx.h"
    
    #using < mscorlib.dll>
    #using < System.dll>
    #using < System.Data.dll>
    #using < System.Xml.dll>
    
    using namespace System;
    using namespace System::Data;
    using namespace System::Data::SqlClient;
    
    #ifdef _UNICODE
        int wmain(void)
    #else
        int main(void)
    #endif
    {
        SqlConnection *cn = new SqlConnection();
        DataSet *CustomersDataSet = new DataSet();
        SqlDataAdapter *da;
        SqlCommandBuilder *cmdBuilder;
    
        //Set the connection string of the SqlConnection object to connect
        //to the SQL Server database in which you created the sample
        //table in Section 1.0
        cn->ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
        cn->Open();
    
        //Initialize the SqlDataAdapter object by specifying a Select command
        //that retrieves data from the sample table
        da = new SqlDataAdapter("select * from CustTest order by CustId", cn);
    
        //Initialize the SqlCommandBuilder object to automatically generate and initialize
        //the UpdateCommand, InsertCommand and DeleteCommand properties of the SqlDataAdapter
        cmdBuilder = new SqlCommandBuilder(da);
    
        //Populate the DataSet by executing the Fill method of the SqlDataAdapter
        da->Fill(CustomersDataSet, "Customers");
    
        //Display the Update, Insert and Delete commands that were automatically generated
        //by the SqlCommandBuilder object
        Console::WriteLine("Update command Generated by the Command Builder : ");
        Console::WriteLine("==================================================");
        Console::WriteLine(cmdBuilder->GetUpdateCommand()->CommandText);
        Console::WriteLine(" ");
        Console::WriteLine("Insert command Generated by the Command Builder : ");
        Console::WriteLine("==================================================");
        Console::WriteLine(cmdBuilder->GetInsertCommand()->CommandText);
        Console::WriteLine(" ");
        Console::WriteLine("Delete command Generated by the Command Builder : ");
        Console::WriteLine("==================================================");
        Console::WriteLine(cmdBuilder->GetDeleteCommand()->CommandText);
        Console::WriteLine(" ");
    
        //Write out the value in the CustName field before updating the data using the DataSet
        DataRow *rowCust = CustomersDataSet->Tables->Item["Customers"]->Rows->Item[0];
        Console::WriteLine("Customer Name before Update : {0} ", rowCust->Item["CustName"]);
    
        //Modify the value of the CustName field
        String *newStrVal = new String("Jack");
        rowCust->set_Item("CustName", newStrVal);
    
        //Modify the value of the CustName field again
        String *newStrVal2 = new String("Jack2");
        rowCust->set_Item("CustName", newStrVal2);
    
        //Post the data modification to the database
        da->Update(CustomersDataSet, "Customers");
    
        Console::WriteLine("Customer Name after Update : {0} ", rowCust->Item["CustName"]);
    
        //Close the database connection
        cn->Close();
    
        //Pause
        Console::ReadLine();
        return 0;
    }
    
  3. Dans le code que vous avez copié et collé à l’étape 2, modifiez la ligne de code de chaîne de connexion pour vous connecter correctement à votre ordinateur SQL Server, comme suit :

    cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
    

    Après avoir exécuté ce code, vous pouvez vous connecter à votre installation de SQL Server, puis vous connecter.

  4. Enregistrez et exécutez l’application. Une fenêtre de console s’ouvre et affiche la sortie suivante :

    Update command generated by the Command Builder:
    ==================================================
    UPDATE CustTest SET CustID = @p1 , CustName = @p2 WHERE ( (CustID = @p3)
    AND ((CustName IS NULL AND @p4 IS NULL)
    OR (CustName = @p5)))
    Insert command generated by the Command Builder :
    ==================================================
    INSERT INTO CustTest( CustID , CustName ) VALUES ( @p1 , @p2 )
    Delete command generated by the Command Builder :
    ==================================================
    DELETE FROM CustTest WHERE ( (CustID = @p1)
    AND ((CustName IS NULL AND @p2 IS NULL)
    OR (CustName = @p3)))
    Customer Name before Update : John
    Customer Name after Update : Jack2
    
  5. Appuyez sur n’importe quelle touche pour ignorer la fenêtre de console et arrêter l’application.

Exemple de code 2 : Créer et initialiser manuellement la propriété UpdateCommand

La sortie générée par l’exemple de code 1 indique que la logique permettant de générer automatiquement des commandes pour les instructions est basée sur l'optimisme de la concurrence . Autrement dit, les enregistrements ne sont pas verrouillés pour modification et peuvent être modifiés par d’autres utilisateurs ou processus à tout moment. Étant donné qu’un enregistrement a peut-être été modifié après son retour à partir de l’instruction SELECT , mais avant l’émission de l’instruction, l’instruction UPDATE générée automatiquement UPDATE contient une WHERE clause afin qu’une ligne soit mise à jour uniquement si elle contient toutes les valeurs d’origine et n’a pas été supprimée. Cela permet de s’assurer que les nouvelles données ne sont pas remplacées. Dans les cas où une mise à jour générée automatiquement tente de mettre à jour une ligne qui a été supprimée ou ne contient pas les valeurs d'origine trouvées dans le DataSet, la commande ne touche aucun enregistrement et une DBConcurrencyException exception est levée.

Si vous souhaitez que le UPDATE se termine indépendamment des valeurs d'origine, vous devez définir explicitement la UpdateCommand plutôt que de vous appuyer sur la génération de commandes automatique pour le DataAdapter.

Pour créer et initialiser manuellement la UpdateCommand propriété de l’objet SqlDataAdapter utilisé dans l’exemple de code 1, procédez comme suit :

  1. Copiez et collez le code suivant (en remplaçant le code existant) dans la fonction dans le Main() fichier UpdateSQL.cpp dans l’application C++ créée dans l’exemple de code 1 :

    SqlConnection *cn = new SqlConnection();
    DataSet *CustomersDataSet = new DataSet();
    SqlDataAdapter *da;
    SqlCommand *DAUpdateCmd;
    cn->ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
    cn->Open();
    da = new SqlDataAdapter("select * from CustTest order by CustId", cn);
    
    //Initialize the SqlCommand object that will be used as the DataAdapter's UpdateCommand
    //Notice that the WHERE clause uses only the CustId field to locate the record to be updated
    DAUpdateCmd = new SqlCommand("Update CustTest set CustName = @pCustName where CustId = @pCustId"
    , da->SelectCommand->Connection);
    
    //Create and append the parameters for the Update command
    DAUpdateCmd->Parameters->Add(new SqlParameter("@pCustName", SqlDbType::VarChar));
    DAUpdateCmd->Parameters->Item["@pCustName"]->SourceVersion = DataRowVersion::Current;
    DAUpdateCmd->Parameters->Item["@pCustName"]->SourceColumn = "CustName";
    
    DAUpdateCmd->Parameters->Add(new SqlParameter("@pCustId", SqlDbType::Int));
    DAUpdateCmd->Parameters->Item["@pCustId"]->SourceVersion = DataRowVersion::Original;
    DAUpdateCmd->Parameters->Item["@pCustId"]->SourceColumn = "CustId";
    
    //Assign the SqlCommand to the UpdateCommand property of the SqlDataAdapter
    da->UpdateCommand = DAUpdateCmd;
    da->Fill(CustomersDataSet, "Customers");
    
    DataRow *rowCust = CustomersDataSet->Tables->Item["Customers"]->Rows->Item[0];
    Console::WriteLine("Customer Name before Update : {0} ", rowCust->Item["CustName"]);
    
    //Modify the value of the CustName field
    String *newStrVal = new String("Jack");
    rowCust->set_Item("CustName", newStrVal);
    
    //Modify the value of the CustName field again
    String *newStrVal2 = new String("Jack2");
    rowCust->set_Item("CustName", newStrVal2);
    
    da->Update(CustomersDataSet, "Customers");
    Console::WriteLine("Customer Name after Update : {0} ", rowCust->Item["CustName"]);
    cn->Close();
    Console::ReadLine();
    return 0;
    
  2. Modifiez la ligne de code de chaîne de connexion dans l’exemple de code précédent comme suit :

    cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
    
  3. Si vous avez déjà exécuté le code dans l’exemple de code 1 de cet article, ouvrez votre table CustTestdans SQL Server, puis remplacez la valeur CustName dans le premier enregistrement par John.

  4. Enregistrez et exécutez l’application. Une fenêtre de console s’ouvre et affiche la sortie suivante :

    Customer Name before Update : John
    Customer Name after Update : Jack2