2009-03-09 8 views
11

Mi chiedevo se qualcuno avesse un modo più elegante per verificare eccezioni chiave univoche da SQL in .NET diverse dall'analisi del messaggio di errore? In questo momento sto chiamando lo sproc in SQL, quindi utilizzando un blocco catch try in .NET. Nel blocco catch try analizzo il messaggio di errore ed è un errore di chiave Univoco. Lancio un'istanza di un errore personalizzato nella classe chiamante, se non lancio l'eccezione originale la classe chiamante. Questo mi sembra terribilmente inefficiente.Catching eccezioni chiave univoche di SQL in .NET

risposta

24

Se si cattura una SqlException, si dovrebbe essere in grado di enumerare la raccolta "Errori" contenente un numero di oggetti "SqlError".

L'oggetto SqlError include, tra le altre cose, proprietà come "Class" e "Number": le violazioni delle chiavi univoche sono class = 14 e number = 2601. Verificare che tali numeri individuino con precisione il proprio errore.

Quelli sono gli stessi codici di errore che si ottiene quando si tenta di eseguire la query in SQL Management Studio:

Msg 2601, livello 14, stato 1, riga 1
Impossibile inserire la riga chiave duplicata in oggetto ..........
La dichiarazione è stata chiusa.

Il "messaggio" si traduce nella proprietà "Numero" su SqlError, il "Livello" in "Classe".

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

In questo modo, è possibile identificare facilmente ed ESATTAMENTE un errore "limitazione univoca violata".

Marc

+0

Penso che il controllo per "numero" (senza classe) sia sufficiente. La "classe" sembra solo dire la gravità. – slartidan

1

Risposta ovvia: tentare di recuperare quel valore dal database prima di inserirlo (o aggiornarlo) e avvisare l'utente prima di eseguire l'inserimento.

Risposta alternativa: verificare l'unicità all'interno dell'SP e restituirlo come un messaggio di errore dall'SP, quindi non è necessario analizzare eventuali errori. Sono tutti cattivi.

2

Perché non si interroga solo se esiste l'ID univoco? È meglio quindi ottenere l'eccezione.

+0

+1 per evitare l'eccezione in primo luogo. Il tuo stored proc dovrebbe verificare la presenza e restituire un risultato noto se la chiave esiste già, nel qual caso puoi gestire senza generare un'eccezione, che è molto più efficiente. –

+9

Se non si rende serializzabile la procedura memorizzata, non si verificheranno problemi di concorrenza con l'aumento del numero di transazioni al secondo? In altre parole, tra il controllo che la riga non esiste e l'inserimento, un altro utente ha già inserito la riga. Per non parlare del sovraccarico di fare il controllo in primo luogo. IMHO è molto meglio semplicemente inserire e gestire l'errore da .NET. –

2

Il messaggio di errore dell'analisi è una cattiva idea. Ad esempio, se si utilizza Ms Ms, il messaggio può essere localizzato (in una lingua diversa) e non si trova la parola che si sta cercando.

Se si utilizza Ms SQL, è necessario verificare la proprietà Number.

+0

Ciò che mi infastidisce è che SQL Server non distingue tra una violazione della chiave primaria e una violazione del vincolo univoco quando si tratta di codici di errore, in quanto entrambi restituiscono 2627. Una violazione indice univoca restituisce 2601, ma la maggior parte delle volte sono utilizzando PK o UC.Qualche idea su come segnalare una violazione PK da una violazione UC in un modo sicuro per la localizzazione? –