JDBC Metada retrieve Constraint information - oracle

I need information about table and column name from the name of the constraint.
exists someone similar to connection.getMetadata().getX to retrieve the constraint information?
my test case is in Oracle Database, but my best solution I just want to solve with jdbc

If you are talking about foreign key and primary key constraints. The DatabaseMetaData does provide methods for retrieving this information: you can use getImportedKeys(..) and getCrossReference(..) for foreign keys, and getPrimaryKeys(..) and getExportedKeys(..) for primary keys.
Just be careful how you use them: getCrossReference(..) and getExportedKeys are a bit counter-intuitive in my opinion.
If you also need unique constraints, then you should be able to use getIndexInfo(..) with passing true for the parameter unique.

You can get defined constraints information from USER_CONSTRAINTS and ALL_CONSTRAINTS table.
You need to pass required where clause fields.
Example :
select
CONSTRAINT_NAME,
CONSTRAINT_TYPE,
TABLE_NAME,
...
from
USER_CONSTRAINTS
where
CONSTRAINT_NAME like concat(?, '%');

Related

How to get a table-level check constraint in Oracle and PostgreSQL

I want to know if there is some specific way to obtain a table-level check constraint in Oracle and in PostgreSQL.
I can obtain all the check constraints in a table, but I want to obtain only this specific check constraint, I don't know if there is any specific query.
Thanks!
In PostgreSQL there is a System Catalog pg_constraint.
The catalog pg_constraint stores check, primary key, unique, foreign
key, and exclusion constraints on tables. (Column constraints are not
treated specially. Every column constraint is equivalent to some table
constraint.) Not-null constraints are represented in the pg_attribute
catalog, not here.
User-defined constraint triggers (created with CREATE CONSTRAINT
TRIGGER) also give rise to an entry in this table.
Check constraints on domains are stored here, too.
SELECT
*
FROM
pg_constraint
WHERE
contype = 'c' AND -- check constraint
conrelid != 0 AND -- table constraint
conname = 'my_check';
The contype column contains the constraint type, c is for check constraint.
The conrelid column contains the oid of the table this constraint is on, 0 if not a table constraint.
For Oracle basic view is ALL_CONSTRAINTS
Query, to obtain specific constraint in specific table:
SELECT *
FROM all_constraints
WHERE constraint_name LIKE upper('%&your_costraint%')
AND table_name LIKE upper('%&your_table%');

Oracle identify if a delete will cascade

I am working on a legacy oracle database system (10g) and I do not have detailed schema information. I need to find out if deleting a particular record in a table will cause cascading deletes in other tables. I have checked for triggers. But, I am not sure about cascading due to referential constraints. Is there a simple way to identify this?
Assuming you know (or can determine) the foreign key constraint(s) involved, you can look at the DELETE_RULE column from DBA_CONSTRAINTS
SELECT constraint_name, delete_rule
FROM dba_constraints
WHERE r_constraint_name = <<name of the primary key constraint>>
AND r_owner = <<owner of the primary key constraint>>
AND delete_rule = 'CASCADE'
will show you all the foreign key constraints that refer to a particular primary key constraint and will cascade the deletes. If you care about constraints that will do a SET NULL when the parent row is deleted, you could look for rows where the delete_rule was SET NULL as well.
Note that if you do not have privileges on the DBA_CONSTRAINTS table, you can use ALL_CONSTRAINTS instead assuming that you're really only concerned with tables that you have SELECT privileges on.

oracle - drop a constraint defined within

I have a oracle query as -
occupation varchar2(50) CHECK(occupation IN ('student','govt_service','private','business')));
now i need to remove the check constraint so i use the following query-
ALTER TABLE registration drop constraint occupation;
but since i haven't defined the constraint name it says invalid constraint name. Is there any way to delete the constraint ? I guess i can alter the table and add the name of the constraint, then delete it but is there any other way ?
run this query:
select * from all_constraints where table_name = 'REGISTRATION';
And you'll find the constraint name.
EDIT: I also recommend you to have a table Occupations and replace the current constraint with a foreign key. (If you are already want to do this, pls apologize me ). Further, normalising, the Occupations may have IDs and and the foreign should be defined on these ids.
Try querying USER_CONSTRAINTS table for CONSTRAINT_NAME, it must have generated a system name for the constraint you have created.
select * from USER_CONSTRAINTS
where owner='<your_schema>' and CONSTRAINT_TYPE='C';

Oracle unique constraint violation referencing a constraint that doesn't seem to exist

I'm receiving an error that I can't make sense of. The error is pretty straightforward:
ORA-00001: unique constraint (*schema*.*xyz_constraint*) violated
However, what's causing my confusion is the fact that no such constraint seems to exist. It's certainly not defined on the table; the DB in question has almost no referential integrity defined, and the particular table into which I'm inserting data has no key defined.
For what it's worth, I can't find the constraint anywhere in the database:
select *
from all_constraints
where constraint_name like '%xyz_constraint%'
Is there anything I'm overlooking? Thanks.
I had the exact same error and it was not a permissions issue. Rather, the entity turned out to be an INDEX not a CONSTRAINT and I found it with:
SELECT * FROM ALL_INDEXES WHERE INDEX_NAME LIKE '%XYZ_UK1'
...because it did not exist in ALL_CONSTRAINTS or DBA_CONSTRAINTS. Confusing how the error message is the same. I'm running Oracle 11g.
This happens when the constraint belongs to another user and you don't have permissions to it.
Try looking it once again for now from SYS perspective
Schema object names are almost always stored in upper-case. Try
select *
from all_constraints
where constraint_name like '%XYZ_CONSTRAINT%'
ORA-00001 usually happens for duplicate primary keys. Are you sure you don't have one on the table?

