How to add check constraint on a column in table? - sql

ALTER TABLE Student ADD CONSTRAINT CHK_Student_ID_LENGTH CHECK (LEN([ID]) between 12 and 14);
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_NAME = 'CHK_Student_ID_LENGTH';
alter table Student drop constraint CHK_Student_ID_LENGTH;
I tried to add check constraint using the first statement. It gave me the below error.
[23000][547] The ALTER TABLE statement conflicted with the CHECK constraint "CHK_Student_ID_LENGTH". The conflict occurred in database, table "Student", column 'ID'.
I tried to check if there was any existing constraint with the same name. But I did not get any. Still I tried to drop the constraint. But then it gave the error:
CHK_Student_ID_LENGTH is not a constraint.
But still add constraint statement gives error saying it already exists. Where am I going wrong?

The error message is a little badly worded, but isn't saying what you think it's saying.
It's not saying that there's already a constraint with the same name. It's saying that the constraint is being violated. That means that there is data already in the table that doesn't meet the requirements of the new constraint you're trying to introduce.
You could use the NOCHECK option to create the constraint whilst allowing existing data to violate it. But this is frequently the wrong thing to do. It is usually more sensible to fix the existing data.
Specifying NOCHECK means that the constraint can't be used by the optimizer to eliminate redundant actions that the logic of the constraint would preclude.

You probably have some records in Your table that conflict with that new constraint.
Just find them and UPDATE/DELETE before adding a contraint.
SELECT *
FROM Student
WHERE LEN([ID]) between 12 and 14
Or try to add that constraint without checking existing values using WITH NOCHECK
ALTER TABLE Student WITH NOCHECK
ADD CONSTRAINT CHK_Student_ID_LENGTH CHECK (LEN([ID]) between 12 and 14);
Tip: In migration files I usually add this before adding a new constraint:
IF OBJECT_ID('CHK_Student_ID_LENGTH') IS NOT NULL
ALTER TABLE Student DROP CONSTRAINT CHK_Student_ID_LENGTH
IF OBJECT_ID('CHK_Student_ID_LENGTH') IS NULL
ALTER TABLE Student ADD CONSTRAINT ...
More about ALTER TABLE https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-table-transact-sql?view=sql-server-ver15

Related

The ALTER TABLE statement conflicted with the CHECK constraint

I want to create a foreign key between two database. Happens that the tables have data, so when I'm making the foreign relational there's giving me error.
I found the error happen when your tables have data. So how to not verify existing data?
ALTER TABLE [contrato_sigob].[relacion_institucion_categoria]
ADD CONSTRAINT CHECK_CATEGORIA
CHECK([dbo].[func_CHECK_CATEGORIA](id_categoria)=1);
The error says:
The ALTER TABLE statement conflicted with the CHECK constraint "CHECK_CATEGORIA". The conflict occurred in database "SIGOB_Contraloria", table "contrato_sigob.relacion_institucion_categoria", column 'id_categoria'.
So how to not verify existing data?
You can create a constraint that will not check your existing records by adding WITH NOCHECK:
ALTER TABLE TABLE_NAME WITH NOCHECK
ADD CONSTRAINT ...

Altering constraint in Derby

I don't understand the logic in Derby syntax.
I'm new to SQL, I'm learning now.
I needed to alter a column constraint. I needed to add "not null".
Since I already did an alter on a column for the constraint unique, I thought the syntax will be the same since they are both constraints.
I finally found for not null this link Cannot alter column in existing table in java Derby database
and as I say the same syntax doesn't work for adding a unique constraint to the same column, so my question is: how is the syntax changed for each constraint?
This works:
ALTER TABLE WALLETUSER ALTER COLUMN WALLETUSERNAME NOT NULL;
So why does this not work?
ALTER TABLE WALLETUSER ALTER COLUMN WALLETUSERNAME unique;
And why does this work:
alter table customer add constraint cu1 unique (cust_name);
but this does not:
alter table customer add constraint not null (cust_name);

Unable to add foreign key constraint due to obscure conflict

