5

Immaginiamo che avete ottenuto una violazione di vincolo indice univoco nel MSSQL 2008 del database come questo:Bisogno di un modo per intercettare solo un'eccezione chiave duplicata MSSQL

Violation of PRIMARY KEY constraint 'PK_ManufacturerCode'. Cannot insert duplicate key in object 'dbo.ManufacturerCode'. The duplicate key value is (8410179) 

Attualmente sto manipolazione di questo un'eccezione da una globale gestore di eccezioni in un thick client (scritto in Delphi 6 usando ADO, ma non importa, prevedo di usare C# .NET in futuro) e il messaggio di eccezione viene aggiunto ad una casella di log.

Ma voglio gestire personalmente questa specifica chiave duplicata e visualizzare un messaggio di errore appropriato in un client utilizzando il proprio testo del client spesso. Ho potuto analizzare il messaggio di errore per partita, ma non voglio fare questo per due motivi:

  • Questo non è un modo giusto per fare la cosa - è meglio fare affidamento su alcuni codici di errore;
  • La thick client ha lo scopo di utilizzare varietà di versioni server MSSQL in diverse lingue che possono avere diversi testi di errore

Non mi rallegrare per fare il lavoro con i ritorni con i codici di uscita personalizzato o costantemente chiamare un stored procedure speciali per verificare la presenza di duplicati.

risposta

3

In ADO, si accede alla proprietà Errors delle connessioni dopo un errore e si esamina la proprietà per ottenere i numeri di errore specifici di SQL Server.

Quando si passa a .NET, lo stesso numero è esposto come il Number proprietà di SqlException o SqlError

Tuttavia, trovare i numeri di errore specifici può essere un po 'di un lavoro di routine - Per chiave duplicato, è il numero di errore 2627.

+0

La tua risposta mi sembra buona, ma ... potrei rilevare in questo modo quale violazione di colonna si è verificata? – Learner

3

AFAIK, l'unico modo per distinguere un'eccezione di chiave duplicata è analizzare il messaggio di errore.

Una soluzione migliore consiste nel prevenire l'eccezione della chiave duplicata in primo luogo. Scrivere l'inserto di non inserire chiavi duplicate, e verificare con @@rowcount se è stata aggiunta una riga:

insert YourTable 
     (id, col1, col2) 
select 1, 'a', 'b' 
where not exists 
     (
     select * 
     from YourTable yt2 
     where yt2.id = 1 
     ) 

if @@rowcount = 0 
    -- Duplicate key! 
+0

La domanda riguarda piuttosto la comunicazione tra MSSQL e thick client (la cosa che viene quando @@ rowcount = 0) rispetto a come rilevare la chiave duplicata. – Paul

+1

Ho interpretato il tuo titolo 'Ho bisogno di un modo per intercettare solo un'eccezione di chiave duplicata in MSSQL' poiché ti interessano solo le eccezioni chiave duplicate. Penso che Andomar l'abbia fatto, quindi potresti voler riformulare la domanda. –

+0

Nota che dovrai gestire il blocco correttamente se esiste un accesso simultaneo a 'YourTable'. È possibile che '@@ rowcount' ritorni zero appena prima che qualcun altro inserisca il valore duplicato nella tabella; il codice che presuppone che abbia la tabella bloccata per l'operazione successiva potrebbe non averlo fatto e causerà un errore per la riga duplicata che non era presente quando è successo a controllare. – MikeB

2

Fortunatamente, non c'è bisogno di analizzare il testo. A SqlException ha una proprietà Number. Oberserve, quale numero viene restituito e abbinato su di esso. I numeri sono ben definiti. Puoi anche guardarli tutti in una delle tabelle del catalogo di sistema (non avere il nome a portata di mano).

È una buona idea per voi rilevare solo un errore molto specifico invece di catturare tutti gli SqlException s (ad esempio).

+0

La tua risposta mi sembra buona, ma ... potrei rilevare in questo modo quale violazione di colonna si è verificata? – Learner

+1

No, che purtroppo richiede l'analisi del messaggio. In generale, consiglierei di provare a inserire solo dati noti. Controllare prima di inserire. Gestire gli errori come risposta a dati errati spesso non è la migliore strategia. Meno controllo (come si vede qui) e le eccezioni sono estremamente lente. Si sente anche all'indietro. – usr

+0

Sì, "Controlla prima di inserire" sembra corretto anche a me. Grazie, lo apprezzo davvero ... – Learner

Problemi correlati