views:

389

answers:

2

I would like to better understand the differences for checking uniqueness in a record before an INSERT between using CHECKSUM (with unique constraints) versus self-referencing table statement like the one below. What scenarios would pose one option to be the best choice over the other, and for what reasons?

Requirement: Each set of columns need to be unique from every record in the table, which is why I put this statement together; to check for all columns in one call to the database.

INSERT INTO tblTable
(Column1, Column2, Column3, Column4, Column5, Column6) 
SELECT 
@Column1, @Column2, @Column3, @Column4, @Column5, @Column6 
WHERE NOT EXISTS 
    (SELECT DISTINCT 
     t1.Column1, 
     t1.Column2,  
      t2.Column3, 
      t2.Column4, 
       t3.Column5, 
       t3.Column6 
    FROM tblTable t1 
     JOIN tblTable t2 ON (t1.UID = t2.UID)
     JOIN tblTable t3 ON (t1.UID = t3.UID)
    WHERE
     t1.Column1 = @Column1 and 
     t1.Column2 = @Column2 and 
      t2.Column3 = @Column3 and 
      t2.Column4 = @Column4 and 
       t3.Column5 = @Column5 and 
       t3.Column6 = @Column6)
+1  A: 

Using a Unique constraint will guarantee that the constrained data is unique regardless of how it is inserted (by hand from query editor, via a stored procedure, via an ORM tool or any other layer of abstraction). It doesn't rely on developers remembering to check with every query they write that they aren't violating the principle. It also makes your queries less convoluted and easy to read. No chance of mistakes.

Dan Diplo
When using unique constraints in a table, how and where would I handle notifying the user that these values are not available for their use since they're already used?
Cameron
It depends on both the SQL variant you are using and also the programming language you are using. If it was SQL Server / .NET you could catch an SqLException and then use that to generate your error message. See http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlexception.aspx
Dan Diplo
+1  A: 

Why would you need more than this NOT EXISTS clause?

NOT EXISTS 
    (SELECT *
    FROM tblTable t1 
    WHERE
        t1.Column1 = @Column1 and 
        t1.Column2 = @Column2)

Seriously.

I've never thought it through... but the self join implies unique checks over more than one row (or unique over a group of rows? or unique over parent/child rows?). Which would invalidate the unique row concept...

Edit, on 2nd reading

Just use a standard unique constraint.

No need for CHECKSUM, which does not guarantee uniqueness anyway.

However, there is a small chance that the checksum will not change. For this reason, we do not recommend using CHECKSUM to detect whether values have changed, unless your application can tolerate occasionally missing a change

gbn
That's why I wrote the sample query that way - the "self join implies unique checks over more than one row".
Cameron