Trying to run :
ALTER TABLE [dbo].[Table1] ADD
CONSTRAINT [FK_Table1_ScenarioResult]
FOREIGN KEY ([ScenarioResultID]) REFERENCES [dbo].[ScenarioResult] ([ScenarioResultID]) ON DELETE CASCADE
Getting this error :
Msg 547, Level 16, State 0, Line 1
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_Table1_ScenarioResult". The conflict occurred in database "8362", table "dbo.ScenarioResult", column 'ScenarioResultID'.
I have checked :
Constraint does not already exist, and no other exists on same column
The values in the column match in both tables
Types of columns are the same
Tried a different name, also fails
On SQL Server 2008 R2
Any ideas what I could try?
In theory this might work:
ALTER TABLE [dbo].[Table1] WITH NOCHECK ADD
CONSTRAINT [FK_Table1_ScenarioResult]
FOREIGN KEY ([ScenarioResultID]) REFERENCES [dbo].[ScenarioResult] ([ScenarioResultID])
ON DELETE CASCADE
Not sure how you checked for integrity of existing values, but it should be:
SELECT COUNT(*) as Orphans FROM [dbo].[Table1] t
WHERE NOT EXISTS
(SELECT * FROM [dbo].[ScenarioResult] WHERE ScenarioResultID = t.ScenarioResultID)
If "Orphans" is greater then zero you need to clean the data before adding a constraint.
This one was baffling me aswell, and then the penny dropped.
I was trying to create a Foreign Key using "Database Diagrams" in SQL Server 2012, but it refused to let me as it claimed to clash with the foreign key I was trying to create. Huh ?
But, I had accepted the defaults to "Enforce foreign key constraint". But I already had data in the two tables I was attempting to create a foreign key for, and it was breaking the foreign key rule I was trying to make, so SQL Server was rejecting the new key.
The solution (in this particular case) was to change "Enforce foreign key constraint" to "No", or at least until I had cleaned up my data.
Hope this helps.
I had the same issue
I clear the data of the tables where i want to edit the content and add a new foreign key constraint and retry.
It works for me.
I hope it help you.

What can I do about a SQL Server ghost FK constraint?

I'm having some trouble with a SQL Server 2005 database that seems like it's keeping a ghost constraint around. I've got a script that drops the constraint in question, does some work, and then re-adds the same constraint. Normally, it works fine. Now, however, it can't re-add the constraint because the database says that it already exists, even though the drop worked fine!
Here are the queries I'm working with:
alter table individual drop constraint INDIVIDUAL_EMP_FK
ALTER TABLE INDIVIDUAL
ADD CONSTRAINT INDIVIDUAL_EMP_FK
FOREIGN KEY (EMPLOYEE_ID)
REFERENCES EMPLOYEE
After the constraint is dropped, I've made sure that the object really is gone by using the following queries:
select object_id('INDIVIDUAL_EMP_FK')
select * from sys.foreign_keys where name like 'individual%'
Both return no results (or null), but when I try to add the query again, I get:
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "INDIVIDUAL_EMP_FK".
Trying to drop it gets me a message that it doesn't exist. Any ideas?
It means the data is wrong on creation of the FK
That is, you have "EMPLOYEE_ID" values in the INDIVIDUAL child table that don not exist in the parent EMPLOYEE table.
You could use ALTER TABLE ...WITH NOCHECK ADD CONSTRAINT... but then the FK is no use

Can you replace or update a SQL constraint?

I have written the following constraint for a column I've called 'grade':
CONSTRAINT gradeRule CHECK grade IN (‘easy’, ‘moderate’, ‘difficult’),
Is it possible to later update the gradeRule to have different values? For example, 'moderate' and 'difficult' could be changed to 'medium' and 'hard'.
Thanks
You could drop the existing constraint, and add the new constraint with the NOCHECK option. This would allow you to add the constraint even though data in the table violates the constraint. The problem with doing this though would be that you wouldn't be able to update existing records without making them pass the constraint first.
ALTER TABLE SomeTable DROP CONSTRAINT gradeRule
GO
ALTER TABLE SomeTable ADD CONSTRAINT gradeRule ... WITH NOCHECK
GO
Although this is possible, its not usually recommended because of the potential problems with future updates of the data.
Drop the constraint, and then add the replacement constraint.
You can't update a constraint in SQL Server at least.
ALTER TABLE SomeTable DROP CONSTRAINT gradeRule
In addition, you'll need to update the table data before adding the new constraint, so that it meets the new constraint.
If you change the constraint, all of the data currently in the table must meet the constraint. So if you had 2 rows of data with 'moderate' and tried to change the constraint to easy, medium, and hard, it would not let you.
So you would have to make the new constraint (easy, moderate, medium, difficult, hard) or, update the data to the new values - moderate --> medium etc.