Construcción de una Aplicación

Anuncio
Construcción de una Aplicación .NET en Oracle Database para
Visual Studio .NET 2003
Por John Paul Cook
Conozca los procesos básicos y esenciales para crear una aplicación .NET en base de datos de Oracle.
Última actualización: septiembre de 2008
Con la creciente popularidad del entorno .NET de Microsoft, muchos desarrolladores desean obtener
información sobre las mejores maneras de integrar las aplicaciones .NET con Oracle—no solo en términos de
conectividad básica, sino también con relación al desarrollo efectivo y eficiente de la aplicación utilizando
Visual Studio.NET (VS.NET).
En este artículo, explicaré los procesos básicos y esenciales para crear una aplicación .NET ejecutada en una
base de datos Oracle, que incluyen:



Cómo incorporar referencias de proyectos para soportar Oracle Class Libraries en su proyecto .NET
Cómo crear cadenas de conexión para Oracle Database
Cómo trabajar con objetos Connection, Command y DataReader
Tendrá la oportunidad de aplicar lo que ha aprendido en tres laboratorios prácticos, con distintos grados de
dificultad, desde los relativamente fáciles hasta los más complejos.
Para obtener información, conocer los laboratorios y saber cómo proteger sus aplicaciones, lea mi artículo "
Protección de las Aplicaciones .NET en la Base de Datos de Oracle". (También consulte OTN .NET Developer Center y
lea los artículos técnicos que abarcan una amplia gama de temas relacionados con el ciclo de vida de la
aplicación .NET en Oracle)
Recuerde que Oracle Developer Tools para Visual Studio, que puede descargarse desde el sitio OTN, ofrece un
módulo Visual Studio que hace que el desarrollo de las aplicaciones .NET en Oracle sea mucho más fácil e
intuitivo. Ese tema escapa a nuestro alcance, no obstante puede obtener más información en Oracle
Developer Tools para Visual Studio Product Center.
Proveedor de Datos .NET
Además del software básico de conectividad cliente de Oracle, las aplicaciones .NET requieren el uso de lo
que se conoce como managed data provider (proveedor de datos administrado, en donde el término
"managed" hace referencia al código administrado por el entorno .NET). El proveedor de datos actúa entre el
código de aplicaciones .NET y el software de conectividad cliente de Oracle. En casi todos los casos, el mejor
desempeño se logra utilizando un proveedor optimizado para una plataforma de base de datos específica en
lugar de un proveedor de datos OLE DB .NET genérico.
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 instalación del
software cliente de Oracle.) En este artículo, utilizaremos el Proveedor de Datos de Oracle para .NET
(ODP.NET), el cual se incluye con Oracle Database o como descarga separada.
ODP.NET brinda acceso de datos ADO.NET estándar, mientras se ofrecen las características específicas de
la base de datos de Oracle, tales como XML DB, las optimizaciones de desempeño de acceso de datos, y el
grupo de conexión 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
máquina 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 sección "Instalación de Productos.NET" en la Guía de 2 Días de Oracle
Database para Desarrolladores para obtener información sobre la instalación y configuración de ODP.NET
específicamente, o consulte la Biblioteca de Documentación de Oracle Database para tener un panorama general
sobre Oracle Database.
Creación de un Proyecto en Visual Studio.NET
Luego de iniciar VS.NET, lo primero que hay que hacer es crear un proyecto. Puede hacer click en el botón
Nuevo Proyecto o seleccionar File | New | Project... como se muestra a continuación.
Figura 1: Creación de un nuevo proyecto en Visual Studio.NET
Aparece la ventana de diálogo New Project ( Nuevo Proyecto). A la izquierda de la ventana de diálogo, bajo
el título Project Types (Tipo de Proyecto), seleccione el lenguaje de programación de su preferencia. En
nuestro ejemplo, se ha elegido VB.NET. A la derecha, bajo el título Templates (Plantillas), seleccione la
plantilla del proyecto. Para facilitar las cosas, en este caso se seleccionan las Aplicaciones de Windows.
Figura 2: Utilización de la ventana de diálogo New Project
Seguramente quiera especificar nombres significativos para designar al proyecto (nosotros utilizamos
OraWinApp) y al nombre de la solución (utilizamos OraSamples). Toda solución contiene uno o más
proyectos. Cuando una solución contiene solamente un proyecto, muchas personas utilizan el mismo nombre
para ambos.
Incorporación de una Referencia
Debido 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 seleccione Add Reference (Agregar Referencias).
De manera alternativa, puede ir a la barra del menú y seleccionar Project y luego Add Reference .
Figura 3: Incorporación de una referencia
Se abre la ventana de diálogo Add Reference.
Figura 4: Selección del Proveedor de Datos ODP.NET Administrado
Seleccione Oracle.DataAccess.dll de la lista, luego haga un click en el botón S elect (Seleccionar), y
finalmente click en el botón OK para 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 común es agregar sentencias VB.NET Imports, sentencias C# using, o
sentencias J# import. Técnicamente 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 convención, estas sentencias aparecen cerca o en la parte superior del archivo de códigos, antes del
namespace o declaración 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 incorporación de una sentencia Imports o using.
Conexión de Cadenas y Objetos
Una cadena de conexión de Oracle es inseparable de la resolución de nombres de Oracle. Supongamos que
teníamos 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 información de conexión de la dirección de la base de datos para el cliente. Para
utilizar el OraDb definido en el archivo tnsnames.ora que se muestra arriba, usted debería 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 conexión para obviar la necesidad del archivo tnsnames.ora. Simplemente
reemplace el nombre del alias con el nombre que se definiría 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 contraseña están incorporados en la cadena de
conexión en texto limpio. Este es el enfoque más simple para crear una cadena de conexión. No obstante,
desde una perspectiva de seguridad, el enfoque de texto limpio no es tan aconsejable. En particular, usted
debe comprender que el código de aplicación.NET compilado es solo apenas más seguro que los archivos de
código de origen del texto limpio. Descompilar archivos .NET DLL y EXE y ver el contenido del texto limpio
original es muy fácil. (En realidad, la solución adecuada es la encriptación, pero ese tema implicaría una
digresión para nuestro debate.)
Luego, debe representar un objeto de conexión a partir de la clase de conexión. La cadena de conexión debe
estar relacionada con el objeto de conexión.
Dim conn As New OracleConnection(oradb) ' VB.NET
OracleConnection conn = new OracleConnection(oradb); // C#
Observe que la cadena de conexión se relaciona con el objeto de conexión 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.NET
conn.ConnectionString = oradb
OracleConnection conn = new OracleConnection(); // C#
conn.ConnectionString = oradb;
Luego de relacionar una cadena de conexión con un objeto de conexión, utilice el método Open para realizar
la conexión real.
conn.Open() ' VB.NET
conn.Open(); // C#
Más adelante abarcaremos el manejo de errores.
Objeto Command
El 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
número de departamento (DEPTNO) es 10.
Dim sql As String = "select dname from dept where deptno = 10" ' VB.NET
Dim 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 métodos para ejecutar el texto command. Existen distintos métodos que son adecuados para
distintos tipos de comandos SQL.
Recuperación de un Valor Escalar
Recuperar datos de una base de datos puede lograrse a través de la representación de un objeto
OracleDataReader y utilizando el método 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 Basic
dr.Read()
Label1.Text=dr.Item("dname") ' recuperar por nombre de columna
Label1.Text=dr.Item(0)'recuperar la primera columna en la lista de
selección
Label1.Text=dr.GetString(0) ' emitir un tipo de datos.NET
Label1.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 están 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 columna
label1.Text=dr.GetString(0).ToString();//emitir un tipo de datos.NET
label1.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 también 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 ejecución .NET
intenta implícitamente 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 conversión implícita falla, generando una
excepción. Pero incluso cuando funciona, es aún mejor utilizar las conversiones explícitas de los tipos de
datos en vez de la conversión implícita de los tipos de datos.
A continuación observamos una conversión explícita a número entero:
Label1.Text = CStr(dr.Item("deptno"))
' Número entero de Visual Basic para la conversión de cadena
C# no es tan inflexible como Visual Basic respecto de las conversiones implícitas. Usted se encontrará
realizando conversiones explícitas:
label1.Text = dr.GetInt16("deptno").ToString(); // C#
Puede explícitamente convertir matrices y valores escalares.
Métodos Close y Dispose
El método Close o Dispose del objeto de conexión deberían invocarse para cerrar la conexión a la base de
datos cuando dicha conexión ya no es necesaria. El método Dispose invoca al método Close.
conn.Close()
' Visual Basic
conn.Dispose() ' Visual Basic
conn.Close();
// C#
conn.Dispose(); // C#
Alternativamente, C# ofrece una sintaxis especial que permite disponer automáticamente de una conexión
cuando ésta se encuentra fuera del alcance. La clave using activa esta característica.
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 método Dispose; y OracleDataReader incluye un método Close y
Dispose. Cerrar y disponer de objetos .NET libera recursos del sistema, garantizando un desempeño más
eficiente de las aplicaciones, lo cual es especialmente importante en condiciones de mucha carga. Usted
puede experimentar algunos de los conceptos aprendidos aquí en Lab 1 (Recuperación de Datos de la Base
de Datos) y en Lab 2 (Incorporación de Interactividad).
Manejo de Errores
Cuando ocurre un error, las aplicaciones .NET deben manejar este error correctamente y mantener al usuario
informado a través 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 If
Catch 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 aplicación real, utilice el código 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 fácil 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 solución es agregar una sentencia Catch adicional para capturar los errores de base de datos
más 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 Select
Catch 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 sentencias Catch en el código de muestra de arriba. Si no hay ningún error de Oracle para
capturar, la primera sentencia Catch se saltea, dejando que cualquier otro tipo de error que no sea de Oracle
sea capturado por la segunda sentencia Catch. Las sentencias Catch deben ordenarse en el código de la
más específica a la más general. Luego de implementar el código de manejo fácil de excepciones, aparece el
mensaje de error ORA-12545 como se muestra a continuación:
Figura 7: Mensaje de error comprensible
para el usuario advirtiendo sobre un error
ORA-12545
El bloque de código Finally siempre se ejecuta independientemente de que se produzca un error o no. De
ahí proviene el código cleanup. Si no utiliza Using ni using, debería disponer de su conexión y de otros
objetos en el bloque de código Finally.
Recuperación de Múltiples Valores Utilizando DataReader
Hasta el momento nuestros ejemplos han mostrado cómo recuperar un valor único. OracleDataReader puede
recuperar los valores de múltiples columnas y múltiples filas. Primero analicemos la consulta de múltiples
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 utilizando
dr.Item(2) o dr.Item("loc").
Aquí vemos un fragmento del código 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 múltiples filas:
select deptno, dname, loc from dept
Para procesar múltiples filas emitidas desde OracleDataReader, se requiere algún tipo de construcción de
loop. Además, siempre es mejor un control que pueda desplegar múltiples 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 código:
.
While dr.Read() ' Visual Basic
ListBox1.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 (Recuperación de Múltiples Columnas y Filas con OracleDataReader) destaca algunos de estos
conceptos.
Resumen
Este artículo ha presentado el proceso que debe seguirse para acceder a las bases de datos de Oracle
utilizando los lenguajes de programación VS.NET. Ahora tendrá la capacidad de conectarse a la base de
datos y recuperar múltiples filas y columnas.
Lab 1: Recuperación de Datos desde la Base de Datos
1.
2.
Comenzamos con el requisito de haber creado un proyecto y haber agregado una referencia como se
muestra anteriormente en este artículo.
Ahora incorporaremos el control button y el control label en el formulario Windows. Asegúrese de
dejar espacio arriba de los controles para permitir las incorporaciones que serán realizadas en Lab 2.
Figura 8: Formulario Lab 1 con controles button y label
3.
Agregue el código para recuperar los datos de la base de datos de Oracle y desplegar los resultados
en el formulario. Coloque el código en un controlador de eventos click para button. La forma más
sencilla de comenzar con esta tarea es haciendo doble click con el botón 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 declaración Public Class o las sentencias C#
using antes de la declaración del namespace.
5. Imports System.Data
' VB.NET
6. Imports Oracle.DataAccess.Client ' ODP.NET Oracle managed provider
7.
8.
9. using System.Data;
// C#
10. using Oracle.DataAccess.Client; // ODP.NET Oracle managed provider
11. Agregue la versión VB.NET del controlador de eventos click entre las sentencias Private Sub y End
Sub (asegúrese de reemplazar OTNSRVR con el nombre de host de su servidor):
12.
13.
14.
15.
16.
17.
18.
19.
20.
Dim oradb As String = "Data Source=(DESCRIPTION=(ADDRESS_LIST=" _
+ "(ADDRESS=(PROTOCOL=TCP)(HOST=OSRVR)(PORT=1521)))"
+ "(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL)));" _
+ "User Id=scott;Password=tiger;"
Dim conn As New OracleConnection(oradb) ' VB.NET
conn.Open()
Dim cmd As New OracleCommand
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
cmd.Connection = conn
cmd.CommandText = "select dname from dept where deptno = 10"
cmd.CommandType = CommandType.Text
Dim dr As OracleDataReader = cmd.ExecuteReader()
dr.Read() ' remplace esta sentencia en el próximo lab
Label1.Text = dr.Item("dname") ' or dr.Item(0), remove in next lab
dr.Dispose()
cmd.Dispose()
conn.Dispose()
Agregue el siguiente código C# al controlador de eventos click entre { and } llaves para el controlador
de eventos click de button (asegúrese 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 próximo lab
label1.Text = dr["dname"].ToString(); // remove in next lab
dr.Dispose();
cmd.Dispose();
conn.Dispose();
32. Ejecute la aplicación. Haga click en button. Usted debería ver lo siguiente:
Figura 10: Datos recuperados con éxito
Lab 2: Incorporación de Interactividad
Ahora que los fundamentos del acceso a la base de datos se implementaron en el código, el próximo paso es
incorporar la interactividad a la aplicación. En lugar de ejecutar una consulta hard coded, se puede agregar un
control textbox para aceptar el input del usuario para el número de departamento (es decir, DEPTNO).
1.
Incorpore el control textbox y otro control label al formulario como se muestra abajo. Determine la
propiedad de texto del control Label2 en Enter DEPTNO: y asegúrese de que la propiedad Text
de TextBox1 no esté sujeta a ningún valor.
Figura 11: Formulario Lab 2 con controles button y label.
2.
Modifique el código que defina la cadena de selección:
3.
4.
5.
6.
7.
8.
9.
cmd.CommandText = "select dname from dept where
deptno = " + TextBox1.Text 'VB.NET
cmd.CommandText = "select dname from dept where
deptno = " + textBox1.Text; // C#
10. Ejecute la aplicación. Pruebe la aplicación ingresando 10 para el deptno. Vuelva a probar la
aplicación ingresando un DEPTNO inválido (por ej., 50). La aplicación finalizará.
Figura 12: Una excepción inmanejable
11. Modifique su código para evitar cualquier error cuando se ingrese un DEPTNO inválido. Recuerde
que el método ExecuteReader en verdad devuelve un objeto. Reemplace la línea que contiene
dr.Read con las siguientes sentencias.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
If dr.Read() Then ' Visual Basic
Label1.Text = dr.Item("dname").ToString()
Else
Label1.Text = "deptno not found"
End If
if (dr.Read()) // C#
{
label1.Text = dr["dname"].ToString();;
}
else
{
label1.Text = "deptno not found";
}
29. Pruebe la aplicación ingresando un DEPTNO que no existe. Ahora la aplicación ya no se cierra.
Ingrese la letra A en vez de un número y haga click en button. La aplicación se cierra. Claramente,
nuestra aplicación necesita un mejor enfoque de manejo de errores.
Aunque podría discutirse que la aplicación no debería permitir al usuario realizar inputs inválidos que
pudieran causar errores, en última instancia la aplicación debe tener un sólido controlador de errores
incorporado. No todos los errores pueden prevenirse, por lo tanto debe implementarse un controlador
de errores.
Lab 3: Recuperación de Múltiples Columnas y Filas con DataReader
Ahora que se ha recuperado un valor único, el próximo paso es recuperar múltiples 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 tamaño del control para cubrir el mayor ancho
posible del formulario como se muestra abajo.
Figura 13: Formulario con ListBox incorporado
2.
Elimine la cláusula where de la consulta e incorpore las columnas adicionales:
3.
4. cmd.CommandText = "select deptno, dname, loc from dept" ' VB.NET
5.
6. cmd.CommandText = "select deptno, dname, loc from dept"; // C#
7.
Los resultados de la consulta serán leídos en un while loop y completarán el control ListBox.
Modifique su código 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 Basic
14. conn.Open()
15.
16. Dim cmd As New OracleCommand
17. cmd.Connection = conn
18. cmd.CommandText = "select deptno, dname, loc from dept";
19. cmd.CommandType = CommandType.Text
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
Dim dr As OracleDataReader = cmd.ExecuteReader()
While dr.Read()
ListBox1.Items.Add("The " + dr.Item("dname") + _
" department is in " + dr.Item("loc"))
End While
dr.Dispose()
cmd.Dispose()
conn.Dispose()
Modifique su código 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 aplicación. El ListBox debería completarse con todos los nombres de localizaciones y
departamentos de la tabla DEPT. Las descargas de códigos presentan controladores de errores
implementados.
Descargar