Construcción de Una Aplicación .net con oracle 11g y visual .net 2003

Embed Size (px)

DESCRIPTION

Podrá ver como crear una pequeña aplicación con BD Oracle y VS2003

Citation preview

Construccin de una Aplicacin .NET en Oracle Database para Visual Studio .NET 2003Por John Paul Cook

Conozca los procesos bsicos y esenciales para crear una aplicacin .NET en base de datos de Oracle.ltima actualizacin: septiembre de 2008Con la creciente popularidad del entorno .NET de Microsoft, muchos desarrolladores desean obtener informacin sobre las mejores maneras de integrar las aplicaciones .NET con Oracleno solo en trminos de conectividad bsica, sino tambin con relacin al desarrollo efectivo y eficiente de la aplicacin utilizando Visual Studio.NET (VS.NET).En este artculo, explicar los procesos bsicos y esenciales para crear una aplicacin .NET ejecutada en una base de datos Oracle, que incluyen: Cmo incorporar referencias de proyectos para soportar Oracle Class Libraries en su proyecto .NET Cmo crear cadenas de conexin para Oracle Database Cmo trabajar con objetosConnection, Command y DataReaderTendr la oportunidad de aplicar lo que ha aprendido en tres laboratorios prcticos, con distintos grados de dificultad, desde los relativamente fciles hasta los ms complejos.Para obtener informacin, conocer los laboratorios y saber cmo proteger sus aplicaciones, lea mi artculo "Proteccin de las Aplicaciones .NET en la Base de Datos de Oracle". (Tambin consulte OTN.NET Developer Centery lea los artculos tcnicos que abarcan una amplia gama de temas relacionados con el ciclo de vida de la aplicacin .NET en Oracle)Recuerde que Oracle Developer Tools para Visual Studio, que puededescargarsedesde el sitio OTN, ofrece un mdulo Visual Studio que hace que el desarrollo de las aplicaciones .NET en Oracle sea mucho ms fcil e intuitivo. Ese tema escapa a nuestro alcance, no obstante puede obtener ms informacin en Oracle Developer Tools para Visual StudioProduct Center.Proveedor de Datos .NETAdems del software bsico de conectividad cliente de Oracle, las aplicaciones .NET requieren el uso de lo que se conoce comomanaged data provider(proveedor de datos administrado, en donde el trmino "managed" hace referencia al cdigo administrado por el entorno .NET). El proveedor de datos acta entre el cdigo de aplicaciones .NET y el software de conectividad cliente de Oracle. En casi todos los casos, el mejor desempeo se logra utilizando un proveedor optimizado para una plataforma de base de datos especfica en lugar de un proveedor de datos OLE DB .NET genrico.Oracle, Microsoft y los proveedores externos, todos ofrecen proveedores de datos .NET optimizados para Oracle. Oracle y Microsoft ofrecen sus proveedores de datos Oracle de manera gratuita. (El proveedor de Microsoft para el Entorno .NET 1.1 se encuentra incluido en el entorno, pero requiere la instalacin del software cliente de Oracle.) En este artculo, utilizaremos el Proveedor de Datos de Oracle para .NET (ODP.NET), el cual se incluye con Oracle Database o comodescargaseparada.ODP.NET brinda acceso de datos ADO.NET estndar, mientras se ofrecen las caractersticas especficas de la base de datos de Oracle, tales como XML DB, las optimizaciones de desempeo de acceso de datos, y el grupo de conexin de Real Application Clusters.Cuando el software cliente de Oracle y ODP.NET se instalan, puede comenzar el desarrollo de aplicaciones utilizando Visual Studio. Confirmar la conectividad del cliente antes de iniciar el desarrollo es una buena idea. Si usted puede conectarse a Oracle utilizando el software cliente de Oracle como SQL*Plus en la misma mquina como Visual Studio, entonces usted sabr que su software cliente de Oracle ha sido correctamente instalado y configurado.Si usted es nuevo en Oracle, vea la seccin "Instalacin de Productos.NET" en laGua de 2 Das de Oracle Database para Desarrolladorespara obtener informacin sobre la instalacin y configuracin de ODP.NET especficamente, o consultela Biblioteca de Documentacin de Oracle Databasepara tener un panorama general sobre Oracle Database.Creacin de un Proyecto en Visual Studio.NETLuego de iniciar VS.NET, lo primero que hay que hacer es crear un proyecto. Puede hacer click en el botnNuevo Proyectoo seleccionarFile |New |Project...como se muestra a continuacin.

