Presentacion Tema 3.pptx

24
Curso 2015 Acceso a Datos Tema 3: Programación mediante Conectores Joaquín Álvarez García 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 distribución 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/

Transcript of Presentacion Tema 3.pptx

Page 1: Presentacion Tema 3.pptx

Curso 2015

Acceso a DatosTema 3: Programación mediante

ConectoresJoaquín Álvarez García

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 distribución 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/  

   

Page 2: Presentacion Tema 3.pptx

Conceptos Básicos…• A pesar de la capacidad de los SGBD para realizar procesos lógicos, no alcanzan la potencia de

los lenguajes de programación.

• Los lenguajes de programación permiten realizar conexiones con el SGBD a través de uno o varios objetos que establecen una conexión y posibilitan el intercambio de información.

• Al igual que en el modelo-vista-controlador, que se utiliza para independizar la capa de la vista de la capa de negocio, a través de un controlador (que es un objeto intermedio que intercambia la información, en el acceso a las bases de datos también se utiliza un objeto controlador intermedio, que recibe el nombre de conector.

Vista Modelo SGBD

Controlador Conector

Page 3: Presentacion Tema 3.pptx

Conceptos Básicos…• Un conector es un objeto que pone en comunicación la lógica del programa con el sistema gestor

de bases de datos.

• Un conector es un objeto que permite independizar la lógica 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 estándar de acceso a bases de datos, desarrollado a comienzos de la década 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 más 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 específicos 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 métodos 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 tamaño. 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.

Page 4: Presentacion Tema 3.pptx

Conceptos Básicos…• 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 leero Crear un objeto conexión.o Abrir una conexión con el sistema gestoro Ejecutar comando del lecturao Recoger los resultados y tratarloso Cerrar la conexión

Para escribiro Crear un objeto conexión.o Abrir una conexión con el sistema gestoro Ejecutar comando de inserción, borrado, actualizacióno Cerrar la conexión

• Para ejecutar un comando se necesita crear un objeto de tipo comando que se encapsula en la conexión.

• Para leer un resultado se necesita disponer de un objeto lector que recoge los datos que el conector le traslada.

Page 5: Presentacion Tema 3.pptx

Conexión mediante ODBC…

• Para conectar con el gestor de base de datos, mediante un conector ODBC debemos declarar la fuente de datos en Orígenes de Datos del equipo en el que se ejecuta el programa que realiza la conexión: Panel de Control -> Sistema y Seguridad -> Herramientas Administrativas -> Orígenes de Datos.

• Declarada la fuente de datos, el paso siguiente ya es establecer la conexión desde el lenguaje de programación, en nuestro caso C#

Page 6: Presentacion Tema 3.pptx

Conexión 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 conexión. Esta cadena de conexión incorpora diferentes parámetros separados por el carácter punto y coma (“;”).

o Estos parámetros pueden variar según la versión de SQL Server que estemos utilizando.

o En la dirección de internet: http://www.connectionstrings.com/se puede encontrar todo tipo de cadenas de conexión, en función del gestor y versiones que tengamos.

o Por ejemplo: Una conexión utilizando autentificación integrada de Windows:

string conector = "Driver={SQL Server Native Client 11.0};”;

string servidor = “Server=ADTSERVER;”;string baseDatos = “Database=Liga;”;string seguridad = “Trusted_Connection=yes;";

 

string cadenaConexion = conector+servidor+baseDatos+seguridad;

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

Page 7: Presentacion Tema 3.pptx

Conexión mediante ODBC…o Por ejemplo: Una conexión utilizando la autentificación de SQL Server

string conector = "Driver={SQL Server Native Client 11.0};”;

string servidor = “Server=ADTSERVER;”;string baseDatos = “Database=Liga;”;string usuario = ”Uid=sqldam220;”;string clave = “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 conexión. Este objeto es de la clase OdbcConnection, y con dos posibles constructores, uno debe recibir la cadena de conexión, que debe estar declarada como static y otro que no recibe parámetros.

OdbcConnection conexion = new OdbcConnection(cadenaConexion);

En el caso de no pasarle parámetros: OdbcConnection conexion = new OdbcConnection(); conexion.ConnectionString = cadenaConexion;

Page 8: Presentacion Tema 3.pptx

Conexión mediante ODBC…• En cuarto lugar debemos abrir la conexión con el servidor (instrucción Open).

 conexion.Open();

• En quinto lugar trabajaremos con la lógica del programa, enviando comandos y recogiendo resultados.

• Por último, cerraremos la conexión:

conexion.Close();

• Es importante señalar que durante el proceso de apertura, es necesario controlar las posibles excepciones que se puedan producir.:

// Intentamos la conexióntry{

conexion.Open();MessageBox.Show("Conexión Establecida");

 // Cerramos la conexiónconexion.Close();

}catch (OdbcException mensaje){

MessageBox.Show("Imposible realizar la conexión");foreach (OdbcError error in mensaje.Errors) MessageBox.Show(error.Message);

}

