Reputation: 5699
I have a table, I created a composite primary key from field word1 and word2, their data type are both int.
Now I want to avoid records like this:
-------- Word1---------Word2--------------
1 2
2 1
I want to treat - 1 2 - and - 2 1 - as one key.
How can I do this?
Upvotes: 0
Views: 161
Reputation: 146557
For every new row to be inserted, if word1 and word 2 are different values, Always insert them with lower of the two values in word1, and the higher of the two values in word2.
Insert myTable(word1, word2, etc.)
values (case When @word1 < @word2 then @word1 else @word2 End,
case When @word1 < @word2 then @word2 else @word1 End,
etc.)
or use a trigger
Create trigger NoWord1Word2Dupes
On myTable for Insert, Update
As
Begin
If Exists(Select * From MyTable e
join inserted I
on i.Word1 = e.word2
and i.word2 = e.word1)
Begin
Rollback Transaction
Raiserror ('Duplicate exists with swapped word1, word2 values.', 16, 1)
End
End
Upvotes: 1
Reputation: 40359
A check constraint can be used to ensure no "transitive" keys. An example:
CREATE TABLE MyTable
(
Word1 int not null
,Word2 int not null
,constraint PK_MyTable
primary key clustered (Word1, Word2)
,constraint CK_MyTable__KeyCheck
check (Word1 < Word2)
)
This prevents any rows where Word2 is less than or equal to Word1. (If Word1 = Word2 is alloed, makey it check (Word1 <= Word2)
This does leave a possible indexing problem: to find all rows referencing value N, you have to check in both columns...
Upvotes: 0
Reputation: 85116
I think you would need to create a CHECK constraint that calls a UDF that performs this check. As far as I know there is no built in way to do this with SQL Server. Something like this:
ALTER TABLE MyTable
ADD CONSTRAINT SwappableUnique CHECK(dbo.SwappableUnique(Word1, Word2))
You can read up more on CHECK constraints here.
Upvotes: 2