tags:

views:

44

answers:

3

Database is MS SQLServer

Data example:

| Name | defaultValue |  value   |
| one  |     true     | valone   |
| one  |     false    | valtwo   |
| one  |     false    | valthree |

I'm after a way of constraining the table such that each 'Name' can only have one row with 'defaultValue' set to true

+1  A: 

Create a computed column like this:

  ALTER TABLE yourtable
  ADD ValueCheck AS CASE defaultValue
     WHEN true THEN 1
     WHEN false THEN NULL
  END

and then add unique constraint for (Name, ValueCheck)

Michael Pakhantsov
I +1ed this but then realised it doesn't work. Unique constraints in SQL Server only allow 1 NULL.
Martin Smith
You are right. :(
Michael Pakhantsov
If yourtable has a key column (eg. keyid), then changing NULL to keyid above should work.
Mark Bannister
(and changing ...when true then 1... to ...when true then 0...)
Mark Bannister
A: 

You can use a TRIGGER to validate this constraint on update or insert events and roll back the transaction if it was invalid.

SubPortal
But make sure you take into account the effects of snapshot isolation http://sqlblog.com/blogs/hugo_kornelis/archive/tags/Isolation/default.aspx
Martin Smith
+1  A: 

I liked Michael's idea but it will only allow you one false value per name in SQL Server. To avoid this how about using

  ALTER TABLE yourtable
  ADD [ValueCheck] AS 
     (case [defaultValue] when (1) then ('~Default#?@') /*Magic string!*/
                 else value  end) persisted

and then add unique constraint for (Name, ValueCheck).

I am assuming that name, value combinations will be unique. If the value column does not allow NULLs then using NULL rather than the magic string would be preferable otherwise choose a string that cannot appear in the data (e.g. 101 characters long if the value column only allows 100 chars)

Martin Smith