Page 9: Presentacion Tema 3.pptx

Conexión mediante el conector SQL…• El proceso para realizar la conexión desde el cliente SQL Server es exactamente el mismo, sólo

cambio la clase a la que pertenece nuestro objeto conexión y el formato de la cadena de conexión.

• El espacio de nombres ahora sería: System.Data.SqlClient

o Si la conexión se realiza con un servidor remoto, con seguridad SQL Server, construiremos la cadena de conexión de la forma siguiente: 

Server=myServerAddress;Database=myDataBase;Uid=myUsername; Pwd=myPassword; 

o Si la conexión se realiza con un servidor remoto, con seguridad Windows Server=myServerAddress;Database=myDataBase;Trusted_Connection=True;

• El objeto conexión sería de la forma:

SqlConnection conexion = new SqlConnection(cadenaConexión);

O bien:

SqlConnection conexion = new SqlConnection();conexion.ConnectionString = cadenaConexion;

Page 10: Presentacion Tema 3.pptx

Lectura de datos….• El proceso de lectura es simular para el conector ODBC y para el conector propietario de SQL

Server, sólo cambia el tipo de conector y, la forma de especificar los parámetros de la conexión.

o En primer lugar necesitamos un objeto conexión con el que realizar la conexión al origen de datos

o En segundo lugar un objeto comando que contendrá una instrucción SQL o el nombre de un procedimiento almacenado que queramos ejecutar.

o 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.

o Por último, cerraremos la conexión

Un esquema general del proceso, mediante conectores ODBC y sin tener en cuentas las excepciones, podría ser:  

// Crear el objeto conexión y abrir la conexiónOdbcConnection conexion = new OdbcConnection(cadenaConexion);

// Abrir la conexiónConexion.Open();

 // Definir un objeto commandOdbcCommand comando = new OdbcCommand();

 // Definir un objeto lectorOdbcDataReader lector;

Page 11: Presentacion Tema 3.pptx

Lectura de datos….  

// Asignamos al objeto comando la conexión previamente establecidacomando.Connection = conexion;

// Asignamos al objeto comando la orden SQL que queremos ejecutarcomando.CommandText = consultaSQL; // ejemplo “select * from clientes”

 // Ejecutamos la orden SQL, recogiendo la dirección donde están las filas obtenidaslector = comando.ExecuteReader();

// Si el lector tiene datos (filas) que mostrar if (lector.HasRows){

// Leer las filas. Devuelve false cuando no haya nada más que leerwhile (lector.Read()){

// Mostramos la fila y la columna que nos interesaMessageBox.Show(lector.GetString(0));

}}

 // Cerramos el lector y la conexiónlector.Close();conexión.Close();

Page 12: Presentacion Tema 3.pptx

Lectura de datos….• Si en vez de haber utilizado un conector ODBC hubiéramos utilizado un conector nativo SQL, el

