Een SQL Server-database bijwerken met behulp van het object SqlDataAdapter in Visual C++

In dit artikel wordt uitgelegd hoe u het SqlDataAdapter object gebruikt om een SQL Server-database bij te werken in Microsoft Visual C++.

Oorspronkelijke productversie: Visual C++
Origineel KB-nummer: 308510

Samenvatting

Het SqlDataAdapter object fungeert als een brug tussen een ADO.NET-object DataSet en een SQL Server-database. Het is een tussenliggend object dat u kunt gebruiken om het volgende te doen:

  • Vul een ADO.NET DataSet met gegevens die zijn opgehaald uit een SQL Server-database.
  • Werk de database bij om de wijzigingen (invoegen, updates, verwijderingen) in de gegevens weer te geven met behulp van de DataSet. Dit artikel bevat Visual C++ .NET-codevoorbeelden om te laten zien hoe het SqlDataAdapter object kan worden gebruikt om een SQL Server-database bij te werken met gegevenswijzigingen die worden uitgevoerd op een DataSet object dat is gevuld met gegevens uit een tabel in de database.

Dit artikel verwijst naar de naamruimte System::Data::SqlClient.NET Framework Class Library .

SqlDataAdapter-object en -eigenschappen

De InsertCommandeigenschappen , UpdateCommanden DeleteCommand van het SqlDataAdapter object worden gebruikt om de database bij te werken met de gegevenswijzigingen die zijn uitgevoerd op een DataSet object. Elk van deze eigenschappen zijn SqlCommand objecten die de respectieve INSERT, UPDATEen DELETE TSQL-opdrachten opgeven die worden gebruikt om de DataSet wijzigingen in de doeldatabase te posten. De SqlCommand objecten die aan deze eigenschappen zijn toegewezen, kunnen handmatig in code worden gemaakt of automatisch worden gegenereerd met behulp van het SqlCommandBuilder object.

Het eerste codevoorbeeld in dit artikel laat zien hoe het SqlCommandBuilder object kan worden gebruikt om automatisch de UpdateCommand eigenschap van het SqlDataAdapter object te genereren. In het tweede voorbeeld wordt gebruikgemaakt van een scenario waarin het automatisch genereren van opdrachten niet kan worden gebruikt en wordt daarom het proces gedemonstreerd waarmee u handmatig een SqlCommand object kunt maken en gebruiken als de UpdateCommand eigenschap van een SqlDataAdapter object.

De voorbeeldtabel SQL Server maken

Voer de volgende stappen uit om een voorbeeld SQL Server tabel te maken voor gebruik in de Visual C++ .NET-codevoorbeelden die in dit artikel worden beschreven:

  1. Open SQL Server Query Analyzer en maak vervolgens verbinding met een database waarin u de voorbeeldtabel wilt maken. De codevoorbeelden in dit artikel maken gebruik van de Northwind-database die wordt geleverd met SQL Server.

  2. Voer de volgende T-SQL-instructies uit om een voorbeeldtabel met de naam CustTest te maken en voeg er vervolgens een record in in.

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

Codevoorbeeld 1: Automatisch gegenereerde opdrachten

Als de SELECT instructie voor het ophalen van de gegevens die worden gebruikt voor het vullen van een DataSet is gebaseerd op één databasetabel, kunt u gebruikmaken van het CommandBuilder -object om automatisch de DeleteCommandeigenschappen , InsertCommanden UpdateCommand van de DataAdapterte genereren. Dit vereenvoudigt en vermindert de code die nodig is om , UPDATEen-bewerkingen DELETE uit te voerenINSERT.

Als minimale vereiste moet u de SelectCommand eigenschap instellen voor het automatisch genereren van opdrachten. Het tabelschema dat wordt opgehaald door de SelectCommand bepaalt de syntaxis van de automatisch gegenereerde INSERTinstructies , UPDATEen DELETE .

De SelectCommand moet ook ten minste één primaire sleutel of unieke kolom retourneren. Als er geen aanwezig is, wordt er een InvalidOperation uitzondering gegenereerd en worden de opdrachten niet gegenereerd.

Voer de volgende stappen uit om een Visual C++ .NET-consoletoepassing te maken die laat zien hoe u het SqlCommandBuilder object gebruikt om automatisch de InsertCommandobjecteigenschappen , DeleteCommanden UpdateCommand SqlCommand voor een SqlDataAdapter object te genereren:

  1. Start Visual Studio .NET en maak vervolgens een nieuwe beheerde C++-toepassing. Geef het de naam updateSQL.

  2. Kopieer en plak de volgende code in updateSQL.cpp (de standaardinhoud wordt vervangen):

    #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. Wijzig in de code die u in stap 2 hebt gekopieerd en geplakt de regel verbindingsreekscode om op de juiste manier verbinding te maken met uw SQL Server computer, als volgt:

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

    Nadat u deze code hebt uitgevoerd, kunt u verbinding maken met uw SQL Server installatie en u vervolgens aanmelden.

  4. Sla de toepassing op en voer deze uit. Er wordt een consolevenster geopend en de volgende uitvoer weergegeven:

    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. Druk op een willekeurige toets om het consolevenster te sluiten en de toepassing te stoppen.

Codevoorbeeld 2: de eigenschap UpdateCommand handmatig maken en initialiseren

De uitvoer die wordt gegenereerd door codevoorbeeld 1 geeft aan dat de logica voor het automatisch genereren van opdrachten voor UPDATE -instructies is gebaseerd op optimistische gelijktijdigheid. Dat wil dus dat records niet zijn vergrendeld voor bewerking en op elk gewenst moment kunnen worden gewijzigd door andere gebruikers of processen. Omdat een record mogelijk is gewijzigd nadat deze is geretourneerd vanuit de SELECT instructie, maar voordat de UPDATE instructie wordt uitgegeven, bevat de automatisch gegenereerde UPDATE instructie een WHERE component, zodat een rij alleen wordt bijgewerkt als deze alle oorspronkelijke waarden bevat en niet is verwijderd. Dit wordt gedaan om ervoor te zorgen dat nieuwe gegevens niet worden overschreven. In gevallen waarin een automatisch gegenereerde update probeert een rij bij te werken die is verwijderd of die niet de oorspronkelijke waarden bevat die zijn gevonden in de DataSet, heeft de opdracht geen invloed op records en wordt er een DBConcurrencyException gegenereerd.

Als u wilt dat de UPDATE wordt voltooid ongeacht de oorspronkelijke waarden, moet u expliciet de UpdateCommand instellen voor de DataAdapter in plaats van te vertrouwen op automatisch genereren van opdrachten.

Voer de volgende stappen uit om de UpdateCommand eigenschap van het SqlDataAdapter object dat wordt gebruikt in codevoorbeeld 1 handmatig te maken en te initialiseren:

  1. Kopieer en plak de volgende code (de bestaande code overschrijft) in de Main() functie in het UpdateSQL.cpp-bestand in de C++-toepassing die is gemaakt in het codevoorbeeld 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. Wijzig de regel verbindingsreekscode in het voorgaande codevoorbeeld als volgt:

    cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
    
  3. Als u de code al hebt uitgevoerd in de sectie codevoorbeeld 1 van dit artikel, opent u de tabel CustTestin SQL Server en wijzigt u vervolgens de custName-waarde in de eerste record weer in John.

  4. Sla de toepassing op en voer deze uit. Er wordt een consolevenster geopend en de volgende uitvoer weergegeven:

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