ALTER DOMAIN CHECK in POSTGRES - postgresql-13

The syntax for ALTER DOMAIN IN POSTGRES DDL allows for CHECK condition to be changed provided a named constraint exists.
How should one change a CHECK defined in a domain which does not specify a named constraint
Say the original constraint is as follows
CREATE DOMAIN ref_type_type varchar(5) CHECK (VALUE IN ('00001', '00002', '00003'));
As part of alteration, an additional value '00004' is needed to be added as valid.

The check constraint will still have a name - just a generated one. You can retrieve the name using the following query:
select t.typname as domain_name,
c.conname as constraint_name
from pg_catalog.pg_type t
join pg_catalog.pg_constraint c on t.oid = c.contypid
where t.typtype = 'd'
and t.typnamespace = 'public'::regnamespace --<< or whatever schema you use
and t.typname = 'ref_type_type'
But you can't really alter the check constraint, you need to drop and re-create it.

Related

Oracle - constraint to check a value exists in another column

I need to check if the value of 'montant' exists in the column 'prix' of the table 'service' in order to add this value in the table.
This is what I tried so far :
ALTER TABLE abonnement ADD CONSTRAINT montant_inclus CHECK(montant in (select prix from service));
Here is the error I got :
ORA-02251: subquery not allowed here
As per error it's clear Oracle is not allowing to do
Subqueries in CHECK constraints.
This is doable by JOIN.
ALTER TABLE abonnement ADD CONSTRAINT montant_inclus CHECK(EXISTS (SELECT 1 FROM service WHERE service.prix = abonnement.montant));
It's also possible using Trigger and other ways.
similar question answer 1
how to add constraint via trigger

trying to create a column but it also creates a default constraint with useless name

I am using the alter command to add a column with not null and default value to the sql,
but when i run it it also creates the constraint with some silly words, how can i use the alter command to add the column also and also add the constraint with it with the name i specify
my alter is like this
ALTER TABLE users
ADD role bit not null default 0;
Should the combined constraint with same alter command will work, not sure how to add it
You can include the constraint name within the statement as follows:
ALTER TABLE users ADD role bit NOT NULL CONSTRAINT DF_Users__Role DEFAULT (0);
There are examples in the docs online, albeit a long way down the page: B. Adding a column with a constraint

I want to add a check in database column, so that people who enter data into it should be in capital and trimmed

