SqlException Fecha: 02/Feb/2005 (1 Febrero 2005)
|
Una ventaja del manejo de excepciones es el poder manejar excepciones especializadas o personalizadas, con lo cual, podemos realizar un mejor manejo en el flujo de nuestra aplicaci�n al poder reaccionar ante un error especifico y de �sta manera realizar acciones especificas.
Como ejemplo, utilizaremos la excepci�n SqlException, mediante la cual, podemos recuperar los c�digos de error que Sql Server genera internamente, �stos errores van desde un "Acceso denegado al usuario x" o "Nombre de objeto invalido x" por poner un ejemplo.
SqlException nos expone a trav�s de su propiedad SqlException.Errors una colecci�n que contiene uno o m�s objetos del tipo SqlError, con los cuales, podremos conocer el error exacto que ocurrio en el servidor, utilizando �sta informaci�n construiremos una aplicaci�n a manera de ejemplo, mediante la cual controlaremos los errores basicos que suceden al momentos de realizar la conexi�n hacia la base de datos.
La aplicaci�n nos pedira los siguientes datos, mediante los cuales esperaremos una determinada excepci�n de sql.
Comunmente dentro del manejo de errores unicamenye incluimos el manejador de la excepci�n "general" Exception ,pero en esta ocasi�n dentro de nuestro bloque Try, incluiremos una excepci�n m�s SqlException .
try { //hacer algo } catch (SqlException ex) {//hacer algo } catch(Exception ex) {//hacer algo }A�n cuando la �nica excepci�n que intentamos utilizar ser� SqlException, es recomendable dejar el manejador de las excepciones generales, ya que no siempre (dependiendo de la implementaci�n del bloque try) las exepciones internas ser�n propiciadas por Sql, aunque insisto, eso depende por mucho de la implementaci�n que se tenga.
Si unicamente intentaramos detectar la ejecuci�n a manera general, bastaria con obtener el mensaje de error que genero Sql Server SqlException.Message, para este ejemplo entraremos un poco m�s en detalle y obtendremos el error detallado generado en el servidor, para �sto, tendremos que realizar un for dentro de nuestro bloque Catch para asi obtener todos los errores generados.
catch (SqlException ex) { foreach (SqlError sError in ex.Errors) { //Implementaci�n.....La clase que realmente contiene la informaci�n detallada del error generado es SqlError, para obtener el c�digo de error generado utilizaremos la propiedad number SqlError.Number, �ste c�digo de error es que el Sql Server genero internamente, para ver todos los c�digos de error posibles consulte la documentaci�n de Sql Server. Si bien, en este ejemplo nos limitamos a reemplazar el mensaje de error generado por uno m�s especifico para el usuario, esta no es la �nica utilidad que podemos obtener, por ejemplo, en caso de que el usuario y password sean incorrectos, podriamos guardar una bitacora con el usuario que esta intentando acceder a nuestra base de datos.
Por ejemplo, si intentaramos acceder a un servidor y �ste no fuera encontrado se generaria un Error 17, estos errores los capturaremos dentro de nuestro bloque switch
switch (sError.Number)
{
case 17:
MessageBox.Show("El servidor '" + servidor + "' no existe, por favor verifique el nombre");
break ;
Si el usuario y password fueran incorrectos, el error generado seria el numero 18456, hay que tener especial antenci�n en el caso de que se generen m�s de 1 error, tal es el caso de un usuario el cual este tratando de acceder a una base de datos en la cual no tiene permisos, para �ste escenario primero se generaria un error 4060, el cual pertenece a //Cannot open database requested in login '%.*ls'. Login fails. pero tambien se generara un error 18456 //Login failed for user '%ls'. ya que efectivamente, el acceso fallo, para este caso se pueden tener dos posibles acciones, informar de un error y salir del bucle, o informar de ambos errores.
Por ultimo, la clase SqlError nos provee de varia informaci�n, la cual nos puede llegar a ser �til, para el caso del error 208 //Invalid object name '%ls'." Nombre de objeto invalido, este error podria darse por ejemplo, dentro de una vista, pero para tener una mayor referencia el objeto SqlError, nos da la informaci�n de la linea en la cual ocurrio el error SqlError.LineNumber, al final de cuentas SqlError nos provee de la misma informaci�n que si ocurria un error al ejecutar una sentencia desde el Analizador de Consultas.
Servidor: mensaje 208, nivel 16, estado 1, l�nea 1 El nombre de objeto 'sysobject' no es v�lido.
using System;
using System.Data.SqlClient;
using System.Windows.Forms;
namespace ExcepcionesSql
{
/// <summary>
/// Summary description for DB.
/// </summary>
public class DB
{
/// <summary>
/// Realiza la conexi�n a un servidor Sql Server e intenta ejecutar un determinado comando.
/// </summary>
/// <param name="servidor">Nombre del servidor</param>
/// <param name="usuario">Nombre de usuario</param>
/// <param name="clave">Password del usuario</param>
/// <param name="basedatos">Base de datos en el servidor sql</param>
/// <param name="sqlText">Un comando Sql (Select)</param>
public DB(string servidor,string usuario,string clave,string basedatos,string sqlText)
{
// Se crea la variable que contiene el string de conexi�n
string adoCon = String.Format("Data Source={0};Initial Catalog={1};User Id={2};Password={3}",servidor,basedatos,usuario,clave);
try
{
using (SqlConnection sCon = new SqlConnection(adoCon))
{
sCon.Open();
MessageBox.Show("Se realizo la conexi�n");
SqlCommand sComando = new SqlCommand(sqlText,sCon);
sComando.ExecuteNonQuery();//SOlo para comprobar que la sentencia puede ejecutarse.
MessageBox.Show("Se realizo la consulta");
}
}
catch (SqlException ex)
{
foreach (SqlError sError in ex.Errors)
{
switch (sError.Number)
{
case 17:
MessageBox.Show("El servidor '" + servidor + "' no existe, por favor verifique el nombre");
break;
case 18452: //Login failed for user '%ls'. Reason: Not associated with a trusted SQL Server connection.
MessageBox.Show("Especifique un usuario y password");
break;
case 18456: //Login failed for user '%ls'.
MessageBox.Show("El usuario o password es incorrecto");
break;
case 4060: //Cannot open database requested in login '%.*ls'. Login fails.
MessageBox.Show("El usuario no tiene permisos para acceder a la base de datos '" + basedatos + "'");
break;
case 208: //Invalid object name '%ls'."
MessageBox.Show("El nombre del objeto es incorrecto, para mayor informaci�n consulte la lnea :" + sError.LineNumber);
break;
default:
MessageBox.Show(sError.Message);
break;
}
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
Espacios de nombres usados en el c�digo de este art�culo:
System.Data.SqlClient
Fichero con el c�digo de ejemplo: neo_mx_SqlException.zip - 20.3 KB