Figura 1: Creacin de un nuevo proyecto en Visual Studio.NET

Aparece la ventana de dilogoNew Project(Nuevo Proyecto). A la izquierda de la ventana de dilogo, bajo el ttuloProject Types(Tipo de Proyecto), seleccione el lenguaje de programacin de su preferencia. En nuestro ejemplo, se ha elegido VB.NET. A la derecha, bajo el ttuloTemplates(Plantillas), seleccione la plantilla del proyecto. Para facilitar las cosas, en este caso se seleccionan las Aplicaciones de Windows.

Figura 2: Utilizacin de la ventana de dilogoNew Project

Seguramente quiera especificar nombres significativos para designar al proyecto (nosotros utilizamos OraWinApp) y al nombre de la solucin (utilizamos OraSamples). Toda solucin contiene uno o ms proyectos. Cuando una solucin contiene solamente un proyecto, muchas personas utilizan el mismo nombre para ambos.Incorporacin de una ReferenciaDebido a que nuestro proyecto debe conectarse a una base de datos de Oracle, es necesario agregar una referencia a dll que contenga el proveedor de datos de su preferencia. Dentro de Solution Explorer, seleccione el nodo References (Referencias), haga click derecho y seleccioneAdd Reference(Agregar Referencias). De manera alternativa, puede ir a la barra del men y seleccionarProjecty luegoAddReference.

Figura 3: Incorporacin de una referencia

Se abre la ventana de dilogoAdd Reference.

Figura 4: Seleccin del Proveedor de Datos ODP.NET Administrado

Seleccione Oracle.DataAccess.dll de la lista, luego haga un click en el botnSelect(Seleccionar), y finalmente click en el botnOKpara comunicar al proyecto el proveedor de datos ODP.NET.

Figura 5: Solution Explorer luego de seleccionar el Proveedor Administrado de Oracle

Sentencias VB.NET/C#Luego de incorporar referencias, lo comn es agregar sentencias VB.NET Imports, sentencias C# using, o sentencias J# import. Tcnicamente estas sentencias no son requeridas, pero nos permiten referirnos a los objetos de la base de datos sin utilizar nombres largos o totalmente detallados.Por convencin, estas sentencias aparecen cerca o en la parte superior del archivo de cdigos, antes del namespace o declaracin de clase.Imports Oracle.DataAccess.Client ' VB.NET

using Oracle.DataAccess.Client; // C#

import Oracle.DataAccess.Client; // J#ODP.NET Oracle managed provider

Si agreg la referencia, Intellisense lo ayudar a completar la incorporacin de una sentencia Imports o using.

Conexin de Cadenas y ObjetosUna cadena de conexin de Oracle es inseparable de la resolucin de nombres de Oracle. Supongamos que tenamos un alias de base de datos OraDb definido en un archivo tnsnames.ora, de este modo:OraDb= (DESCRIPTION= (ADDRESS_LIST= (ADDRESS=(PROTOCOL=TCP)(HOST=OTNSRVR)(PORT=1521)) ) (CONNECT_DATA= (SERVER=DEDICATED) (SERVICE_NAME=ORCL) ) )

El alias OraDb define la informacin de conexin de la direccin de la base de datos para el cliente. Para utilizar el OraDb definido en el archivo tnsnames.ora que se muestra arriba, usted debera utilizar la siguiente sintaxis:Dim oradb As String="Data Source=OraDb;User Id=scott;Password=tiger;" 'VB.NET

string oradb = "Data Source=OraDb;User Id=scott;Password=tiger;"; // C#

Puede modificar la cadena de conexin para obviar la necesidad del archivo tnsnames.ora. Simplemente reemplace el nombre del alias con el nombre que se definira en un archivo tnsnames.ora.' VB.NET Dim oradb As String = "Data Source=(DESCRIPTION=" _+ "(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=OTNSRVR)(PORT=1521)))" _+ "(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));" _+ "User Id=scott;Password=tiger;"

