Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need a way to intercept only a Duplicate key exception in MSSQL

Let's imagine that you have got a unique index constraint violation in your MSSQL 2008 database like this:

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

Currently I am handling this exception by a global exception handler in a thick client (written in Delphi 6 using ADO, but it does not matter, I plan do use C#.NET in a future) and the exception message is appended to a log box.

But I want to handle this specific duplicate key exception personally and display an appropriate error message in a client using thick client's own text. I could parse the error message for match, but won't do this out of two reasons:

  • This is not a right way to do the thing - it is better to rely on some error codes;
  • The thick client is intended to use variety of MSSQL server versions in diverse languages which may have different error texts

It does not cheer me up to do the job with RETURNs with custom exit codes or constantly calling a special stored procedure to check for duplicates.

like image 809
Paul Avatar asked Dec 31 '12 13:12

Paul


People also ask

How do I ignore duplicate keys in SQL?

Use the INSERT IGNORE command rather than the INSERT command. If a record doesn't duplicate an existing record, then MySQL inserts it as usual. If the record is a duplicate, then the IGNORE keyword tells MySQL to discard it silently without generating an error.

What is the use of @@ error in SQL Server?

Using @@ERROR to conditionally exit a procedure. The following example uses IF...ELSE statements to test @@ERROR after an DELETE statement in a stored procedure. The value of the @@ERROR variable determines the return code sent to the calling program, indicating success or failure of the procedure.

How do I capture an exception in SQL?

To handle exception in Sql Server we have TRY.. CATCH blocks. We put T-SQL statements in TRY block and to handle exception we write code in CATCH block. If there is an error in code within TRY block then the control will automatically jump to the corresponding CATCH blocks.


3 Answers

In ADO, you'd access the connections Errors property after an error occurs, and examine the NativeError property to get the SQL Server specific error numbers.

When you switch to .NET, the same number is exposed as the Number property of SqlException or SqlError

However, finding the specific error numbers can be a bit of a chore - For Duplicate Key, it's error number 2627.

like image 76
Damien_The_Unbeliever Avatar answered Sep 28 '22 02:09

Damien_The_Unbeliever


AFAIK, the only way to tell a duplicate key exception apart is to parse the error message.

A better solution is to prevent the duplicate key exception in the first place. Write the insert not to insert duplicate keys, and check with @@rowcount if a row was added:

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!
like image 26
Andomar Avatar answered Sep 28 '22 02:09

Andomar


Fortunately, you don't have to parse the text. A SqlException has a Number property. Oberserve, what number is being returned and match on it. The numbers are well-defined. You can even look at all of them in one of the system catalog tables (don't have the name handy).

It is a very good idea of yours to catch only a very specific error instead of just catching all SqlExceptions (for example).

like image 39
usr Avatar answered Sep 28 '22 02:09

usr