How can I drop a "not null" constraint in Oracle when I don't know the name of the constraint?

I have a database which has a NOT NULL constraint on a field, and I want to remove this constraint. The complicating factor is that this constraint has a system-defined name, and that constraint's name differs between the production server, integration server, and the various developer databases. Our current process is to check in change scripts, and an automated task executes the appropriate queries through sqlplus against the target database, so I'd prefer a solution that could just be sent straight into sqlplus.
On my own database, the SQL to drop this would be:
alter table MYTABLE drop constraint SYS_C0044566
I can see the constraint when I query the all_constraints view:
select * from all_constraints where table_name = 'MYTABLE'
but I am not sure how to work with the SEARCH_CONDITION's LONG data type or how best to dynamically delete the looked-up constraint even after I know its name.
So, how can I create a change script that can drop this constraint based on what it is, rather than what its name is?
EDIT:
#Allan's answer is a good one, but I am concerned (in my lack of Oracle expertise) that it may not be universally true that any constraint that might have a system-generated name will have associated with it a way to remove the constraint without having to know its name. Is it true that there will always be a way to avoid having to know a system-named constraint's name when logically dropping that constraint?
alter table MYTABLE modify (MYCOLUMN null);
In Oracle, not null constraints are created automatically when not null is specified for a column. Likewise, they are dropped automatically when the column is changed to allow nulls.
Clarifying the revised question: This solution only applies to constraints created for "not null" columns. If you specify "Primary Key" or a check constraint in the column definition without naming it, you'll end up with a system-generated name for the constraint (and the index, for the primary key). In those cases, you'd need to know the name to drop it. The best advice there is to avoid the scenario by making sure you specify a name for all constraints other than "not null". If you find yourself in the situation where you need to drop one of these constraints generically, you'll probably need to resort to PL/SQL and the data-definition tables.
Try:
alter table <your table> modify <column name> null;
Just remember, if the field you want to make nullable is part of a primary key, you can't.
Primary Keys cannot have null fields.
To discover any constraints used, use the code below:
-- Set the long data type for display purposes to 500000.
SET LONG 500000
-- Define a session scope variable.
VARIABLE output CLOB
-- Query the table definition through the <code>DBMS_METADATA</code> package.
SELECT dbms_metadata.get_ddl('TABLE','[Table Described]') INTO :output FROM dual;
This essentially shows a create statement for how the referenced table is made. By knowing how the table is created, you can see all of the table constraints.
Answer taken from Michael McLaughlin's blog: http://michaelmclaughlin.info/db1/lesson-5-querying-data/lab-5-querying-data/ From his Database Design I class.
I was facing the same problem trying to get around a custom check constraint that I needed to updated to allow different values. Problem is that ALL_CONSTRAINTS does't have a way to tell which column the constraint(s) are applied to. The way I managed to do it is by querying ALL_CONS_COLUMNS instead, then dropping each of the constraints by their name and recreate it.
select constraint_name
from all_cons_columns
where table_name = [TABLE_NAME]
and column_name = [COLUMN_NAME];
Something like that happened to me when I made copies of structures to temporary tables, so I removed the not null.
DECLARE
CURSOR cur_temp_not_null IS
SELECT table_name, constraint_name FROM all_constraints WHERE table_name LIKE 'TEMP_%' AND owner='myUSUARIO';
V_sql VARCHAR2(200);
BEGIN
FOR c_not_null IN cur_temp_not_null
LOOP
v_sql :='ALTER TABLE ' || c_not_null.table_name || ' DROP CONSTRAINT '|| c_not_null.constraint_name;
EXECUTE IMMEDIATE v_sql;
END LOOP;
END;
If constraint on column STATUS was created without a name during creating a table, Oracle will assign a random name for it. Unfortunately, we cannot modify the constraint directly.
Steps involved of dropping unnamed constraint linked to column STATUS
Duplicate STATUS field into a new field STATUS2
Define CHECK constraints on STATUS2
Migrate data from STATUS into STATUS2
Drop STATUS column
Rename STATUS2 to STATUS
ALTER TABLE MY_TABLE ADD STATUS2 NVARCHAR2(10) DEFAULT 'OPEN';
ALTER TABLE MY_TABLE ADD CONSTRAINT MY_TABLE_CHECK_STATUS CHECK (STATUS2 IN ('OPEN', 'CLOSED'));
UPDATE MY_TABLE SET STATUS2 = STATUS;
ALTER TABLE MY_TABLE DROP COLUMN STATUS;
ALTER TABLE MY_TABLE RENAME COLUMN STATUS2 TO STATUS;

Resources