// C#string oradb = "Data Source=(DESCRIPTION="+ "(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=ORASRVR)(PORT=1521)))"+ "(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));"+ "User Id=scott;Password=tiger;";

Como puede observar arriba, el nombre de usuario y la contrasea estn incorporados en la cadena de conexin en texto limpio. Este es el enfoque ms simple para crear una cadena de conexin. No obstante, desde una perspectiva de seguridad, el enfoque de texto limpio no es tan aconsejable. En particular, usted debe comprender que el cdigo de aplicacin.NET compilado es solo apenas ms seguro que los archivos de cdigo de origen del texto limpio. Descompilar archivos .NET DLL y EXE y ver el contenido del texto limpio original es muy fcil. (En realidad, la solucin adecuada es la encriptacin, pero ese tema implicara una digresin para nuestro debate.)Luego, debe representar un objeto de conexin a partir de la clase de conexin. La cadena de conexin debe estar relacionada con el objeto de conexin.Dim conn As New OracleConnection(oradb) ' VB.NET

OracleConnection conn = new OracleConnection(oradb); // C#

Observe que la cadena de conexin se relaciona con el objeto de conexin al ser transferido al constructor del objeto, el cual se encuentra sobrecargado. La sobrecarga del constructor permite la siguiente sintaxis alternativa:Dim conn As New OracleConnection() ' VB.NETconn.ConnectionString = oradb

OracleConnection conn = new OracleConnection(); // C#conn.ConnectionString = oradb;

Luego de relacionar una cadena de conexin con un objeto de conexin, utilice el mtodo Open para realizar la conexin real.conn.Open() ' VB.NET

conn.Open(); // C#

Ms adelante abarcaremos el manejo de errores.

Objeto CommandEl objeto Command se utiliza para especificar el texto de comando SQL ejecutado, ya sea que se trate de una cadena SQL o un procedimiento almacenado. De manera similar al objeto Connection, debe representarse a partir de su clase y presenta un constructor sobrecargado. En este ejemplo, ODP.NET realizar la consulta SQL para obtener el nombre de departamento (DNAME) de la tabla de departamentos (DEPT) en donde el nmero de departamento (DEPTNO) es 10.Dim sql As String = "select dname from dept where deptno = 10" ' VB.NETDim cmd As New OracleCommand(sql, conn)cmd.CommandType = CommandType.Text

string sql = "select dname from dept where deptno = 10"; // C#OracleCommand cmd = new OracleCommand(sql, conn);cmd.CommandType = CommandType.Text;

Al utilizar sobrecargas distintas, la sintaxis puede ser estructurada de manera ligeramente distinta. El objeto Command tiene mtodos para ejecutar el texto command. Existen distintos mtodos que son adecuados para distintos tipos de comandos SQL.

Recuperacin de un Valor EscalarRecuperar datos de una base de datos puede lograrse a travs de la representacin de un objeto OracleDataReader y utilizando el mtodo ExecuteReader, que permite obtener un objeto OracleDataReader. Los datos obtenidos se vuelven accesibles al trasmitir tanto el nombre de columna como el ordinal de base cero de la columna a OracleDataReader.Dim dr As OracleDataReader = cmd.ExecuteReader() ' Visual Basicdr.Read()

Label1.Text=dr.Item("dname") ' recuperar por nombre de columnaLabel1.Text=dr.Item(0)'recuperar la primera columna en la lista de seleccinLabel1.Text=dr.GetString(0) ' emitir un tipo de datos.NETLabel1.Text=dr.GetOracleString(0)'emitir un tipo de datos de Oracle

Existen descriptores de acceso (accessors) para emitir tipos de datos .NET nativos y otros para emitir tipos de datos Oracle nativos, y todos estn disponibles en C#, Visual Basic, o cualquier otro lenguaje .NET. Los ordinales de base cero pasan al descriptor de acceso para especificar qu columna emitir.OracleDataReader dr = cmd.ExecuteReader(); // C#dr.Read();

label1.Text=dr["dname"].ToString();//recuperar C# por nombre de columnalabel1.Text=dr.GetString(0).ToString();//emitir un tipo de datos.NETlabel1.Text=dr.GetOracleString(0).ToString();//emitir un tipo de datos Oracle

