Aggiornare un database SQL Server usando l'oggetto SqlDataAdapter in Visual C++
Questo articolo illustra come usare l'oggetto SqlDataAdapter
per aggiornare un database SQL Server in Microsoft Visual C++.
Versione originale del prodotto: Visual C++
Numero KB originale: 308510
Riepilogo
L'oggetto SqlDataAdapter
funge da ponte tra un oggetto ADO.NET DataSet
e un database SQL Server. Si tratta di un oggetto intermedio che è possibile usare per eseguire le operazioni seguenti:
- Popolare un ADO.NET
DataSet
con i dati recuperati da un database SQL Server. - Aggiornare il database in modo che rifletta le modifiche (inserimenti, aggiornamenti, eliminazioni) apportate ai dati tramite
DataSet
. Questo articolo fornisce esempi di codice .NET di Visual C++ per illustrare come usare l'oggettoSqlDataAdapter
per aggiornare un database SQL Server con modifiche ai dati eseguite su unDataSet
oggetto popolato con dati da una tabella nel database.
Questo articolo fa riferimento allo spazio dei nomi System::Data::SqlClient
della libreria di classi .NET Framework.
Proprietà e oggetto SqlDataAdapter
Le InsertCommand
proprietà , UpdateCommand
e DeleteCommand
dell'oggetto SqlDataAdapter
vengono utilizzate per aggiornare il database con le modifiche ai dati eseguite su un DataSet
oggetto . Ognuna di queste proprietà è SqlCommand
costituita da oggetti che specificano i rispettivi INSERT
comandi , UPDATE
e DELETE
TSQL usati per pubblicare le DataSet
modifiche al database di destinazione. Gli SqlCommand
oggetti assegnati a queste proprietà possono essere creati manualmente nel codice o generati automaticamente tramite l'oggetto SqlCommandBuilder
.
Il primo esempio di codice in questo articolo illustra come usare l'oggetto SqlCommandBuilder
per generare automaticamente la UpdateCommand
proprietà dell'oggetto SqlDataAdapter
. Il secondo esempio usa uno scenario in cui non è possibile usare la UpdateCommand
generazione automatica di comandi e quindi illustra il processo tramite il quale è possibile creare e usare manualmente un SqlCommand
oggetto come proprietà di un SqlDataAdapter
oggetto.
Creare la tabella di SQL Server di esempio
Per creare una tabella SQL Server di esempio da usare negli esempi di codice .NET di Visual C++ documentati in questo articolo, seguire questa procedura:
Aprire SQL Server Analizzatore query e quindi connettersi a un database in cui si vuole creare la tabella di esempio. Gli esempi di codice in questo articolo usano il database Northwind fornito con SQL Server.
Eseguire le istruzioni T-SQL seguenti per creare una tabella di esempio denominata CustTest e quindi inserirvi un record.
Create Table CustTest ( CustID int primary key, CustName varchar(20) ) Insert into CustTest values(1,'John')
Esempio di codice 1: Comandi generati automaticamente
Se l'istruzione SELECT
per recuperare i dati utilizzati per popolare un DataSet
oggetto è basata su una singola tabella di database, è possibile sfruttare l'oggetto CommandBuilder
per generare automaticamente le DeleteCommand
proprietà , InsertCommand
e UpdateCommand
di DataAdapter
. Ciò semplifica e riduce il codice necessario per eseguire INSERT
operazioni , UPDATE
e DELETE
.
Come requisito minimo, è necessario impostare la proprietà per il funzionamento della SelectCommand
generazione automatica dei comandi. Lo schema di tabella recuperato da SelectCommand
determina la sintassi delle istruzioni , UPDATE
e DELETE
generate INSERT
automaticamente.
Deve SelectCommand
inoltre restituire almeno una chiave primaria o una colonna univoca. Se non è presente, viene generata un'eccezione InvalidOperation
e i comandi non vengono generati.
Per creare un'applicazione console di Visual C++ .NET di esempio che illustra come usare l'oggetto SqlCommandBuilder
per generare automaticamente le proprietà dell'oggetto InsertCommand
, DeleteCommand
e UpdateCommand
SqlCommand per un SqlDataAdapter
oggetto, seguire questa procedura:
Avviare Visual Studio .NET e quindi creare una nuova applicazione C++ gestita. Assegnare il nome updateSQL.
Copiare e incollare il codice seguente in updateSQL.cpp (sostituendone il contenuto predefinito):
#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; }
Nel codice copiato e incollato nel passaggio 2 modificare la riga di codice stringa di connessione per connettersi correttamente al computer SQL Server, come indicato di seguito:
cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
Dopo aver eseguito questo codice, è possibile connettersi all'installazione di SQL Server e quindi accedere.
Salvare ed eseguire l'applicazione. Verrà aperta una finestra della console e verrà visualizzato l'output seguente:
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
Premere un tasto qualsiasi per chiudere la finestra della console e arrestare l'applicazione.
Esempio di codice 2: Creare e inizializzare manualmente la proprietà UpdateCommand
L'output generato dall'esempio di codice 1 indica che la logica per la generazione automatica dei comandi per UPDATE
le istruzioni è basata sulla concorrenza ottimistica. Ovvero, i record non sono bloccati per la modifica e possono essere modificati da altri utenti o processi in qualsiasi momento. Poiché un record può essere stato modificato dopo che è stato restituito dall'istruzione SELECT
ma prima dell'istruzione , l'istruzione UPDATE
generata UPDATE
automaticamente contiene una WHERE
clausola in modo che una riga venga aggiornata solo se contiene tutti i valori originali e non è stata eliminata. Questa operazione viene eseguita per garantire che i nuovi dati non vengano sovrascritti. Nei casi in cui un aggiornamento generato automaticamente tenta di aggiornare una riga che è stata eliminata o non contiene i valori originali trovati in DataSet
, il comando non influisce su alcun record e viene generato un DBConcurrencyException
oggetto .
Se si vuole che l'oggetto UPDATE
venga completato indipendentemente dai valori originali, è necessario impostare UpdateCommand
in modo esplicito per DataAdapter
anziché basarsi sulla generazione automatica dei comandi.
Per creare e inizializzare manualmente la UpdateCommand
proprietà dell'oggetto SqlDataAdapter
usato nell'esempio di codice 1, seguire questa procedura:
Copiare e incollare il codice seguente (sovrascrivendo il codice esistente) nella
Main()
funzione all'interno del file UpdateSQL.cpp nell'applicazione C++ creata nell'esempio di codice 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;
Modificare la riga di codice stringa di connessione nell'esempio di codice precedente nel modo seguente:
cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
Se il codice è già stato eseguito nella sezione 1 dell'esempio di codice di questo articolo, aprire la tabella CustTestin SQL Server e quindi modificare di nuovo il valore CustName nel primo record in John.
Salvare ed eseguire l'applicazione. Verrà aperta una finestra della console e verrà visualizzato l'output seguente:
Customer Name before Update : John Customer Name after Update : Jack2
Commenti e suggerimenti
https://aka.ms/ContentUserFeedback.
Presto disponibile: nel corso del 2024 verranno dismessi i problemi di GitHub come meccanismo di feedback per il contenuto e verranno sostituiti con un nuovo sistema di feedback. Per altre informazioni, vedere:Invia e visualizza il feedback per