esquema sería el mismo, sólo cambiaríamos el tipo de dato de los objetos: SqlConection, SqlDataReader y SqlCommand

// Crear el objeto conexión y abrir la conexiónSqlConnection conexion = new SqlConnection(cadenaConexion);

// Abrir la conexiónConexion.Open();

 // Definir un objeto commandSqlCommand comando = new OdbcCommand();

 // Definir un objeto lectorSqlDataReader lector;

// Asignamos al objeto comando la conexión previamente establecidacomando.Connection = conexion;

// Asignamos al objeto comando la orden SQL que queremos ejecutarcomando.CommandText = consultaSQL; // ejemplo “select * from clientes”

 // Ejecutamos la orden SQL, recogiendo la dirección donde están las filas obtenidaslector = comando.ExecuteReader();

Page 13: Presentacion Tema 3.pptx

Lectura de datos….

// Si el lector tiene datos (filas) que mostrar if (lector.HasRows){

// Leer las filas. Devuelve false cuando no haya nada más que leerwhile (lector.Read()){

// Mostramos la fila y la columna que nos interesaMessageBox.Show(lector.GetString(0));

}}

 // Cerramos el lector y la conexiónlector.Close();conexión.Close();

Page 14: Presentacion Tema 3.pptx

Parámetros….• Cuando realizamos procesos de búsqueda o de actualización de datos, es necesario utilizar valores

para filtrar las instrucciones. Estos valores se denominan parámetros, por ejemplo

select * from clientes where nombre = ‘Juan Antonio’

• Estos parámetros 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 instrucción.

• Los parámetros son comodines que serán sustituidos por valores en el momento de realizar la ejecución de la orden.

• Estos parámetros se representan por una ? en la instrucción SQL cuando utilizamos conectores ODBC y por un @nombre cuando utilizamos un conector nativo para SQL.

• Los parámetros 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 parámetro de la conexióncomando.Connection = conexion;  

// Establecemos la orden, con parámetroscomando.CommandText = "INSERT INTO Equipos (Nombre, Ciudad, Liga) VALUES (?, ?, ?)"; 

// Definimos los parámetros con su tipo de datoparametroEquipo = new OdbcParameter("pEquipo", OdbcType.NVarChar, 30);parametroCiudad = new OdbcParameter("pCiudad", OdbcType.NVarChar, 40);parametroLiga = new OdbcParameter("pLiga", OdbcType.NVarChar, 10);

Page 15: Presentacion Tema 3.pptx

Parámetros….• Cada interrogante representa el “pEquipo”, “pCiudad” y “pLiga”.

 

// Damos valores a los parámetrosparametroEquipo.Value = strEquipo;parametroCiudad.Value = strCiudad;parametroLiga.Value = strLiga; 

// Añadimos los parámetros al comandocomando.Parameters.Add(parametroEquipo);comando.Parameters.Add(parametroCiudad);comando.Parameters.Add(parametroLiga);

• Además de ser más cómodo para el programador, es más rápido, pues con este sistema el gestor de base de datos prepara un plan de ejecución, 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 parámetro haya que asignarle un valor null, debemos tener en cuenta que el valor NULL de un lenguaje de programación 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

Page 16: Presentacion Tema 3.pptx

Actualizaciones de datos….• Para realizar cualquier tipo de inserción, borrado o modificación de los datos, utilizaremos un objeto

de la clase xxCommand, donde ”xx” representa al conector.  

• Este objeto xxCommand lo lanzaremos llamando al método ExecuteNonQuery, teniendo en cuenta que la conexión con el gestor debe estar abierta, dado que estamos trabajando en el modelo conectado,

 

• Si recordamos los comandos de SQL, para insertar un registro, utilizábamos la la orden INSERT, y así teníamos:

 

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 parámetros para hacer más sencilla la composición de la orden,

Page 17: Presentacion Tema 3.pptx

Procedimientos almacenados….• Un procedimiento almacenado es un fragmento de código 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 método, al poder recibir y devolver valores mediante

