Actualización de una base de datos de SQL Server mediante el objeto SqlDataAdapter en Visual C++
En este artículo se presenta cómo usar el SqlDataAdapter
objeto para actualizar una base de datos de SQL Server en Microsoft Visual C++.
Versión original del producto: Visual C++
Número de KB original: 308510
Resumen
El SqlDataAdapter
objeto actúa como un puente entre un objeto ADO.NET DataSet
y una base de datos de SQL Server. Es un objeto intermedio que puede usar para hacer lo siguiente:
- Rellene un ADO.NET
DataSet
con los datos recuperados de una base de datos de SQL Server. - Actualice la base de datos para reflejar los cambios (inserciones, actualizaciones, eliminaciones) realizados en los datos mediante
DataSet
. En este artículo se proporcionan ejemplos de código .NET de Visual C++ para mostrar cómo se puede usar elSqlDataAdapter
objeto para actualizar una base de datos de SQL Server con modificaciones de datos ejecutadas en unDataSet
objeto que se rellena con datos de una tabla de la base de datos.
En este artículo se hace referencia al espacio de nombres System::Data::SqlClient
biblioteca de clases de .NET Framework .
Propiedades y objeto SqlDataAdapter
Las InsertCommand
propiedades , UpdateCommand
y DeleteCommand
del SqlDataAdapter
objeto se usan para actualizar la base de datos con las modificaciones de datos ejecutadas en un DataSet
objeto . Cada una de estas propiedades son SqlCommand
objetos que especifican los comandos , UPDATE
y DELETE
TSQL correspondientes INSERT
que se usan para publicar las DataSet
modificaciones en la base de datos de destino. Los SqlCommand
objetos asignados a estas propiedades se pueden crear manualmente en el código o se pueden generar automáticamente mediante el SqlCommandBuilder
objeto .
En el primer ejemplo de código de este artículo se muestra cómo se puede usar el SqlCommandBuilder
objeto para generar automáticamente la UpdateCommand
propiedad del SqlDataAdapter
objeto. El segundo ejemplo usa un escenario en el que no se puede usar la UpdateCommand
generación automática de comandos y, por tanto, muestra el proceso por el que se puede crear y usar manualmente un SqlCommand
objeto como propiedad de un SqlDataAdapter
objeto.
Creación de la tabla de SQL Server de ejemplo
Para crear una tabla de SQL Server de ejemplo que se usará en los ejemplos de código .NET de Visual C++ documentados en este artículo, siga estos pasos:
Abra SQL Server Analizador de consultas y, a continuación, conéctese a una base de datos en la que desea crear la tabla de ejemplo. Los ejemplos de código de este artículo usan la base de datos Northwind que incluye SQL Server.
Ejecute las siguientes instrucciones T-SQL para crear una tabla de ejemplo denominada CustTest y, a continuación, inserte un registro en ella.
Create Table CustTest ( CustID int primary key, CustName varchar(20) ) Insert into CustTest values(1,'John')
Ejemplo de código 1: comandos generados automáticamente
Si la SELECT
instrucción para recuperar los datos utilizados para rellenar un DataSet
se basa en una sola tabla de base de datos, puede aprovechar el CommandBuilder
objeto para generar automáticamente las DeleteCommand
propiedades , InsertCommand
y UpdateCommand
de DataAdapter
. Esto simplifica y reduce el código necesario para realizar INSERT
operaciones , UPDATE
y DELETE
.
Como requisito mínimo, debe establecer la propiedad para que funcione la SelectCommand
generación automática de comandos. El esquema de tabla recuperado por SelectCommand
determina la sintaxis de las instrucciones , UPDATE
y DELETE
generadas INSERT
automáticamente.
SelectCommand
También debe devolver al menos una clave principal o una columna única. Si no hay ninguno, se genera una InvalidOperation
excepción y no se generan los comandos.
Para crear una aplicación de consola de Visual C++ .NET de ejemplo que muestre cómo usar el SqlCommandBuilder
objeto para generar automáticamente las InsertCommand
propiedades de objeto , DeleteCommand
y UpdateCommand
SqlCommand para un SqlDataAdapter
objeto, siga estos pasos:
Inicie Visual Studio .NET y, a continuación, cree una nueva aplicación de C++ administrada. Asígnele el nombre updateSQL.
Copie y pegue el código siguiente en updateSQL.cpp (reemplazando su contenido predeterminado):
#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; }
En el código que copió y pegó en el paso 2, modifique la línea de código de cadena de conexión para conectarse correctamente al equipo SQL Server, como se indica a continuación:
cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
Después de ejecutar este código, puede conectarse con la instalación de SQL Server y, a continuación, iniciar sesión.
Guarde y ejecute la aplicación. Se abrirá una ventana de consola y se mostrará la siguiente salida:
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
Presione cualquier tecla para descartar la ventana de la consola y detener la aplicación.
Ejemplo de código 2: crear e inicializar manualmente la propiedad UpdateCommand
La salida generada por el ejemplo de código 1 indica que la lógica para generar comandos automáticamente para UPDATE
instrucciones se basa en la simultaneidad optimista. Es decir, los registros no están bloqueados para su edición y otros usuarios o procesos pueden modificarlos en cualquier momento. Dado que un registro puede haberse modificado después de que se devolvió de la SELECT
instrucción pero antes de que se emita la UPDATE
instrucción , la instrucción generada UPDATE
automáticamente contiene una WHERE
cláusula para que una fila se actualice solo si contiene todos los valores originales y no se ha eliminado. Esto se hace para asegurarse de que no se sobrescriben los nuevos datos. En los casos en los que una actualización generada automáticamente intenta actualizar una fila que se ha eliminado o no contiene los valores originales que se encuentran en , DataSet
el comando no afecta a ningún registro y se produce .DBConcurrencyException
Si desea que UPDATE
se complete independientemente de los valores originales, deberá establecer explícitamente para en lugar de depender de la UpdateCommand
DataAdapter
generación automática de comandos.
Para crear e inicializar manualmente la UpdateCommand
propiedad del SqlDataAdapter
objeto usado en el ejemplo de código 1, siga estos pasos:
Copie y pegue el código siguiente (sobrescribiendo el código existente) en la
Main()
función dentro del archivo UpdateSQL.cpp de la aplicación de C++ creada en el ejemplo de código 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;
Modifique la línea de código de cadena de conexión en el ejemplo de código anterior de la siguiente manera:
cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
Si ya ha ejecutado el código en la sección de ejemplo de código 1 de este artículo, abra la tabla CustTesten SQL Server y, a continuación, cambie el valor custName del primer registro a John.
Guarde y ejecute la aplicación. Se abrirá una ventana de consola y se mostrará la siguiente salida:
Customer Name before Update : John Customer Name after Update : Jack2
Comentarios
https://aka.ms/ContentUserFeedback.
Próximamente: A lo largo de 2024 iremos eliminando gradualmente GitHub Issues como mecanismo de comentarios sobre el contenido y lo sustituiremos por un nuevo sistema de comentarios. Para más información, vea:Enviar y ver comentarios de