En este ejemplo simplificado, el valor emitido de DNAME es una cadena y se utiliza para establecer el valor de la propiedad de texto del control Etiqueta, que tambin es una cadena. Pero si en cambio DEPTNO, que no es una cadena, ha sido recuperado, se producir un desajuste del tipo de datos. El tiempo de ejecucin .NET intenta implcitamente convertir un tipo de datos a otro cuando los tipos de datos de origen y destino no coinciden. Algunas veces el tipo de datos es incompatible y la conversin implcita falla, generando una excepcin. Pero incluso cuando funciona, es an mejor utilizar las conversiones explcitas de los tipos de datos en vez de la conversin implcita de los tipos de datos.

A continuacin observamos una conversin explcita a nmero entero:Label1.Text = CStr(dr.Item("deptno")) ' Nmero entero de Visual Basic para la conversin de cadena

C# no es tan inflexible como Visual Basic respecto de las conversiones implcitas. Usted se encontrar realizando conversiones explcitas:label1.Text = dr.GetInt16("deptno").ToString(); // C#

Puede explcitamente convertir matrices y valores escalares.

MtodosCloseyDisposeEl mtodo Close o Dispose del objeto de conexin deberan invocarse para cerrar la conexin a la base de datos cuando dicha conexin ya no es necesaria. El mtodo Dispose invoca al mtodo Close.conn.Close() ' Visual Basicconn.Dispose() ' Visual Basic

conn.Close(); // C#conn.Dispose(); // C#

Alternativamente, C# ofrece una sintaxis especial que permite disponer automticamente de una conexin cuando sta se encuentra fuera del alcance. La clave using activa esta caracterstica.using (OracleConnection conn = new OracleConnection(oradb)){ conn.Open();

OracleCommand cmd = new OracleCommand(); cmd.Connection = conn; cmd.CommandText = "select dname from dept where deptno = 10"; cmd.CommandType = CommandType.Text; OracleDataReader dr = cmd.ExecuteReader(); dr.Read();

label1.Text = dr.GetString(0);}

Asimismo, OracleCommand incluye un mtodo Dispose; y OracleDataReader incluye un mtodo Close y Dispose. Cerrar y disponer de objetos .NET libera recursos del sistema, garantizando un desempeo ms eficiente de las aplicaciones, lo cual es especialmente importante en condiciones de mucha carga. Usted puede experimentar algunos de los conceptos aprendidos aqu enLab 1(Recuperacin de Datos de la Base de Datos) y enLab 2(Incorporacin de Interactividad).Manejo de ErroresCuando ocurre un error, las aplicaciones .NET deben manejar este error correctamente y mantener al usuario informado a travs de un mensaje.El manejo de errores estructurados de tipo Try-Catch-Finally es parte de los lenguajes .NET. Aqu vemos un ejemplo relativamente minimalista que utiliza la sintaxis Try-Catch-Finally:' Visual Basic

Try conn.Open()

Dim cmd As New OracleCommand cmd.Connection = conn cmd.CommandText = "select dname from dept where deptno="+TextBox1.Text cmd.CommandType = CommandType.Text

If dr.Read() Then Label1.Text = dr.Item("dname") ' or use dr.Item(0) End IfCatch ex As Exception ' catches any error MessageBox.Show(ex.Message.ToString())Finally ' In a real application, put cleanup code here.

End Try

// C#

try{ conn.Open();

OracleCommand cmd = new OracleCommand(); cmd.Connection = conn; cmd.CommandText = "select dname from dept where deptno=" + textBox1.Text; cmd.CommandType = CommandType.Text;

if (dr.Read()) // C# { label1.Text = dr["dname"].ToString(); // or use dr.GetOracleString(0).ToString() }}catch (Exception ex) // catches any error{ MessageBox.Show(ex.Message.ToString());}finally{ // En una aplicacin real, utilice el cdigo cleanup aqu.

}

A pesar de que este enfoque permitir capturar correctamente cualquier error que surja al intentar obtener datos de la base de datos, no es tan fcil de utilizar por parte del usuario. Por ejemplo, observe el siguiente mensaje que se despliega cuando la base de datos no est disponible:

Figura 6: Error ORA-12545 capturado y desplegado ante el usuario.