el paso de parámetros, a la vez que también devuelve un valor.

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

• Podemos observar los parámetros de entrada, de salida y que devuelve un entero.

• Los parámetros de entrada y salida los define el programador, según necesidades.

• El último parámetro, conocido como valor de retorno, que devuelve un entero, es creado por el sistema de forma automática y representa el número de filas afectadas por la ejecución del procedimiento.

Page 18: Presentacion Tema 3.pptx

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 ODBCcomando.CommandText = "nombreProcedimiento"; // para conector nativo SQL

• Los valores de entrada y salida del procedimiento son parámetros 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 ejecución del procedimiento almacenado se realiza mediante:

int filasAfectadas = comando.ExecuteNonQuery();

• Se puede ver cómo se recogen el «valor de retorno» del procedimiento almacenado.

Page 19: Presentacion Tema 3.pptx

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 conexión con autentificación Windows strConexion = "Driver={SQL Server Native Client 11.0}; Server=ADTSERVER;

Database=LigaFutbol; Trusted_Connection=yes";  // Creamos el objeto conexión, pasándole la cadena de conexión conexion = new OdbcConnection(strConexion);   try { // Abrimos la conexión conexion.Open();  // Indicamos que queremos ejecutar un procedimiento almacenado comando.CommandType = CommandType.StoredProcedure;  // Indicamos la conexión abierta comando.Connection = conexion; 

Page 20: Presentacion Tema 3.pptx

Procedimientos almacenados…. // Indicamos la orden en formato Odbc comando.CommandText = "{? = CALL paInsertarJugador (?, ?, ?, ?, ?, ?)}";  // Indicamos el valor devuelto por el procedimiento: número de filas insertadas parRetorno = comando.Parameters.Add("ValorRetorno", OdbcType.Int); parRetorno.Direction = ParameterDirection.ReturnValue;  // Parámetros 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;  // Parámetros de salida del procedimiento parMensaje = comando.Parameters.Add("mensaje", OdbcType.NVarChar,50); parMensaje.Direction = ParameterDirection.Output; 

Page 21: Presentacion Tema 3.pptx

Procedimientos almacenados…. // Mostramos el parámetro retornado y el parámetro de salida Console.WriteLine("filas grabadas: " + comando.ExecuteNonQuery().ToString()); Console.WriteLine(Convert.ToString(comando.Parameters["mensaje"].Value)); } catch (Exception error) { Console.WriteLine(error); } } }}

Page 22: Presentacion Tema 3.pptx

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 conexión con autentificación Windows strConexion = "Server = ADTSERVER; Database = LigaFutbol; Trusted_Connection=yes";  // Creamos el objeto conexión, pasándole la cadena de conexión conexion = new SqlConnection(strConexion);  try { // Abrimos la conexión conexion.Open();  // Indicamos la conexión abierta comando.Connection = conexion; // Indicamos la orden en formato SqlClient comando.CommandText = "paInsertarJugador";

Page 23: Presentacion Tema 3.pptx

Procedimientos almacenados….// Indicamos que queremos ejecutar un procedimiento almacenado

comando.CommandType = CommandType.StoredProcedure;  // Indicamos el valor devuelto por el procedimiento: número de filas insertadas parRetorno = comando.Parameters.Add("@ValorRetorno", SqlDbType.Int); parRetorno.Direction = ParameterDirection.ReturnValue;  // Parámetros 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;  // Parámetros de salida del procedimiento parMensaje = comando.Parameters.Add("@mensaje", SqlDbType.NVarChar, 50); parMensaje.Direction = ParameterDirection.Output;

Page 24: Presentacion Tema 3.pptx

Procedimientos almacenados….  // Mostramos el parámetro retornado y el parámetro de salida Console.WriteLine("filas grabadas: " + comando.ExecuteNonQuery().ToString()); Console.WriteLine(Convert.ToString(comando.Parameters["@mensaje"].Value)); } catch (Exception error) { Console.WriteLine(error); } } }}