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 hetSqlDataAdapter
object kan worden gebruikt om een SQL Server-database bij te werken met gegevenswijzigingen die worden uitgevoerd op eenDataSet
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 InsertCommand
eigenschappen , UpdateCommand
en 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
, UPDATE
en 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:
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.
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 DeleteCommand
eigenschappen , InsertCommand
en UpdateCommand
van de DataAdapter
te genereren. Dit vereenvoudigt en vermindert de code die nodig is om , UPDATE
en-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 INSERT
instructies , UPDATE
en 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 InsertCommand
objecteigenschappen , DeleteCommand
en UpdateCommand
SqlCommand voor een SqlDataAdapter
object te genereren:
Start Visual Studio .NET en maak vervolgens een nieuwe beheerde C++-toepassing. Geef het de naam updateSQL.
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; }
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.
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
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:
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;
Wijzig de regel verbindingsreekscode in het voorgaande codevoorbeeld als volgt:
cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
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.
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
Feedback
https://aka.ms/ContentUserFeedback.
Binnenkort beschikbaar: In de loop van 2024 zullen we GitHub-problemen geleidelijk uitfaseren als het feedbackmechanisme voor inhoud en deze vervangen door een nieuw feedbacksysteem. Zie voor meer informatie:Feedback verzenden en weergeven voor