Can you replace or update a SQL constraint? - sql

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.

Related

How to add check constraint on a column in table?

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

Constraint after SQL modify

I have two tables:
TableA
TableB
I have a constraint and relation between my tables.
I modify something on my TableA or TableB (for example: change datatype, or add a new column). Should I drop and create the constraint again?
Definitely you don't need to recreate a constraint for new columns.
For datatypes, it depends whether the alteration is on a contrainted column or not. If it is constrainted column, you first need to drop constraint then make alteration and create the constraint again.
Most RDBMS systems do not allow alteration of datatypes on constrainted columns.

SQL statement for making foreign key

ALTER TABLE Chosen_doctor ADD FOREIGN KEY (doctor)
REFERENCES Doctors (name) WHERE areaofexpertise LIKE `General%`
ON DELETE RESTRICT ON UPDATE RESTRICT;
Is this plausible sql statement i want to add to mz foreign key that it should onlz be referenced to doctors name if his area of expertise is general practitioner
FOREIGN KEYs are integrity constraints, not ways to achieve selections.
An FK has the side effect of creating INDEX, but that is for performance, not for filtering.
Filtering is achieved by using a WHERE clause in the SELECT statement.
Also, complex restrictions on DELETE and UPDATE must be handled via WHERE clauses.
In oracle you can create constraint like:
ALTER TABLE suppliers
ADD CONSTRAINT check_supplier_name
CHECK (supplier_name IN ('IBM', 'Microsoft', 'NVIDIA'));
But I didn’t see FK with ‘%like%’. I think in generally rdbms conception is not support FK with ‘like’. You also may create function for your case(task) and add this function in trigger on table before insert for each row .

POSTGRES - Handling several ON CONFLICT constraints/indexes

Have the following in the table where:
CONSTRAINT unique_position UNIQUE (id,city,type)
and
CREATE UNIQUE INDEX unique_position_sat_null ON public."position" (id,city) where type is null
on insert conflict there is currently:
ON CONFLICT ON CONSTRAINT unique_position DO UPDATE SET
.....
How can I incorporate both unique_position and unique_position_sat_null into ON CONFLICT ON CONSTRAINT
Tried:
ON CONFLICT ON CONSTRAINT unique_position DO UPDATE SET
.....,
ON CONFLICT ON CONSTRAINT unique_position_sat_null DO UPDATE SET
.....,
and
ON CONFLICT ON CONSTRAINT unique_position and unique_position_sat_null DO UPDATE SET
.....,
Thank you.
Unfortunately, unique indexes and unique constraints are not the same things in Postgres.
When you define a unique index, not constraint, Postgres doesn't create a constraint with the same name (in case of collisions during INSERTs it will produce error "unique constraint violation" mentioning index' name, but this is a minor bug, see https://www.postgresql.org/message-id/flat/CAH2-Wzn-uXcLgC5uFbqe2rUfmJWP9AxKnMKAEgqU26hbURxk5A%40mail.gmail.com#CAH2-Wzn-uXcLgC5uFbqe2rUfmJWP9AxKnMKAEgqU26hbURxk5A#mail.gmail.com)
So you cannot use index name like it is a constraint name.
You could do ALTER TABLE .. ADD CONSTRAINT .. UNIQUE, but it cannot be unique.
So this can be considered as a not yet implemented feature in Postgres -- either "ON CONFLICT" clause needs to learn how to use index names or ALTER TABLE .. ADD CONSTRAINT .. UNIQUE needs to be patched to allow partial constraints.
I suggest discussing it in pgsql-hackers# mailing list (e.g. if you answer thread mentioned above, explaining your problem, it would be awesome).

Disabling the Not-Nullable field in ORACLE to insert NULL data

I have to add some NULL data into an otherwise not-nullable field. I checked :-
ALTER TABLE <table_name> DROP <default_constraint_name> ;
ALTER TABLE <table_name> ALTER COLUMN <column_name> <data_type> NULL;
ALTER TABLE <table_name> DROP COLUMN <column_name>;
but only the middle one seems fit for my usage because all I want o do is alter instead of . But it does not work. I am using Oracle 11g. Could you suggest anyother method or suggest what mistake I am doing in the 2nd ALTER TABLE SQL?
you can just disable constraint. And then enable it back when you want.
alter table
table_name
ENABLE constraint
constraint_name;
alter table
table_name
DISABLE constraint
constraint_name;
As stated in comment above, it may be a bad idea to allow NULLs in a column that previously did not allow them. Queries or code that already exist may rely on the assumption that the field cannot contain NULL, and could experience various problems if that assumption becomes false (errors if you're lucky, quietly producing incorrect or incomplete results if you're not).
That said, the syntax to simply remove the NOT NULL constraint permanently is:
ALTER TABLE table_name MODIFY column_name NULL;
You can also merely disable the constraint as indicated in another answer. To do this you need the constraint name which you can find by querying USER_CONSTRAINTS. This makes more sense if you expect to enable the constraint later.