Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Tema 3: Programacin
mediante Conectores
Joaqun lvarez Garca
Curso 2015
Este documento se publica bajo licencia Creative Commons. No se permite un uso
comercial de la obra original ni de las posibles obras derivadas, la distribucin de las
cuales se debe hacer con una licencia igual a la que regula la obra original.
Para ver una copia de esta licencia visite: http://creativecommons.org/licenses/
Conceptos Bsicos
A pesar de la capacidad de los SGBD para realizar procesos lgicos, no alcanzan la potencia de
los lenguajes de programacin.
Los lenguajes de programacin permiten realizar conexiones con el SGBD a travs de uno o varios
objetos que establecen una conexin y posibilitan el intercambio de informacin.
Vista
Modelo
Controlador
SGBD
Conector
Conceptos Bsicos
Un conector es un objeto que pone en comunicacin la lgica del programa con el sistema gestor
de bases de datos.
Un conector es un objeto que permite independizar la lgica del programa del gestor de base de
datos, siendo el conector el objeto dependiente de la base de datos.
Con la finalidad de mejorar la rapidez del acceso, se desarrollan conectores especficos del
sistema gestor que se utilicen. Visual Studio incorpora conectores para las bases de datos SQL y
Oracle, pero es posible encontrar en los fabricantes de otros gestores conectores para sus
sistemas.
Las clases con los mtodos y propiedades que permiten el acceso a las bases de datos se
agrupan en espacios de nombres.
Igualmente debe existir una correspondencia entre los tipos de datos de los programas y la de los
gestores de base de datos. Los tipos de datos de los programas y de los gestores no siempre
coinciden, bien en nombre, bien en tamao. Por ejemplo, en Visual Studio y SQL Server que son
dos productos de la misma empresa Microsoft no tienen exactamente los mismos tipos de datos.
Conceptos Bsicos
SqlTypes es el espacio de nombres para SQL Server y Visual Studio para compatibilizar los tipos
de datos.
Para ejecutar un comando se necesita crear un objeto de tipo comando que se encapsula en la
conexin.
Para leer un resultado se necesita disponer de un objeto lector que recoge los datos que el
conector le traslada.
Para conectar con el gestor de base de datos, mediante un conector ODBC debemos declarar
la fuente de datos en Orgenes de Datos del equipo en el que se ejecuta el programa que
realiza la conexin: Panel de Control -> Sistema y Seguridad -> Herramientas Administrativas
-> Orgenes de Datos.
Estos parmetros pueden variar segn la versin de SQL Server que estemos utilizando.
En tercer lugar debemos crear un objeto conexin. Este objeto es de la clase OdbcConnection,
y con dos posibles constructores, uno debe recibir la cadena de conexin, que debe estar
declarada como static y otro que no recibe parmetros.
OdbcConnection conexion = new OdbcConnection(cadenaConexion);
En el caso de no pasarle parmetros:
OdbcConnection conexion = new OdbcConnection();
conexion.ConnectionString = cadenaConexion;
En quinto lugar trabajaremos con la lgica del programa, enviando comandos y recogiendo
resultados.
Es importante sealar que durante el proceso de apertura, es necesario controlar las posibles
excepciones que se puedan producir.:
// Intentamos la conexin
try
{
conexion.Open();
MessageBox.Show("Conexin Establecida");
// Cerramos la conexin
conexion.Close();
}
catch (OdbcException mensaje)
{
MessageBox.Show("Imposible realizar la conexin");
foreach (OdbcError error in mensaje.Errors) MessageBox.Show(error.Message);
}
El proceso para realizar la conexin desde el cliente SQL Server es exactamente el mismo, slo
cambio la clase a la que pertenece nuestro objeto conexin y el formato de la cadena de conexin.
Si la conexin se realiza con un servidor remoto, con seguridad SQL Server, construiremos la
cadena de conexin de la forma siguiente:
Server=myServerAddress;
Database=myDataBase;
Uid=myUsername;
Pwd=myPassword;
Lectura de datos.
El proceso de lectura es simular para el conector ODBC y para el conector propietario de SQL
Server, slo cambia el tipo de conector y, la forma de especificar los parmetros de la conexin.
o
En primer lugar necesitamos un objeto conexin con el que realizar la conexin al origen de
datos
En segundo lugar un objeto comando que contendr una instruccin SQL o el nombre de un
procedimiento almacenado que queramos ejecutar.
El tercer lugar un objeto lector que se encargar de leer una secuencia de filas de datos. Es un
objeto que lee secuencialmente y en avance.
Un esquema general del proceso, mediante conectores ODBC y sin tener en cuentas las excepciones,
podra ser:
// Crear el objeto conexin y abrir la conexin
OdbcConnection conexion = new OdbcConnection(cadenaConexion);
// Abrir la conexin
Conexion.Open();
// Definir un objeto command
OdbcCommand comando = new OdbcCommand();
// Definir un objeto lector
OdbcDataReader lector;
Lectura de datos.
// Asignamos al objeto comando la conexin previamente establecida
comando.Connection = conexion;
// Asignamos al objeto comando la orden SQL que queremos ejecutar
comando.CommandText = consultaSQL; // ejemplo select * from clientes
// Ejecutamos la orden SQL, recogiendo la direccin donde estn las filas obtenidas
lector = comando.ExecuteReader();
// Si el lector tiene datos (filas) que mostrar
if (lector.HasRows)
{
// Leer las filas. Devuelve false cuando no haya nada ms que leer
while (lector.Read())
{
// Mostramos la fila y la columna que nos interesa
MessageBox.Show(lector.GetString(0));
}
}
// Cerramos el lector y la conexin
lector.Close();
conexin.Close();
Lectura de datos.
Si en vez de haber utilizado un conector ODBC hubiramos utilizado un conector nativo SQL, el
esquema sera el mismo, slo cambiaramos el tipo de dato de los objetos: SqlConection,
SqlDataReader y SqlCommand
// Crear el objeto conexin y abrir la conexin
SqlConnection conexion = new SqlConnection(cadenaConexion);
// Abrir la conexin
Conexion.Open();
// Definir un objeto command
SqlCommand comando = new OdbcCommand();
// Definir un objeto lector
SqlDataReader lector;
// Asignamos al objeto comando la conexin previamente establecida
comando.Connection = conexion;
// Asignamos al objeto comando la orden SQL que queremos ejecutar
comando.CommandText = consultaSQL; // ejemplo select * from clientes
// Ejecutamos la orden SQL, recogiendo la direccin donde estn las filas obtenidas
lector = comando.ExecuteReader();
Lectura de datos.
// Si el lector tiene datos (filas) que mostrar
if (lector.HasRows)
{
// Leer las filas. Devuelve false cuando no haya nada ms que leer
while (lector.Read())
{
// Mostramos la fila y la columna que nos interesa
MessageBox.Show(lector.GetString(0));
}
}
// Cerramos el lector y la conexin
lector.Close();
conexin.Close();
Parmetros.
Estos parmetros se encierran entre comillas simples y la orden sql que ejecuta el comando debe ir
encerrada entre comillas dobles. Esto se traduce en un engorro a la hora de preparar la instruccin.
Los parmetros son comodines que sern sustituidos por valores en el momento de realizar la
ejecucin de la orden.
Estos parmetros se representan por una ? en la instruccin SQL cuando utilizamos conectores
ODBC y por un @nombre cuando utilizamos un conector nativo para SQL.
Los parmetros deben estar declarados del tipo del conector (OdbcParameter / SqlParameter) y
tener un valor en el momento de ejecutarse la orden
OdbcParameter parametroEquipo;
OdbcParameter parametroCiudad;
OdbcParameter parametroLiga;
// Establecemos el parmetro de la conexin
comando.Connection = conexion;
// Establecemos la orden, con parmetros
comando.CommandText = "INSERT INTO Equipos (Nombre, Ciudad, Liga) VALUES (?, ?, ?)";
// Definimos los parmetros con su tipo de dato
parametroEquipo = new OdbcParameter("pEquipo", OdbcType.NVarChar, 30);
parametroCiudad = new OdbcParameter("pCiudad", OdbcType.NVarChar, 40);
parametroLiga = new OdbcParameter("pLiga", OdbcType.NVarChar, 10);
Parmetros.
Adems de ser ms cmodo para el programador, es ms rpido, pues con este sistema el gestor
de base de datos prepara un plan de ejecucin, que es aprovechado en consultas posteriores, sin
tener que volver a prepararlo.
SELECT * FROM Equipos WHERE liga = ?
// Utilizando Odbc
SELECT * FROM Equipos WHERE liga = @paramLiga // Utilizando SqlClient
Nota importante.- Cuando a un parmetro haya que asignarle un valor null, debemos tener en
cuenta que el valor NULL de un lenguaje de programacin no representa lo mismo que el valor
NULL de un sistema gestor de base de datos, as desde C# un valor NULL para la base de datos
SQL Server se indica por SqlInt32.Null
Actualizaciones de datos.
Para realizar cualquier tipo de insercin, borrado o modificacin de los datos, utilizaremos un objeto
de la clase xxCommand, donde xx representa al conector.
Si recordamos los comandos de SQL, para insertar un registro, utilizbamos la la orden INSERT, y
as tenamos:
INSERT INTO nombreTabla (campo1, campo2, campo3) VALUES (valor1, valor2, valor3)
En la orden anterior, estamos insertando un registro, donde los nombres de los campos vienen
dados por nos nombres campo1, campo2, campo3) y los valores asociados a esos campos son
valor1, valor2, valor3.
Como hicimos en la orden SELECT utilizaremos parmetros para hacer ms sencilla la composicin
de la orden,
Procedimientos almacenados.
El ltimo parmetro, conocido como valor de retorno, que devuelve un entero, es creado por el
sistema de forma automtica y representa el nmero de filas afectadas por la ejecucin del
procedimiento.
Procedimientos almacenados.
Los valores de entrada y salida del procedimiento son parmetros que deben asignarse e indicarse
si son de entrada, de salida o el valor de retorno.
Procedimientos almacenados.
static void insertJugODBC(int nFed, string nombre, string ape1, string ape2, int nEquipo)
{
OdbcConnection conexion;
OdbcCommand comando = new OdbcCommand();
OdbcParameter parRetorno, parEquipo, parJugador, parNombre;
OdbcParameter parApellido1, parApellido2, parMensaje;
string strConexion;
// Construimos la cadena de conexin con autentificacin Windows
strConexion = "Driver={SQL Server Native Client 11.0}; Server=ADTSERVER;
Database=LigaFutbol; Trusted_Connection=yes";
// Creamos el objeto conexin, pasndole la cadena de conexin
conexion = new OdbcConnection(strConexion);
try
{
// Abrimos la conexin
conexion.Open();
// Indicamos que queremos ejecutar un procedimiento almacenado
comando.CommandType = CommandType.StoredProcedure;
// Indicamos la conexin abierta
comando.Connection = conexion;
Procedimientos almacenados.
// Indicamos la orden en formato Odbc
comando.CommandText = "{? = CALL paInsertarJugador (?, ?, ?, ?, ?, ?)}";
// Indicamos el valor devuelto por el procedimiento: nmero de filas insertadas
parRetorno = comando.Parameters.Add("ValorRetorno", OdbcType.Int);
parRetorno.Direction = ParameterDirection.ReturnValue;
// Parmetros de entrada al procedimiento
parJugador = comando.Parameters.Add("numFed", OdbcType.Int);
parJugador.Value = nFed;
parNombre = comando.Parameters.Add("nombre", OdbcType.VarChar, 30);
parNombre.Value = nombre;
parApellido1 = comando.Parameters.Add("apellido1", OdbcType.VarChar, 25);
parApellido1.Value = ape1;
parApellido2 = comando.Parameters.Add("apellido2", OdbcType.VarChar, 25);
parApellido2.Value = ape2;
parEquipo = comando.Parameters.Add("equipo", OdbcType.Int);
parEquipo.Value = nEquipo;
// Parmetros de salida del procedimiento
parMensaje = comando.Parameters.Add("mensaje", OdbcType.NVarChar,50);
parMensaje.Direction = ParameterDirection.Output;
Procedimientos almacenados.
// Mostramos el parmetro retornado y el parmetro de salida
Console.WriteLine("filas grabadas: " + comando.ExecuteNonQuery().ToString());
Console.WriteLine(Convert.ToString(comando.Parameters["mensaje"].Value));
}
catch (Exception error)
{
Console.WriteLine(error);
}
}
}
}
Procedimientos almacenados.
static void insertJugSQL(int nFed, string nombre, string ape1, string ape2, int nEquipo)
{
SqlConnection conexion;
SqlCommand comando = new SqlCommand();
SqlParameter parRetorno, parEquipo, parJugador, parNombre;
SqlParameter parApellido1, parApellido2, parMensaje;
string strConexion;
// Construimos la cadena de conexin con autentificacin Windows
strConexion = "Server = ADTSERVER; Database = LigaFutbol;
Trusted_Connection=yes";
// Creamos el objeto conexin, pasndole la cadena de conexin
conexion = new SqlConnection(strConexion);
try
{
// Abrimos la conexin
conexion.Open();
// Indicamos la conexin abierta
comando.Connection = conexion;
// Indicamos la orden en formato SqlClient
comando.CommandText = "paInsertarJugador";
Procedimientos almacenados.
// Indicamos que queremos ejecutar un procedimiento almacenado
comando.CommandType = CommandType.StoredProcedure;
// Indicamos el valor devuelto por el procedimiento: nmero de filas insertadas
parRetorno = comando.Parameters.Add("@ValorRetorno", SqlDbType.Int);
parRetorno.Direction = ParameterDirection.ReturnValue;
// Parmetros de entrada al procedimiento
parJugador = comando.Parameters.Add("@numFed", SqlDbType.Int);
parJugador.Value = nFed;
parNombre = comando.Parameters.Add("@nombre", SqlDbType.NVarChar, 30);
parNombre.Value = nombre;
parApellido1 = comando.Parameters.Add("@apellido1", SqlDbType.NVarChar, 25);
parApellido1.Value = ape1;
parApellido2 = comando.Parameters.Add(@"apellido2", SqlDbType.NVarChar, 25);
parApellido2.Value = ape2;
parEquipo = comando.Parameters.Add(@"equipo", SqlDbType.Int);
parEquipo.Value = nEquipo;
// Parmetros de salida del procedimiento
parMensaje = comando.Parameters.Add("@mensaje", SqlDbType.NVarChar, 50);
parMensaje.Direction = ParameterDirection.Output;
Procedimientos almacenados.
// Mostramos el parmetro retornado y el parmetro de salida
Console.WriteLine("filas grabadas: " + comando.ExecuteNonQuery().ToString());
Console.WriteLine(Convert.ToString(comando.Parameters["@mensaje"].Value));
}
catch (Exception error)
{
Console.WriteLine(error);
}
}
}
}