The situation is: I have a column in a database table where people enter data using SQL scripts directly (without any web page).
I want to put a restriction on that column to ensure if anyone enters data it is trimmed and capitalized, otherwise it should not accept it.
Or it should do it automatically.
Yours sincerely.
Try this one. Replace 'myTableName' with your table name. Replace 'myColumnName' with your column name. NOTE : UpperCaseCheck is the name of the constraint, as well as DataLenCheck.
--UpperCaseCheck
ALTER TABLE myTableName
ADD CONSTRAINT UpperCaseCheck CHECK(myColumnName = UPPER(myColumnName) COLLATE Latin1_General_CS_AS);
-- DataLenCheck constraint
ALTER TABLE myTableName
ADD CONSTRAINT DataLenCheck CHECK(DataLength(myColumnName) = DataLength(Rtrim(LTrim(myColumnName))))
-- Instead of two constraint, we can use only one
ALTER TABLE myTableName
ADD CONSTRAINT UpperCaseCheckAndDataLenCheck CHECK(myColumnName = UPPER(myColumnName) COLLATE Latin1_General_CS_AS
AND DataLength(myColumnName) = DataLength(LTrim(Rtrim(myColumnName))))
SQL Server 2017
select upper(trim(#param_name))
Older versions
select upper(rtrim(ltrim(#param_name)))

How can we know what kind of a constraint was dropped in Sql Server without maintaining our own copy of sys.objects?

So, I created the following DDL trigger:
CREATE TRIGGER [BeforeAlterTable] ON DATABASE FOR ALTER_TABLE
AS
BEGIN
SELECT * FROM sys.objects WHERE Name = 'PK_MyTable'
END
The problem is that when PK_MyTable primary key is dropped, the trigger outputs empty result set - the information about the primary key is already gone from the sys.objects view.
This could be resolved by maintaining our own copy of sys.objects (a subset of type = 'PK' would suffice), but I would like to avoid it.
Anyway to make it work?
EDIT 1
Note that the question is about deducing the kind of the constraint, not its name or the table it belongs too. These are found in the EVENTDATA() function result. What is not found there is the kind of the constraint.

Change primary key value in Oracle

Is there a way to change the value of a primary key which is referenced by another table as foreign key?
An easier alternative is to insert a new row and delete the old one. (Update any referencing rows in other tables before you do the delete)
There isn't an in-built UPDATE CASCADE if that's what you're after. You'd need to do something like disable any FK constraints; run UPDATE statements; re-enable the constraints.
Note that updating Primary Keys is (usually always) a bad idea.
You will need to disable the foreign key constraints before changing the primary key values, and then re-enable them afterwards.
If you actually want to implement "update cascade" functionality instead then see Tom Kyte's Update Cascade package
It is possible even without disabling constraints, in case if you would like only to swap keys (which is also a change's subset, so it might be still answer to your question). I wrote an example here: https://stackoverflow.com/a/26584576/1900739
update MY_TABLE t1
set t1.MY_KEY = (case t1.MY_KEY = 100 then 101 else 100 end)
where t1.MYKEY in (100, 101)
Yes, there is a way to do the cascading update in Oracle, even within a transaction (which does not hold true for the option of enabling/disabling constraints). However, you'll have to implement it yourself. It can be done via before/after-row-update triggers.
It is possible due to the fact that triggers are executed before any constraints are checked. (Well, at least in Oracle 11.2 it was true. Haven't checked against 12.1, but I honestly believe it hasn't changed.)
Anyway, as said before, updating primary keys is usually a bad idea.
The principe is to disable constrainsts, run your udates based on key, and reenable the constrainst. That for here is a script that run the disable script :
(Assuming all the constraints are enable at start)
Generate the script
SELECT 'alter table ' || uc.table_name|| ' disable constraint '|| uc.constraint_name|| ' ;'
FROM user_constraints uc inner join user_cons_columns ucc on uc.constraint_name = ucc.constraint_name where column_name = 'MYCOLUMN_USED_AS_FOREIGN_KEY' and constraint_type='R'
Copy/paste the generated script and run it
alter table MYTABLE1 disable constraint FK_MYTABLE1 ;
alter table MYTABLE2 disable constraint MYTABLE2 ;
alter table MYTABLE3 disable constraint FK3_MYTABLE3 ;
...
Then update your PK values :
update MYTABLE1 set MYFIELD= 'foo' where MYFIELD='bar';
update MYTABLE2 set MYFIELD= 'foo' where MYFIELD='bar';
update MYTABLE3 set MYFIELD= 'foo' where MYFIELD='bar';
commit;
Generate the enable constraints script :
SELECT 'alter table ' || uc.table_name|| ' enable constraint '|| uc.constraint_name|| ' ;'
FROM user_constraints uc inner join user_cons_columns ucc on uc.constraint_name = ucc.constraint_name where column_name = 'MYCOLUMN_USED_AS_FOREIGN_KEY' and constraint_type='R'
Another way you can do this is by changing the foreign key constraints so that the validation of the constraint is deferred until you commit - i.e. instead of Oracle validating the constraints statement-by-statement, it'll do it transaction-by-transaction.
Note you can't do this via the "alter table" statement, but you can drop and re-create the foreign key constraint to be deferrable, i.e:
alter table <table name> drop constraint <FK constraint name>;
alter table <table name> add constraint <FK constraint name> foreign key .... initially deferrable;
Once you've done that, just update the tables in whatever order you like, and commit - at which point, either:
All your FK constraints are satisfied, and everyone's happy; or
You've violated a FK constraint somewhere - you'll get an error and you'll have to fix up the data and commit, or rollback.
Note this feature is quite safe, as Oracle does not allow dirty reads so they'll only see the effects of your updates once you commit. So from the perspective of every other session, referential integrity appears to be preserved.
Also, this is a once-off change, so you don't need to go executing DDL each time you want to go updating the primary keys.

Resources