2009-03-09 21 views
11

Me preguntaba si alguien tenía una forma más elegante de comprobar excepciones únicas de clave de SQL en .NET además de analizar el mensaje de error. En este momento estoy llamando al sproc en SQL, luego usando un bloque try catch en .NET. En el bloque try catch, analizo el mensaje de error y se trata de un error de clave única. Lanzo una instancia de error personalizado a la clase de llamada, si no, simplemente tiro la excepción original a la clase de llamada. Esto me parece terriblemente ineficiente.Captura de excepciones de clave únicas de SQL en .NET

Respuesta

24

Si detecta una SqlException, debería ser capaz de enumerar la colección "Errores" que contiene un número de objetos "SqlError".

El SqlError tiene entre otras cosas propiedades como "Clase" y "Número" - las violaciones de clave únicas son clase = 14 y número = 2601. Verifique esos números para encontrar su error con precisión.

Esos son los mismos códigos de error que recibe cuando intenta ejecutar la consulta en SQL Server Management Studio:

Msg 2601, nivel 14, estado 1, línea 1
No se puede insertar una fila de clave duplicada en objeto ..........
La declaración ha finalizado.

El "Msg" se traduce en la propiedad "Número" en SqlError, el "Nivel" en "Clase".

try 
{ 
    _cmd.ExecuteNonQuery(); 
} 
catch(SqlException sqlExc) 
{ 
    foreach (SqlError error in sqlExc.Errors) 
    { 
     string msg = string.Format("{0}: {1}", error.Number, error.Message); 
    } 
} 

De esta forma, puede identificar fácil y EXACTAMENTE un error de "restricción única violada".

Marc

+0

Creo que es suficiente verificar el "número" (sin clase). La "clase" parece solo decir la gravedad. – slartidan

1

Respuesta obvia: intente recuperar ese valor de la base de datos antes de insertarlo (o actualizarlo) y notificar al usuario antes de hacer la inserción.

Respuesta alternativa: verifique la exclusividad dentro del SP y devuelva eso como un mensaje de error del SP, entonces no tiene que analizar ningún error. Todos son malos.

2

¿Por qué no solo consulta si existe la identificación única? Es mejor que obtener una excepción.

+0

+1 para evitar la excepción en primer lugar. El proceso almacenado debe verificar la existencia y devolver un resultado conocido si la clave ya existe, en cuyo caso puede manejar sin lanzar una excepción, que es mucho más eficiente. –

+9

A menos que haga que su procedimiento almacenado sea serializable, ¿no se encontrará con problemas de concurrencia a medida que aumente el número de transacciones por segundo? En otras palabras, entre su comprobación de que la fila no existe y su inserción, otro usuario ya ha insertado la fila. Sin mencionar los gastos generales de hacer el cheque en primer lugar. En mi humilde opinión, es mucho mejor simplemente insertar y manejar el error de .NET. –

2

El mensaje de error de análisis es una mala idea. Por ejemplo, si está utilizando Ms SQL, el mensaje puede estar localizado (en otro idioma) y no encontrará la palabra que está buscando.

Si está utilizando MS SQL debe marcar la propiedad Number.

+0

Lo que me molesta de esto es que SQL Server no distingue entre una violación de clave primaria y una violación de restricción única cuando se trata de códigos de error, ya que ambos devuelven 2627. Una violación de índice única devuelve 2601, pero la mayoría de las veces soy usando PK o UC.¿Alguna idea sobre cómo distinguir una violación de PK de una violación de UC de una manera segura para la localización? –

Cuestiones relacionadas