Un error ORA-12545 es bastante significativo para un Oracle DBA o desarrollador, pero no para el usuario final. Una mejor solucin es agregar una sentencia Catch adicional para capturar los errores de base de datos ms comunes y proporcionar mensajes comprensibles para el usuario.Catch ex As OracleException ' catches only Oracle errors Select Case ex.Number Case 1 MessageBox.Show("Error attempting to insert duplicate data.") Case 12545 MessageBox.Show("The database is unavailable.") Case Else MessageBox.Show("Database error: " + ex.Message.ToString()) End SelectCatch ex As Exception ' catches any error MessageBox.Show(ex.Message.ToString())

catch (OracleException ex) // solo captura los errores de Oracle { switch (ex.Number) { case 1: MessageBox.Show("Error attempting to insert duplicate data."); break; case 12545: MessageBox.Show("The database is unavailable."); break; default: MessageBox.Show("Database error: " + ex.Message.ToString()); break; }}catch (Exception ex) // captura cualquier error{ MessageBox.Show(ex.Message.ToString());}

Observe las dos sentenciasCatchen el cdigo de muestra de arriba. Si no hay ningn error de Oracle para capturar, la primera sentenciaCatchse saltea, dejando que cualquier otro tipo de error que no sea de Oracle sea capturado por la segunda sentenciaCatch. Las sentenciasCatchdeben ordenarse en el cdigo de la ms especfica a la ms general. Luego de implementar el cdigo de manejo fcil de excepciones, aparece el mensaje de error ORA-12545 como se muestra a continuacin:

Figura 7: Mensaje de error comprensible para el usuario advirtiendo sobre un error ORA-12545

El bloque de cdigoFinallysiempre se ejecuta independientemente de que se produzca un error o no. De ah proviene el cdigo cleanup. Si no utilizaUsingniusing, debera disponer de su conexin y de otros objetos en el bloque de cdigoFinally.Recuperacin de Mltiples Valores Utilizando DataReaderHasta el momento nuestros ejemplos han mostrado cmo recuperar un valor nico. OracleDataReader puede recuperar los valores de mltiples columnas y mltiples filas. Primero analicemos la consulta de mltiples columnas, y una fila nica:select deptno, dname, loc from dept where deptno = 10

Para obtener los valores de las columnas, se pueden utilizar nombres de columnas o valores ordinales de base cero. Los valores ordinales son relativos al orden de la consulta. As, el valor de la columna LOC puede obtenerse en Visual Basic utilizandodr.Item(2)odr.Item("loc").

Aqu vemos un fragmento del cdigo que concatena las columnas DNAME y LOC de la consulta anterior:Label1.Text = "The" + dr.Item("dname") +"department is in" +dr.Item("loc")'VB

label1.Text = "The" + dr["dname"].ToString() + "department is in" + dr["loc"].ToString(); // C#

Ahora, considere una consulta que emite mltiples filas:select deptno, dname, loc from dept

Para procesar mltiples filas emitidas desde OracleDataReader, se requiere algn tipo de construccin de loop. Adems, siempre es mejor un control que pueda desplegar mltiples filas. OracleDataReader es un cursor de solo lectura y de desplazamiento solo hacia adelante, por lo tanto no puede compararse a un control totalmente deslizable o adaptable como un control Windows Forms DataGrid. OracleDataReader es compatible con el control ListBox, tal como lo demuestra el siguiente fragmento de cdigo:.While dr.Read() ' Visual BasicListBox1.Items.Add("The"+dr.Item("dname")+"department is in"+dr.Item("loc"))End While

while (dr.Read()) // C#{ listBox1.Items.Add("The"+dr["dname"].ToString()+"department is in" + dr["loc"].ToString());}Lab 3(Recuperacin de Mltiples Columnas y Filas con OracleDataReader) destaca algunos de estos conceptos.

ResumenEste artculo ha presentado el proceso que debe seguirse para acceder a las bases de datos de Oracle utilizando los lenguajes de programacin VS.NET. Ahora tendr la capacidad de conectarse a la base de datos y recuperar mltiples filas y columnas.Lab 1: Recuperacin de Datos desde la Base de Datos1. Comenzamos con el requisito de haber creado un proyecto y haber agregado una referencia como se muestra anteriormente en este artculo.2. Ahora incorporaremos el controlbutton yel control label en el formulario Windows. Asegrese de dejar espacio arriba de los controles para permitir las incorporaciones que sern realizadas en Lab 2.

