Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Artikel wird erläutert, wie Sie das SqlDataAdapter Objekt zum Aktualisieren einer SQL Server-Datenbank in Microsoft Visual C++ verwenden.
Ursprüngliche Produktversion: Visual C++
Ursprüngliche KB-Nummer: 308510
Zusammenfassung
Das SqlDataAdapter Objekt dient als Brücke zwischen einem ADO.NET-Objekt DataSet und einer SQL Server-Datenbank. Es handelt sich um ein zwischengeschaltetes Objekt, mit dem Sie folgendes ausführen können:
- Füllen Sie eine ADO.NET
DataSetmit Daten, die aus einer SQL Server-Datenbank abgerufen wurden. - Aktualisieren Sie die Datenbank so, dass sie die Änderungen (Einfügungen, Aktualisierungen, Löschungen) an den Daten mithilfe des
DataSet-Objekts widerspiegelt. Dieser Artikel enthält Visual C++-.NET-Codebeispiele, um zu veranschaulichen, wie dasSqlDataAdapter-Objekt verwendet werden kann, um eine SQL Server-Datenbank mit Datenänderungen zu aktualisieren, die auf einemDataSet-Objekt ausgeführt werden, das mit Tabellendaten der Datenbank gefüllt ist.
Dieser Artikel bezieht sich auf den .NET Framework-Klassenbibliotheksnamespace System::Data::SqlClient.
SqlDataAdapter-Objekt und -Eigenschaften
Die InsertCommand, UpdateCommand und DeleteCommand Eigenschaften des SqlDataAdapter Objekts werden verwendet, um die Datenbank mit den Datenänderungen zu aktualisieren, die an einem DataSet Objekt vorgenommen werden. Jede dieser Eigenschaften sind SqlCommand Objekte, die die entsprechenden INSERT, UPDATE und DELETE TSQL-Befehle angeben, mit denen die DataSet Änderungen an der Zieldatenbank übertragen werden. Die SqlCommand diesen Eigenschaften zugewiesenen Objekte können manuell im Code erstellt oder mithilfe des SqlCommandBuilder Objekts automatisch generiert werden.
Das erste Codebeispiel in diesem Artikel veranschaulicht, wie das SqlCommandBuilder Objekt verwendet werden kann, um die UpdateCommand Eigenschaft des SqlDataAdapter Objekts automatisch zu generieren. Im zweiten Beispiel wird ein Szenario verwendet, in dem die automatische Befehlsgenerierung nicht verwendet werden kann, und zeigt daher den Prozess, mit dem Sie ein SqlCommand Objekt manuell als UpdateCommand Eigenschaft eines SqlDataAdapter Objekts erstellen und verwenden können.
Erstellen der SQL Server-Beispieltabelle
Führen Sie die folgenden Schritte aus, um eine SQL Server-Beispieltabelle zu erstellen, die in den in diesem Artikel dokumentierten .NET-Codebeispielen von Visual C++ verwendet werden soll:
Öffnen Sie sql Server Query Analyzer, und stellen Sie dann eine Verbindung mit einer Datenbank her, in der Sie die Beispieltabelle erstellen möchten. In den Codebeispielen in diesem Artikel wird die Northwind-Datenbank verwendet, die im Lieferumfang von SQL Server enthalten ist.
Führen Sie die folgenden T-SQL-Anweisungen aus, um eine Beispieltabelle namens "CustTest" zu erstellen, und fügen Sie dann einen Datensatz in ihn ein.
Create Table CustTest ( CustID int primary key, CustName varchar(20) ) Insert into CustTest values(1,'John')
Codebeispiel 1: Automatisch generierte Befehle
Wenn die SELECT Anweisung zum Abrufen der Daten, die zum Auffüllen einer DataSet verwendet werden, auf einer einzelnen Datenbanktabelle basiert, können Sie das CommandBuilder Objekt nutzen, um die DeleteCommand, InsertCommand und UpdateCommand Eigenschaften des DataAdapter automatisch zu generieren. Dadurch wird der Code vereinfacht und reduziert, der zum Ausführen von INSERT-, UPDATE- und DELETE-Vorgängen erforderlich ist.
Als Mindestanforderung müssen Sie die SelectCommand-Eigenschaft festlegen, damit die automatische Befehlsgenerierung funktioniert. Das von der Tabelle SelectCommand abgerufene Tabellenschema bestimmt die Syntax der automatisch generierten INSERT, UPDATEund DELETE Anweisungen.
Der SelectCommand muss außerdem mindestens einen Primärschlüssel oder eine eindeutige Spalte zurückgeben. Falls kein Schlüssel bzw. keine Spalte vorhanden ist, wird anstelle der Befehle eine InvalidOperation-Ausnahme generiert.
Führen Sie die folgenden Schritte aus, um eine Visual C++-.NET-Konsolenanwendung zu erstellen, die veranschaulicht, wie das SqlCommandBuilder Objekt zum automatischen Generieren der InsertCommandDeleteCommandObjekteigenschaften und UpdateCommand sqlCommand-Objekteigenschaften für ein SqlDataAdapter Objekt verwendet wird:
Starten Sie Visual Studio .NET, und erstellen Sie dann eine neue verwaltete C++-Anwendung. Benennen Sie es updateSQL.
Kopieren Sie den folgenden Code, und fügen Sie ihn in updateSQL.cpp ein (ersetzen Sie den Standardinhalt):
#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; }Ändern Sie im code, den Sie in Schritt 2 kopiert und eingefügt haben, die Zeile des Verbindungszeichenfolgencodes so, dass eine ordnungsgemäße Verbindung mit Ihrem SQL Server-Computer hergestellt wird:
cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";Nachdem Sie diesen Code ausgeführt haben, können Sie eine Verbindung mit Ihrer SQL Server-Installation herstellen und sich dann anmelden.
Speichern und ausführen Sie die Anwendung. Ein Konsolenfenster wird geöffnet und zeigt die folgende Ausgabe an:
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 : Jack2Drücken Sie eine beliebige Taste, um das Konsolenfenster zu schließen und die Anwendung zu beenden.
Codebeispiel 2: Manuelles Erstellen und Initialisieren der UpdateCommand-Eigenschaft
Die vom Codebeispiel 1 generierte Ausgabe gibt an, dass die Logik zum automatischen Generieren von Befehlen für UPDATE Anweisungen auf optimistischer Parallelität basiert. Das heißt, Datensätze sind nicht für die Bearbeitung gesperrt und können jederzeit von anderen Benutzern oder Prozessen geändert werden. Da ein Datensatz möglicherweise geändert wurde, nachdem er von der SELECT Anweisung zurückgegeben wurde, aber bevor die UPDATE Anweisung ausgegeben wird, enthält die automatisch generierte UPDATE Anweisung eine WHERE Klausel, sodass eine Zeile nur aktualisiert wird, wenn sie alle ursprünglichen Werte enthält und nicht gelöscht wurde. Dies geschieht, um sicherzustellen, dass neue Daten nicht überschrieben werden. In Fällen, in denen ein automatisch generiertes Update versucht, eine Zeile zu aktualisieren, die gelöscht wurde oder nicht die ursprünglichen Werte enthält, die im DataSet gefunden wurden, hat der Befehl keine Auswirkungen auf Datensätze und DBConcurrencyException wird ausgelöst.
Wenn Sie möchten, dass der UPDATE unabhängig von den ursprünglichen Werten abgeschlossen wird, müssen Sie explizit den UpdateCommand für den DataAdapter festlegen und sich nicht auf die automatische Befehlsgenerierung verlassen.
Führen Sie die folgenden Schritte aus, um die UpdateCommand Eigenschaft des SqlDataAdapter im Codebeispiel 1 verwendeten Objekts manuell zu erstellen und zu initialisieren:
Kopieren Sie den folgenden Code (überschreiben sie den vorhandenen Code), und fügen Sie ihn in die
Main()Funktion in der UpdateSQL.cpp-Datei in der C++-Anwendung ein, die im Codebeispiel 1 erstellt wurde: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;Ändern Sie die Zeile des Verbindungszeichenfolgencodes im vorherigen Codebeispiel wie folgt:
cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";Wenn Sie den Code bereits im Codebeispiel 1 Abschnitt dieses Artikels ausgeführt haben, öffnen Sie Ihre CustTest-Tabellein SQL Server, und ändern Sie dann den CustName-Wert im ersten Datensatz wieder in John.
Speichern und ausführen Sie die Anwendung. Ein Konsolenfenster wird geöffnet und zeigt die folgende Ausgabe an:
Customer Name before Update : John Customer Name after Update : Jack2