Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo articolo illustra come usare l'oggetto SqlDataAdapter
per aggiornare un database di 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 di 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 di 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 di SQL Server con modifiche ai dati eseguite su unDataSet
oggetto popolato con dati di una tabella nel database.
Questo articolo fa riferimento allo spazio dei nomi System::Data::SqlClient
della libreria di classi .NET Framework .
Proprietà e oggetti 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 oppure possono essere generati automaticamente usando l'oggetto SqlCommandBuilder
.
Il primo esempio di codice di 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 generazione automatica dei comandi e quindi illustra il processo tramite il quale è possibile creare e usare manualmente un SqlCommand
oggetto come UpdateCommand
proprietà di un SqlDataAdapter
oggetto .
Creare la tabella di esempio di SQL Server
Per creare una tabella di SQL Server di esempio da usare negli esempi di codice .NET di Visual C++ documentati in questo articolo, seguire questa procedura:
Aprire SQL Server Query Analyzer 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 inserire 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 usati per popolare un DataSet
oggetto si basa 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 SelectCommand
funzionamento della generazione automatica dei comandi. Lo schema della SelectCommand
tabella recuperato da determina la sintassi delle istruzioni , UPDATE
e DELETE
generate INSERT
automaticamente.
È inoltre necessario che SelectCommand
restituisca almeno una chiave primaria o una colonna univoca. In caso contrario, viene generata un'eccezione InvalidOperation
e i comandi non vengono generati.
Per creare un'applicazione console .NET visual C++ di esempio che illustra come usare l'oggetto per generare automaticamente le proprietà dell'oggetto SqlCommandBuilder
InsertCommand
, DeleteCommand
e UpdateCommand
SqlCommand per un SqlDataAdapter
oggetto , seguire questa procedura:
Avviare Visual Studio .NET e quindi creare una nuova applicazione C++ gestita. Denominarlo updateSQL.
Copiare e incollare il codice seguente in updateSQL.cpp (sostituendo il relativo 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 eseguire l'accesso.
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'esecuzione dell'istruzione , l'istruzione UPDATE
generata automaticamente UPDATE
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 assicurarsi 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 sui record e viene generata un'eccezione DBConcurrencyException
.
Se si vuole UPDATE
completare indipendentemente dai valori originali, sarà necessario impostare in modo esplicito per UpdateCommand
anziché DataAdapter
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 come indicato di seguito:
cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
Se il codice è già stato eseguito nella sezione dell'esempio di codice 1 di questo articolo, aprire la tabella CustTestin SQL Server e quindi modificare 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