Figura 8: Formulario Lab 1 con controlesbuttonylabel

3. Agregue el cdigo para recuperar los datos de la base de datos de Oracle y desplegar los resultados en el formulario. Coloque el cdigo en un controlador de eventos click para button. La forma ms sencilla de comenzar con esta tarea es haciendo doble click con el botn ya que crear un stub para el controlador de eventos.

Figura 9: Click en el stub del controlador de eventos.

4. Agregue las sentencias VB.NET Imports antes de la declaracin Public Class o las sentencias C# using antes de la declaracin del namespace.5. Imports System.Data ' VB.NET6. Imports Oracle.DataAccess.Client ' ODP.NET Oracle managed provider7. 8. 9. using System.Data; // C#10. using Oracle.DataAccess.Client; // ODP.NET Oracle managed provider11. Agregue la versin VB.NET del controlador de eventos click entre las sentencias Private Sub y End Sub (asegrese de reemplazar OTNSRVR con el nombre de host de su servidor):

12. Dim oradb As String = "Data Source=(DESCRIPTION=(ADDRESS_LIST=" _13. + "(ADDRESS=(PROTOCOL=TCP)(HOST=OSRVR)(PORT=1521)))" 14. + "(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));" _15. + "User Id=scott;Password=tiger;"16. 17. Dim conn As New OracleConnection(oradb) ' VB.NET18. conn.Open()19. 20. Dim cmd As New OracleCommand21. cmd.Connection = conn22. cmd.CommandText = "select dname from dept where deptno = 10"23. cmd.CommandType = CommandType.Text24. 25. Dim dr As OracleDataReader = cmd.ExecuteReader()26. dr.Read() ' remplace esta sentencia en el prximo lab27. Label1.Text = dr.Item("dname") ' or dr.Item(0), remove in next lab28. 29. dr.Dispose()30. cmd.Dispose()31. conn.Dispose()

Agregue el siguiente cdigo C# al controlador de eventos click entre { and } llaves para el controlador de eventos click debutton(asegrese de reemplazar OTNSRVR con el nombre del host de su servidor):

string oradb = "Data Source=(DESCRIPTION=(ADDRESS_LIST="+ "(ADDRESS=(PROTOCOL=TCP)(HOST=ORASRVR)(PORT=1521)))"+ "(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));"+ "User Id=scott;Password=tiger;";

OracleConnection conn = new OracleConnection(oradb); // C#conn.Open();

OracleCommand cmd = new OracleCommand();cmd.Connection = conn;cmd.CommandText = "select dname from dept where deptno = 10";cmd.CommandType = CommandType.Text;

OracleDataReader dr = cmd.ExecuteReader();dr.Read(); // reemplace esta sentencia en el prximo lablabel1.Text = dr["dname"].ToString(); // remove in next lab

dr.Dispose();cmd.Dispose();conn.Dispose();32. Ejecute la aplicacin. Haga click en button. Usted debera ver lo siguiente:

Figura 10: Datos recuperados con xito

Lab 2: Incorporacin de Interactividad

Ahora que los fundamentos del acceso a la base de datos se implementaron en el cdigo, el prximo paso es incorporar la interactividad a la aplicacin. En lugar de ejecutar una consultahard coded, se puede agregar un controltextboxpara aceptar el input del usuario para el nmero de departamento (es decir, DEPTNO).1. Incorpore el controltextboxy otro controllabelal formulario como se muestra abajo. Determine la propiedad de texto del control Label2 enEnter DEPTNO: yasegrese de que la propiedadTextdeTextBox1no est sujeta a ningn valor.

Figura 11: Formulario Lab 2 con controlesbuttonylabel.

2. Modifique el cdigo que defina la cadena de seleccin:

3. cmd.CommandText = "select dname from dept where 4. deptno = " + TextBox1.Text 'VB.NET5. 6. cmd.CommandText = "select dname from dept where 7. deptno = " + textBox1.Text; // C#8. 9. 10. Ejecute la aplicacin. Pruebe la aplicacin ingresando 10 para el deptno. Vuelva a probar la aplicacin ingresando un DEPTNO invlido (por ej., 50). La aplicacin finalizar.

