Reputation: 67
So I've got this table where I keep track of Items, there are 3 kinds of items:
I created 3 check constraints for those:
CHECK ([Type]=(1) AND NOT ([PhysDamage]+[ElemDamage])<(1) AND [AttackSpeed]>(0.5))
CHECK ([Type]=(2) AND NOT ([PhysReduction]+[ElemReduction]<(1)))
([Type]=(3) AND ([PhysDamage]+[ElemDamage])=(0) AND [AttackSpeed]=(0) AND ([PhysReduction]+[ElemReduction])=(0));
When I try to add a potion with the following insert;
DECLARE @num int, @Type int, @Name varchar(50), @Description varchar(50), @Gold int
SET @Type = 3
SET @Name = 'Spirit Potion'
SET @Description = 'Restores a bit of Spirit'
SET @Gold = 150
insert into Item(Type, Name, Description, GoldValue) VALUES(@Type, @Name, @Description, @Gold)
I get the following error:
The INSERT statement conflicted with the CHECK constraint "CK_Weapon". The conflict occurred in database "Database", table "dbo.Item".
But it shouldn't trigger this CHECK at all, because Potion Type should be 3!
Is there an easy way for me to alter those CHECKs so it'll only trigger when the Type is the same?
Upvotes: 0
Views: 68
Reputation: 283
You are trying to put 3 constraints onto the same column, hoping that it will only trigger one of them, matching the Type you are inputting. But it will check them all, that's why the CK_Weapon constraint is violated as it is expecting Type = 1.
You might want to try to write a bit of case-logic inside your constraint, like this:
create table [RPGInventory]
(
[Type] tinyint not null
, [PhysDamage] int null
, [ElemDamage] int null
, [AttackSpeed] int null
, [PhysReduction] int null
, [ElemReduction] int null
, constraint ckInventoryType check (1 = iif([Type] = (1)
and not ([PhysDamage] + [ElemDamage]) < (1)
and [AttackSpeed] > (0.5), 1
, iif([Type] = (2)
and not ([PhysReduction] + [ElemReduction] < (1)), 1
, iif([Type] = (3)
and ([PhysDamage] + [ElemDamage]) = (0)
and [AttackSpeed] = (0)
and ([PhysReduction] + [ElemReduction]) = (0), 1, 0)))
)
)
go
Upvotes: 0
Reputation: 239764
You need to reverse the first part of your checks so that they give a "pass" to rows they don't care about. So, e.g. for the Armour check, you should check that either the Type
isn't 2
(so this check constraint doesn't care) Or that (the checks that apply to armour) are passed:
CHECK ([Type]!=(2) OR (NOT ([PhysReduction]+[ElemReduction]<(1))))
Repeat for your other checks. At the moment, you cannot insert any rows since the combination of check constraints require that Type
be simultaneously equal to 1
, 2
and 3
.
Upvotes: 3