Los comandos son clases que nos peromiten establecer y ejecutar instrucciones sobre las bases de datos, el Framework 2.0 nos ofrece una interfaz llamada IDBCommand que es implementada por las clases SqlCommand, OleDbCommand, OdbcCommand y OracleCommand, ademas existe una clase base con la implementacion de dicha interfaz llamada DBCommand que sirve como clase base para ser heredada por los proveedores de datos los cuales los llamaremos XxxCommand.
Ejemplo de un command
string conStr;
conStr = "Data Source=localhost;";
conStr += "Initial Catalog=AdventureWorks;";
conStr += "Integrated Security=true";
string cmdStr;
cmdStr = "SELECT ContactID, LastName, ";
cmdStr += "FirstName, ModifiedDate ";
cmdStr += "FROM Person.Contact";
SqlConnection cn = new SqlConnection();
cn.ConnectionString = conStr;
SqlCommand cmd = new SqlCommand();
cmd.Connection = cn;
cmd.CommandText = cmdStr;
Algunas de las caracteristicas de los comandos son:
Propiedades
CommandText: Indica la sentencia SQL o nombres de un objeto de la base de dato.
Conection: Indica la conexion asignada al comando.
CommandType: Indicar el tipo de comando a utilizar, este es una enumeracion que contiene los siguiente valores:
Text: Es la opcion por defecto. Es necesario que la propiedad CommandText contenga una sentencia SQL valida.
StoreProcedure: Permite utilizar el comando para ejecutar un procedimiento almacenado. La propiedad CommandText deberia tener asignado solamente el nombre del procedimiento.
TableDirect: Cuando necesitamos traer todas las filas y todas las columnas de una tabla o una vista, debemos usar este tipo de comando, asignado a la propiedad CommandText el nombre de la tabla o vista requerida.
Metodos
ExecuteReader: Permite construir un DataReader;
DataReaders
ADO.NET posee una clase que optimiza el acceso a los datos a través de diferentes clases llamados DataReaders, estos son utiles cuando se necesita obtener datos de la base de datos y estos no serán modificados, es decir, que los mismos van a ser de solo lectura.
Ejemplo de un DataReader
string conStr;
conStr = "Data Source=localhost;";
conStr += "Initial Catalog=AdventureWorks;";
conStr += "Integrated Security=true";
string cmdStr;
cmdStr = "SELECT top 10 ContactID as Id, ";
cmdStr += "LastName + ', ' + FirstName as Nombre ";
cmdStr += "FROM Person.Contact";
string msgStr = "Las personas son: ";
SqlConnection cn = new SqlConnection(conStr);
SqlCommand cmd = new SqlCommand(cmdStr, cn);
SqlDataReader dr;
cn.Open();
dr = cmd.ExecuteReader();
while (dr.Read())
{
msgStr += "\n" + dr["Id"] + " - " + dr["Nombre"];
}
dr.Close();
cn.Close();
Console.Write(msgStr);
Algunas de las caracteristicas de los comandos son:
Propiedades
Count: Indica la cantidad de registros.
HasRows: Indica si posee registros o no.
Métodos
Read: Permite leer el siguiente registro (si existe).
NextResult: Permite leer el siguiente resultset (si existe)
GetOrdinal: Devuleve el numero de la columna.
GetSchemaTable:
Close: Permite cerrar el objeto.
CommandBehavior
CloseConnection: Al cerrar el DataReader tambien cerramos la conexion asociada al comando.
Default: Resulta lo mismoque no colocar ningun argumento en el metodo ExecuteReader. Esto nos permitirá traer resultados múltiples con varias filas y columnas.
KeyInfo: Nos devuelve informacion extra sobre las columnas y, lo mas importante, informacion sobre la clave primaria. Extremadamente util cuando consultamos los metadatos a través del metodo GetSchemaTable. Esta constante tambien nos trae los datos.
SchemaOnly: Solamente útil cuando usamos el método GetSchemaTable, ya que trae los metadatos pero ningún dato.
SequentialAccess: Se utiliza para optimizar la lectura de BLOBs (Binary large objects ó grandes objetos binarios) en la base de datos. El acceso secuencial significa que en vez de tener una sola fila en memoria a la vez, tenemos un dato simple por vez, lo que hace que debamos leer los datos de las distintas columnas en el orden exacto que es devuelto por la consulta. Para leer los objetos binarios utilizamos el método GetBytes.
SingleResult: Por defecto el DataReader esta preparado para recibir mas de un conjunto de resultados. Si sabemos que nuestra consulta devolverá solamente un conjunto de resultados, podemos optimizarla eligiendo esta constante, asi el DataReader no debe prepararse para el trabajo extra que insume otro conjunto de resultados.
SingleRow: El DataReader se prepara para recibir solo una fila. Incluso si la consulta devolviera mas de una fila el DataReader no podrá leerla, ya que la segunda vez que ejecutemos el metodo Read devolverá False de todas maneras.
Multiples Resultados
Es posible que un comando retorne mas de un resultado, es por ello que los DataReaders vienen preparados para trabajar en este escenario a través del metodo NextResult, el cual cumple la doble funcion de pasar al siguiente conjunto de resultados y avisar ademas si existe otro conjunto de resultados.
Ejemplo de el Next Result
string conStr;
conStr = "Data Source=localhost;";
conStr += "Initial Catalog=AdventureWorks;";
conStr += "Integrated Security=true";
string cmdStr;
cmdStr = "SELECT top 5 ContactID as Id, ";
cmdStr += "LastName + ', ' + FirstName as Nombre ";
cmdStr += "FROM [Person].[Contact]; ";
cmdStr += "SELECT top 5 CountryRegionCode as Id, ";
cmdStr += "[Name] as Nombre ";
cmdStr += "FROM [Person].[CountryRegion]";
SqlConnection cn = new SqlConnection(conStr);
SqlCommand cmd = new SqlCommand(cmdStr, cn);
SqlDataReader dr;
cn.Open();
dr = cmd.ExecuteReader();
string msgStr = "";
do
{
while (dr.Read())
{
msgStr += "\n" + dr["Id"] + " - " + dr["Nombre"];
}
msgStr += "\n";
}
while (dr.NextResult());
dr.Close();
cn.Close();
Console.Write(msgStr);
Obtener la estructura de una tabla
En aplicaciones que son realmente grandes, podemos escribir mecanismos genéricos para realizar las operaciones para insertar, modificar y eliminar registros. Es por ello que ADO.NET nos permite obtener los metadatos de cualquier tabla a través del metodo GetSchemaTable que no es mas que una tabla que nos ofrece la informacion de otra tabla.
Ejemplo del método GetSchemaTable
string conStr;
conStr = "Data Source=localhost;";
conStr += "Initial Catalog=AdventureWorks;";
conStr += "Integrated Security=true";
string cmdStr;
cmdStr = "SELECT top 5 ContactID as Id, ";
cmdStr += "LastName + ', ' + FirstName as Nombre ";
cmdStr += "FROM [Person].[Contact]";
SqlConnection cn = new SqlConnection(conStr);
SqlCommand cmd = new SqlCommand(cmdStr, cn);
SqlDataReader dr;
cn.Open();
dr = cmd.ExecuteReader();
string msgStr = "";
DataTable dt;
dt = dr.GetSchemaTable();
for (int i = 0; i <>
{
msgStr += dt.Columns[i].ColumnName + "\n";
}
dr.Close();
cn.Close();
Console.Write(msgStr);
Parametros (Parameters)
Es muy probable que se necesiten parametros tanto en las consultas Sql como los procedimientos almacenados, es por ello que ADO.NET nos ofrece el objeto Parameters, entre las caracteristicas de esta clase la mas importante es el ParameterDirection que es una enumeracion que nos permite definir la direccion del parametro, en el podemos seleccionar los siguientes valores:
Input: El parametro es solamente para establecer un valor de entrada al comando. Se debe asignar un valor a la propiedad Value antes de ejecutar el comando.
Output: El valor del parametro se recupera leyendo a la propiedad Value, pero esto debe hacerse posteriormente a la ejecucion del comando.
InputOutput: El parametro resulta bidireccional, es decir, se asigna un valor a la propiedad Value, se ejecuta el comando, y si luego leemos la propiedad Value podriamos obtener un valor diferente del originalmente asignado.
ReturnValue: Los procedimientos almacenados podrian devolver un resultado de la misma manera que lo hacen las funciones. La forma de leer ese resultado es a traves de un parametro con esta direccion. Al igual que los parametros de salida u Output, su valor se obtiene luego de la ejecucion del comando.
Ejemplo de un Parameter
string conStr;
conStr = "Data Source=localhost;";
conStr += "Initial Catalog=AdventureWorks;";
conStr += "Integrated Security=true";
string cmdStr;
cmdStr = "dbo.uspGetManagerEmployees";
SqlConnection cn = new SqlConnection(conStr);
SqlCommand cmd = new SqlCommand(cmdStr, cn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter pmId = new SqlParameter("@ManagerID", SqlDbType.Int);
pmId.Direction = ParameterDirection.Input;
pmId.Value = 3;
cmd.Parameters.Add(pmId);
SqlDataReader dr;
cn.Open();
dr = cmd.ExecuteReader();
string msgStr = "Resultado: ";
while (dr.Read())
{
msgStr += "\n" + dr["LastName"] + ", " + dr["FirstName"];
}
dr.Close();
cn.Close();
Console.Write(msgStr);
Valores Escalares
En algunos escenarios se necesita obtener valores simples que se encuentran almacenados en una base de datos, como una fecha, numero máximo o mínimo, una cuenta, el resultado de una funcion de la base de datos, etc. En ADO.NET tenemos un método llamado ExecuteScalar que nos devuelve solamente el valor de la primera columna en la primera fila, independientemente de la cantidad de filas y columnas que devuelva la consulta.
Ejemplo de ExecuteScalar
string conStr;
conStr = "Data Source=localhost;";
conStr += "Initial Catalog=AdventureWorks;";
conStr += "Integrated Security=true";
string cmdStr;
cmdStr = "select dbo.ufnGetStock(@Id)";
SqlConnection cn = new SqlConnection(conStr);
SqlCommand cmd = new SqlCommand(cmdStr, cn);
SqlParameter pmId = new SqlParameter("@Id", SqlDbType.Int);
pmId.Direction = ParameterDirection.Input;
pmId.Value = 1;
cmd.Parameters.Add(pmId);
cn.Open();
string msgStr = "La existencia del producto es: ";
msgStr += cmd.ExecuteScalar();
cn.Close();
Console.Write(msgStr);
Otras Sentencias
En SQL no solo existen consultas que se limitan a leer o escribir datos, si no tambien existen consultas que permiten crear, modificar y eliminar objetos, asi como otogar, denegar o revocar permisos sobre los mismos, entre los tipos de sentencias tenemos las siguientes:
DDL (Data Definition Language ó Lenguaje de Defnicion de Datos): CREATE, ALTER y DROP.
DCL (Data Control Language ó Lenguaje de Control de Datos): GRANT, DENY y REVOKE.
DML (Data Manipulation Language ó Lenguaje de Manipulacion de Datos): SELECT, INSERT, UPDATE y DELETE.
Es por ello que ADO.NET nos ofrece un metodo llamado ExecuteNonQuery que no devuelve un conjunto de resultados, es decir, que es el que deberia ser utilizado para las sentencias DDL y DCL.
Este comando si bien no devuelve un conjunto de resultados, el comando nos informará, con un tipo de dato System.Int32, sobre la cantidad de registros afectados por nuestra consulta.
string conStr;
conStr = "Data Source=localhost;";
conStr += "Initial Catalog=AdventureWorks;";
conStr += "Integrated Security=true";
string cmdStr = "UPDATE Person.Address ";
cmdStr += "SET PostalCode = '98011' ";
cmdStr += "WHERE PostalCode = '98011'";
SqlConnection cn = new SqlConnection(conStr);
SqlCommand cmd = new SqlCommand(cmdStr, cn);
cmd.CommandText = cmdStr;
Int32 resultado;
cn.Open();
resultado = cmd.ExecuteNonQuery();
cn.Close();
Console.WriteLine("Se modificaron " + resultado.ToString() + " filas");
Transacciones (Transaction)
Las transacciones son una funcionalidad que poseen los manejadores de base de datos que implementen el estandar SQL como lo son SQL Server, Oracle, entre otros; estas manejan elementos de sintaxis tales como BEGIN TRANSACTION, COMMIT TRANSACTION, ROLLBACK TRANSACTION y END TRANSACTION.
Las transacciones exiten debido a que nos ofrecen facilidad de uso y seguridad al momento de utilizar multiples sentencias SQL como si fueran una sola, es decir, que para que la transaccion tenga exito cada una de las sentencias deben tener exito para que la transaccion sea completada.
Ejemplo de Transaction
string conStr;
conStr = "Data Source=localhost;";
conStr += "Initial Catalog=AdventureWorks;";
conStr += "Integrated Security=true";
SqlConnection cn = new SqlConnection(conStr);
string cmdStr = "UPDATE Person.Address ";
cmdStr += "SET PostalCode = '98011' ";
cmdStr += "WHERE PostalCode = '98011'";
string cmdStr2 = "UPDATE Person.Contact ";
cmdStr2 += "SET FirstName = 'Robert' ";
cmdStr2 += "WHERE FirstName = 'Robert'";
SqlCommand cmd = new SqlCommand(cmdStr, cn);
cmd.CommandText = cmdStr;
SqlCommand cmd2 = new SqlCommand(cmdStr2, cn);
cmd2.CommandText = cmdStr;
SqlTransaction tr;
cn.Open();
tr = cn.BeginTransaction();
try
{
cmd.Transaction = tr;
cmd.ExecuteNonQuery();
cmd2.Transaction = tr;
cmd2.ExecuteNonQuery();
tr.Commit();
}
catch (Exception ex)
{
tr.Rollback();
Console.WriteLine(ex.Message);
}
finally
{
if (cn.State == ConnectionState.Open)
cn.Close();
}
Ejemplo de un command
string conStr;
conStr = "Data Source=localhost;";
conStr += "Initial Catalog=AdventureWorks;";
conStr += "Integrated Security=true";
string cmdStr;
cmdStr = "SELECT ContactID, LastName, ";
cmdStr += "FirstName, ModifiedDate ";
cmdStr += "FROM Person.Contact";
SqlConnection cn = new SqlConnection();
cn.ConnectionString = conStr;
SqlCommand cmd = new SqlCommand();
cmd.Connection = cn;
cmd.CommandText = cmdStr;
Algunas de las caracteristicas de los comandos son:
Propiedades
CommandText: Indica la sentencia SQL o nombres de un objeto de la base de dato.
Conection: Indica la conexion asignada al comando.
CommandType: Indicar el tipo de comando a utilizar, este es una enumeracion que contiene los siguiente valores:
Text: Es la opcion por defecto. Es necesario que la propiedad CommandText contenga una sentencia SQL valida.
StoreProcedure: Permite utilizar el comando para ejecutar un procedimiento almacenado. La propiedad CommandText deberia tener asignado solamente el nombre del procedimiento.
TableDirect: Cuando necesitamos traer todas las filas y todas las columnas de una tabla o una vista, debemos usar este tipo de comando, asignado a la propiedad CommandText el nombre de la tabla o vista requerida.
Metodos
ExecuteReader: Permite construir un DataReader;
DataReaders
ADO.NET posee una clase que optimiza el acceso a los datos a través de diferentes clases llamados DataReaders, estos son utiles cuando se necesita obtener datos de la base de datos y estos no serán modificados, es decir, que los mismos van a ser de solo lectura.
Ejemplo de un DataReader
string conStr;
conStr = "Data Source=localhost;";
conStr += "Initial Catalog=AdventureWorks;";
conStr += "Integrated Security=true";
string cmdStr;
cmdStr = "SELECT top 10 ContactID as Id, ";
cmdStr += "LastName + ', ' + FirstName as Nombre ";
cmdStr += "FROM Person.Contact";
string msgStr = "Las personas son: ";
SqlConnection cn = new SqlConnection(conStr);
SqlCommand cmd = new SqlCommand(cmdStr, cn);
SqlDataReader dr;
cn.Open();
dr = cmd.ExecuteReader();
while (dr.Read())
{
msgStr += "\n" + dr["Id"] + " - " + dr["Nombre"];
}
dr.Close();
cn.Close();
Console.Write(msgStr);
Algunas de las caracteristicas de los comandos son:
Propiedades
Count: Indica la cantidad de registros.
HasRows: Indica si posee registros o no.
Métodos
Read: Permite leer el siguiente registro (si existe).
NextResult: Permite leer el siguiente resultset (si existe)
GetOrdinal: Devuleve el numero de la columna.
GetSchemaTable:
Close: Permite cerrar el objeto.
CommandBehavior
CloseConnection: Al cerrar el DataReader tambien cerramos la conexion asociada al comando.
Default: Resulta lo mismoque no colocar ningun argumento en el metodo ExecuteReader. Esto nos permitirá traer resultados múltiples con varias filas y columnas.
KeyInfo: Nos devuelve informacion extra sobre las columnas y, lo mas importante, informacion sobre la clave primaria. Extremadamente util cuando consultamos los metadatos a través del metodo GetSchemaTable. Esta constante tambien nos trae los datos.
SchemaOnly: Solamente útil cuando usamos el método GetSchemaTable, ya que trae los metadatos pero ningún dato.
SequentialAccess: Se utiliza para optimizar la lectura de BLOBs (Binary large objects ó grandes objetos binarios) en la base de datos. El acceso secuencial significa que en vez de tener una sola fila en memoria a la vez, tenemos un dato simple por vez, lo que hace que debamos leer los datos de las distintas columnas en el orden exacto que es devuelto por la consulta. Para leer los objetos binarios utilizamos el método GetBytes.
SingleResult: Por defecto el DataReader esta preparado para recibir mas de un conjunto de resultados. Si sabemos que nuestra consulta devolverá solamente un conjunto de resultados, podemos optimizarla eligiendo esta constante, asi el DataReader no debe prepararse para el trabajo extra que insume otro conjunto de resultados.
SingleRow: El DataReader se prepara para recibir solo una fila. Incluso si la consulta devolviera mas de una fila el DataReader no podrá leerla, ya que la segunda vez que ejecutemos el metodo Read devolverá False de todas maneras.
Multiples Resultados
Es posible que un comando retorne mas de un resultado, es por ello que los DataReaders vienen preparados para trabajar en este escenario a través del metodo NextResult, el cual cumple la doble funcion de pasar al siguiente conjunto de resultados y avisar ademas si existe otro conjunto de resultados.
Ejemplo de el Next Result
string conStr;
conStr = "Data Source=localhost;";
conStr += "Initial Catalog=AdventureWorks;";
conStr += "Integrated Security=true";
string cmdStr;
cmdStr = "SELECT top 5 ContactID as Id, ";
cmdStr += "LastName + ', ' + FirstName as Nombre ";
cmdStr += "FROM [Person].[Contact]; ";
cmdStr += "SELECT top 5 CountryRegionCode as Id, ";
cmdStr += "[Name] as Nombre ";
cmdStr += "FROM [Person].[CountryRegion]";
SqlConnection cn = new SqlConnection(conStr);
SqlCommand cmd = new SqlCommand(cmdStr, cn);
SqlDataReader dr;
cn.Open();
dr = cmd.ExecuteReader();
string msgStr = "";
do
{
while (dr.Read())
{
msgStr += "\n" + dr["Id"] + " - " + dr["Nombre"];
}
msgStr += "\n";
}
while (dr.NextResult());
dr.Close();
cn.Close();
Console.Write(msgStr);
Obtener la estructura de una tabla
En aplicaciones que son realmente grandes, podemos escribir mecanismos genéricos para realizar las operaciones para insertar, modificar y eliminar registros. Es por ello que ADO.NET nos permite obtener los metadatos de cualquier tabla a través del metodo GetSchemaTable que no es mas que una tabla que nos ofrece la informacion de otra tabla.
Ejemplo del método GetSchemaTable
string conStr;
conStr = "Data Source=localhost;";
conStr += "Initial Catalog=AdventureWorks;";
conStr += "Integrated Security=true";
string cmdStr;
cmdStr = "SELECT top 5 ContactID as Id, ";
cmdStr += "LastName + ', ' + FirstName as Nombre ";
cmdStr += "FROM [Person].[Contact]";
SqlConnection cn = new SqlConnection(conStr);
SqlCommand cmd = new SqlCommand(cmdStr, cn);
SqlDataReader dr;
cn.Open();
dr = cmd.ExecuteReader();
string msgStr = "";
DataTable dt;
dt = dr.GetSchemaTable();
for (int i = 0; i <>
{
msgStr += dt.Columns[i].ColumnName + "\n";
}
dr.Close();
cn.Close();
Console.Write(msgStr);
Parametros (Parameters)
Es muy probable que se necesiten parametros tanto en las consultas Sql como los procedimientos almacenados, es por ello que ADO.NET nos ofrece el objeto Parameters, entre las caracteristicas de esta clase la mas importante es el ParameterDirection que es una enumeracion que nos permite definir la direccion del parametro, en el podemos seleccionar los siguientes valores:
Input: El parametro es solamente para establecer un valor de entrada al comando. Se debe asignar un valor a la propiedad Value antes de ejecutar el comando.
Output: El valor del parametro se recupera leyendo a la propiedad Value, pero esto debe hacerse posteriormente a la ejecucion del comando.
InputOutput: El parametro resulta bidireccional, es decir, se asigna un valor a la propiedad Value, se ejecuta el comando, y si luego leemos la propiedad Value podriamos obtener un valor diferente del originalmente asignado.
ReturnValue: Los procedimientos almacenados podrian devolver un resultado de la misma manera que lo hacen las funciones. La forma de leer ese resultado es a traves de un parametro con esta direccion. Al igual que los parametros de salida u Output, su valor se obtiene luego de la ejecucion del comando.
Ejemplo de un Parameter
string conStr;
conStr = "Data Source=localhost;";
conStr += "Initial Catalog=AdventureWorks;";
conStr += "Integrated Security=true";
string cmdStr;
cmdStr = "dbo.uspGetManagerEmployees";
SqlConnection cn = new SqlConnection(conStr);
SqlCommand cmd = new SqlCommand(cmdStr, cn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter pmId = new SqlParameter("@ManagerID", SqlDbType.Int);
pmId.Direction = ParameterDirection.Input;
pmId.Value = 3;
cmd.Parameters.Add(pmId);
SqlDataReader dr;
cn.Open();
dr = cmd.ExecuteReader();
string msgStr = "Resultado: ";
while (dr.Read())
{
msgStr += "\n" + dr["LastName"] + ", " + dr["FirstName"];
}
dr.Close();
cn.Close();
Console.Write(msgStr);
Valores Escalares
En algunos escenarios se necesita obtener valores simples que se encuentran almacenados en una base de datos, como una fecha, numero máximo o mínimo, una cuenta, el resultado de una funcion de la base de datos, etc. En ADO.NET tenemos un método llamado ExecuteScalar que nos devuelve solamente el valor de la primera columna en la primera fila, independientemente de la cantidad de filas y columnas que devuelva la consulta.
Ejemplo de ExecuteScalar
string conStr;
conStr = "Data Source=localhost;";
conStr += "Initial Catalog=AdventureWorks;";
conStr += "Integrated Security=true";
string cmdStr;
cmdStr = "select dbo.ufnGetStock(@Id)";
SqlConnection cn = new SqlConnection(conStr);
SqlCommand cmd = new SqlCommand(cmdStr, cn);
SqlParameter pmId = new SqlParameter("@Id", SqlDbType.Int);
pmId.Direction = ParameterDirection.Input;
pmId.Value = 1;
cmd.Parameters.Add(pmId);
cn.Open();
string msgStr = "La existencia del producto es: ";
msgStr += cmd.ExecuteScalar();
cn.Close();
Console.Write(msgStr);
Otras Sentencias
En SQL no solo existen consultas que se limitan a leer o escribir datos, si no tambien existen consultas que permiten crear, modificar y eliminar objetos, asi como otogar, denegar o revocar permisos sobre los mismos, entre los tipos de sentencias tenemos las siguientes:
DDL (Data Definition Language ó Lenguaje de Defnicion de Datos): CREATE, ALTER y DROP.
DCL (Data Control Language ó Lenguaje de Control de Datos): GRANT, DENY y REVOKE.
DML (Data Manipulation Language ó Lenguaje de Manipulacion de Datos): SELECT, INSERT, UPDATE y DELETE.
Es por ello que ADO.NET nos ofrece un metodo llamado ExecuteNonQuery que no devuelve un conjunto de resultados, es decir, que es el que deberia ser utilizado para las sentencias DDL y DCL.
Este comando si bien no devuelve un conjunto de resultados, el comando nos informará, con un tipo de dato System.Int32, sobre la cantidad de registros afectados por nuestra consulta.
string conStr;
conStr = "Data Source=localhost;";
conStr += "Initial Catalog=AdventureWorks;";
conStr += "Integrated Security=true";
string cmdStr = "UPDATE Person.Address ";
cmdStr += "SET PostalCode = '98011' ";
cmdStr += "WHERE PostalCode = '98011'";
SqlConnection cn = new SqlConnection(conStr);
SqlCommand cmd = new SqlCommand(cmdStr, cn);
cmd.CommandText = cmdStr;
Int32 resultado;
cn.Open();
resultado = cmd.ExecuteNonQuery();
cn.Close();
Console.WriteLine("Se modificaron " + resultado.ToString() + " filas");
Transacciones (Transaction)
Las transacciones son una funcionalidad que poseen los manejadores de base de datos que implementen el estandar SQL como lo son SQL Server, Oracle, entre otros; estas manejan elementos de sintaxis tales como BEGIN TRANSACTION, COMMIT TRANSACTION, ROLLBACK TRANSACTION y END TRANSACTION.
Las transacciones exiten debido a que nos ofrecen facilidad de uso y seguridad al momento de utilizar multiples sentencias SQL como si fueran una sola, es decir, que para que la transaccion tenga exito cada una de las sentencias deben tener exito para que la transaccion sea completada.
Ejemplo de Transaction
string conStr;
conStr = "Data Source=localhost;";
conStr += "Initial Catalog=AdventureWorks;";
conStr += "Integrated Security=true";
SqlConnection cn = new SqlConnection(conStr);
string cmdStr = "UPDATE Person.Address ";
cmdStr += "SET PostalCode = '98011' ";
cmdStr += "WHERE PostalCode = '98011'";
string cmdStr2 = "UPDATE Person.Contact ";
cmdStr2 += "SET FirstName = 'Robert' ";
cmdStr2 += "WHERE FirstName = 'Robert'";
SqlCommand cmd = new SqlCommand(cmdStr, cn);
cmd.CommandText = cmdStr;
SqlCommand cmd2 = new SqlCommand(cmdStr2, cn);
cmd2.CommandText = cmdStr;
SqlTransaction tr;
cn.Open();
tr = cn.BeginTransaction();
try
{
cmd.Transaction = tr;
cmd.ExecuteNonQuery();
cmd2.Transaction = tr;
cmd2.ExecuteNonQuery();
tr.Commit();
}
catch (Exception ex)
{
tr.Rollback();
Console.WriteLine(ex.Message);
}
finally
{
if (cn.State == ConnectionState.Open)
cn.Close();
}