Вы находитесь на странице: 1из 24

Acceso a Datos

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.

Al igual que en el modelo-vista-controlador, que se utiliza para independizar la capa de la vista de


la capa de negocio, a travs de un controlador (que es un objeto intermedio que intercambia la
informacin, en el acceso a las bases de datos tambin se utiliza un objeto controlador intermedio,
que recibe el nombre de conector.

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.

Open DataBase Connectivity (ODBC) es un estndar de acceso a bases de datos, desarrollado a


comienzos de la dcada de los 90, con el objetivo de hacer posible el acceso a cualquier dato de
una base de datos, sin que importe el sistema que almacene este dato, sin ms requisito que el
sistema gestor de base de dato sea compatible (capaz de reconocer lo comandos que le llegan y
responder a ellos).

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.

Con este modelo de trabajo, los programas:


Para leer
o Crear un objeto conexin.
o Abrir una conexin con el sistema gestor
o Ejecutar comando del lectura
o Recoger los resultados y tratarlos
o Cerrar la conexin
Para escribir
o Crear un objeto conexin.
o Abrir una conexin con el sistema gestor
o Ejecutar comando de insercin, borrado, actualizacin
o Cerrar la conexin

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.

Conexin mediante ODBC

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.

Declarada la fuente de datos, el paso siguiente ya es establecer la conexin desde el lenguaje


de programacin, en nuestro caso C#

Conexin mediante ODBC


Los pasos que tenemos que seguir son los siguientes:

En primer lugar debemos incorporar el espacio de nombres System.Data.Odbc.

En segundo lugar debemos preparar la cadena de conexin. Esta cadena de conexin


incorpora diferentes parmetros separados por el carcter punto y coma (;).
o

Estos parmetros pueden variar segn la versin de SQL Server que estemos utilizando.

En la direccin de internet: http://www.connectionstrings.com/se puede encontrar todo tipo


de cadenas de conexin, en funcin del gestor y versiones que tengamos.

Por ejemplo: Una conexin utilizando autentificacin integrada de Windows:


string conector =
string servidor =
string baseDatos
string seguridad =

"Driver={SQL Server Native Client 11.0};;


Server=ADTSERVER;;
=
Database=Liga;;
Trusted_Connection=yes;";

string cadenaConexion = conector+servidor+baseDatos+seguridad;


strConexion = "Driver={SQL Server Native Client 11.0};Server=ADTSERVER;
Database=Liga;Trusted_Connection=yes;";

Conexin mediante ODBC


o

Por ejemplo: Una conexin utilizando la autentificacin de SQL Server


string conector =
string servidor =
string baseDatos
string usuario
=
string clave
=

"Driver={SQL Server Native Client 11.0};;


Server=ADTSERVER;;
=
Database=Liga;;
Uid=sqldam220;;
Pwd=Alumnado220;";

string cadenaConexion = conector+servidor+baseDatos+usuario+clave;


strConexion = "Driver={SQL Server Native Client 11.0};Server=ADTSERVER;
Database=Liga; Uid=sqldam220; Pwd=Alumnado220;";

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;

Conexin mediante ODBC

En cuarto lugar debemos abrir la conexin con el servidor (instruccin Open).


conexion.Open();

En quinto lugar trabajaremos con la lgica del programa, enviando comandos y recogiendo
resultados.

Por ltimo, cerraremos la conexin:


conexion.Close();

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);
}

Conexin mediante el conector SQL

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.

El espacio de nombres ahora sera: System.Data.SqlClient


o

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;

Si la conexin se realiza con un servidor remoto, con seguridad Windows


Server=myServerAddress;
Database=myDataBase;
Trusted_Connection=True;

El objeto conexin sera de la forma:


SqlConnection conexion = new SqlConnection(cadenaConexin);
O bien:
SqlConnection conexion = new SqlConnection();
conexion.ConnectionString = cadenaConexion;

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.

Por ltimo, cerraremos la conexin

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.

Cuando realizamos procesos de bsqueda o de actualizacin de datos, es necesario utilizar valores


para filtrar las instrucciones. Estos valores se denominan parmetros, por ejemplo
select * from clientes where nombre = Juan Antonio

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.

Cada interrogante representa el pEquipo, pCiudad y pLiga.


// Damos valores a los parmetros
parametroEquipo.Value = strEquipo;
parametroCiudad.Value = strCiudad;
parametroLiga.Value = strLiga;
// Aadimos los parmetros al comando
comando.Parameters.Add(parametroEquipo);
comando.Parameters.Add(parametroCiudad);
comando.Parameters.Add(parametroLiga);

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.

Este objeto xxCommand lo lanzaremos llamando al mtodo ExecuteNonQuery, teniendo en cuenta


que la conexin con el gestor debe estar abierta, dado que estamos trabajando en el modelo
conectado,

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.

Un procedimiento almacenado es un fragmento de cdigo fuente escrito en el lenguaje SQL, del


gestor de base de datos que estemos utilizando (T-SQL en el caso de Microsoft), que se almacena
precompilado y se ejecuta en el servidor y que podemos invocar desde un equipo cliente.

Un procedimiento almacenado es parecido a un mtodo, al poder recibir y devolver valores mediante


el paso de parmetros, a la vez que tambin devuelve un valor.

Cuando creamos un procedimiento almacenado en el gestor tendremos una estructura como la


siguiente:

Podemos observar los parmetros de entrada, de salida y que devuelve un entero.

Los parmetros de entrada y salida los define el programador, segn necesidades.

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.

Para ejecutar un procedimiento almacenado, debemos asignar al comando la propiedad


CommandType de la forma siguiente:
comando.CommandType = CommandType.StoredProcedure;

La forma de preparar la llamada al procedimiento almacenado es mediante la orden


CommandText, que tendr la forma:
comando.CommandText = "{? = CALL nombreProcedimiento (?, ?, ?, ?, ?, ?)}"; // para ODBC
comando.CommandText = "nombreProcedimiento"; // para conector nativo SQL

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.

La forma de indicar esto ltimo se hace mediante los valores:


parameterDirection.Input;
ParameterDirection.Output;
ParameterDirection.ReturnValue;

La ejecucin del procedimiento almacenado se realiza mediante:


int filasAfectadas = comando.ExecuteNonQuery();

Se puede ver cmo se recogen el valor de retorno del procedimiento almacenado.

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);
}
}
}
}

Вам также может понравиться