Figura 12: Una excepcin inmanejable

11. Modifique su cdigo para evitar cualquier error cuando se ingrese un DEPTNO invlido. Recuerde que el mtodo ExecuteReader en verdad devuelve un objeto. Reemplace la lnea que contiene dr.Read con las siguientes sentencias.12. If dr.Read() Then ' Visual Basic13. Label1.Text = dr.Item("dname").ToString()14. Else15. Label1.Text = "deptno not found"16. End If17. 18. if (dr.Read()) // C#19. {20. label1.Text = dr["dname"].ToString();;21. }22. else23. 24. {25. label1.Text = "deptno not found";26. }27. 28. 29. Pruebe la aplicacin ingresando un DEPTNO que no existe. Ahora la aplicacin ya no se cierra. Ingrese la letra A en vez de un nmero y haga click enbutton. La aplicacin se cierra. Claramente, nuestra aplicacin necesita un mejor enfoque de manejo de errores.

Aunque podra discutirse que la aplicacin no debera permitir al usuario realizar inputs invlidos que pudieran causar errores, en ltima instancia la aplicacin debe tener un slido controlador de errores incorporado. No todos los errores pueden prevenirse, por lo tanto debe implementarse un controlador de errores.

Lab 3: Recuperacin de Mltiples Columnas y Filas con DataReader

Ahora que se ha recuperado un valor nico, el prximo paso es recuperar mltiples columnas y filas con DataReader. Un control ListBox se agrega al formulario para desplegar los resultados.1. Agregue un control ListBox al formulario. Actualice el tamao del control para cubrir el mayor ancho posible del formulario como se muestra abajo.

Figura 13: Formulario con ListBox incorporado

2. Elimine la clusula where de la consulta e incorpore las columnas adicionales:3. 4. cmd.CommandText = "select deptno, dname, loc from dept" ' VB.NET5. 6. cmd.CommandText = "select deptno, dname, loc from dept"; // C#7. Los resultados de la consulta sern ledos en unwhile loop ycompletarn el control ListBox. Modifique su cdigo VB.NET para que quede de esta manera:

8. Dim oradb As String = "Data Source=(DESCRIPTION=(ADDRESS_LIST=" _9. + "(ADDRESS=(PROTOCOL=TCP)(HOST=OTNSRVR)(PORT=1521)))" _10. + "(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));" _11. + "User Id=scott;Password=tiger;"12. 13. Dim conn As New OracleConnection(oradb) ' Visual Basic14. conn.Open()15. 16. Dim cmd As New OracleCommand17. cmd.Connection = conn18. cmd.CommandText = "select deptno, dname, loc from dept"; 19. cmd.CommandType = CommandType.Text20. 21. Dim dr As OracleDataReader = cmd.ExecuteReader()22. While dr.Read()23. ListBox1.Items.Add("The " + dr.Item("dname") + _24. " department is in " + dr.Item("loc"))25. End While26. 27. dr.Dispose()28. cmd.Dispose()29. conn.Dispose()Modifique su cdigo C# para que quede de esta manera:string oradb = "Data Source=(DESCRIPTION=(ADDRESS_LIST="+ "(ADDRESS=(PROTOCOL=TCP)(HOST=ORASRVR)(PORT=1521)))"+ "(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));"+ "User Id=scott;Password=tiger;";

OracleConnection conn = new OracleConnection(oradb); // C#conn.Open();

OracleCommand cmd = new OracleCommand();cmd.Connection = conn;cmd.CommandText = "select deptno, dname, loc from dept";cmd.CommandType = CommandType.Text;

OracleDataReader dr = cmd.ExecuteReader();while (dr.Read()){ listBox1.Items.Add("The " + dr["dname"].ToString() +"department is in" + dr["loc"].ToString());}

dr.Dispose();cmd.Dispose();conn.Dispose();Ejecute la aplicacin. El ListBox debera completarse con todos los nombres de localizaciones y departamentos de la tabla DEPT. Las descargas de cdigos presentan controladores de errores implementados.