Finding reference table from foreign key in SQL Developer - sql

OK so I'm new to SQL and not very familiar with Oracle SQLDev, but the tool that I'm making requires that I access an Oracle database and gather some information. I'm trying to figure what table a foreign key is pointing to.
This database has thousands of tables.
Example:
I got a table (TASKS) that contains the following columns [id, user, task_type, task_group]. The problem is that all of this values are ids which correspond to another table, and the table naming convention is not intuitive.
So how can I find out what table task_type is a pointing to?

select acc.table_name REFERENCING_TABLE_NAME, acc.column_name REFERENCING_COLUMN_NAME
from all_constraints ac1,
all_constraints ac2,
all_cons_columns acc
where ac1.constraint_type = 'P'
and ac1.table_name = :table_name
and ac2.r_constraint_name = ac1.constraint_name
and ac2.constraint_name = acc.constraint_name;
that should work

see my post here (2nd answer) as to how you can add this as an extension in sqldeveloper:
How can I find which tables reference a given table in Oracle SQL Developer?

select table_name, constraint_name, status, owner
from all_constraints
where r_owner = :r_owner
and constraint_type = 'R'
and r_constraint_name in
(
select constraint_name from all_constraints
where constraint_type in ('P', 'U')
and table_name = :r_table_name
and owner = :r_owner
)
order by table_name, constraint_name

Related

SQL query for selecting all pk/fk in a database

I tried searching for a query that gives out all pk and fk of a big database. As I couldn't find any good query I came up with a solution.
SELECT
cols.table_name, cols.column_name, cols.position, cons.status, cons.owner
FROM
all_constraints cons, all_cons_columns cols
WHERE
cols.owner = 'DATABASE_NAME'
AND cons.constraint_type = 'P'
AND cons.constraint_name = cols.constraint_name
AND cons.owner = cols.owner
ORDER BY
cols.table_name, cols.position;
The only thing that has to be changed is 'DATABASE_NAME' into the specific database name!
My question would be if there is an "easier" way to get all primary keys from one big database?
Another version of the query can be used to get the foreign-key relationship with the table as follow:
SELECT constr.table_name,
column_name,
position,
constr.constraint_name,
DECODE (constraint_type, 'P', 'Primary Key', 'Foreign Key') key_type,
(SELECT constr2.table_name
FROM all_constraints constr2
WHERE constr2.CONSTRAINT_NAME = constr.R_CONSTRAINT_NAME) fK_to_table
FROM all_cons_columns conscol, all_constraints constr
WHERE conscol.constraint_name = constr.constraint_name
AND conscol.table_name = constr.table_name
AND CONSTRAINT_TYPE IN ('P', 'R')
--AND constr.table_name = 'MYTEBLE' (your table here)
ORDER BY table_name, constraint_type, position;
output would be in something below format
TABLE_NAME COLUMN_NAME POSITION CONSTRAINT_NAME KEY_TYPE FK_TO_TABLE
ACCOUNT ACCOUNT_ID 1 ACCOUNT_PK Primary Key
ACCOUNT ACCOUNT_TYPE_ID 1 ACCOUNT_FK3 Foreign Key ACCOUNT_TYPE

Check for the existence of a column in v$database in Oracle

I am familiar how to check for a column name in a table or view by using the following query
select count(*)
from user_tab_columns
where table_name = [name of view]
and column_name = [name of column]
But, this doesn't work for a column that I am trying to check for in v$database.
Is there a workaround for this?
v$database is actually a public synonym for the v_$database view owned by sys (checked in Oracle 12).
So to get column information:
You can't use user_tab_columns, because that only considers tables/views owned by the current user. But the view you're interested in is owned by sys.
You can't use the synonym name v$database. You have to use the actual view name: v_$database.
So you can use either dba_tab_columns or all_tab_columns like so:
select count(*)
from dba_tab_columns
where table_name = 'V_$DATABASE'
and column_name = [name of column]
EDIT:
Another way that is less dependant on the actual view name in sys, which I guess could change between Oracle database versions, would be to join with dba_synonyms:
select count(*)
from dba_synonyms s
join dba_tab_columns c
on c.owner = s.table_owner
and c.table_name = s.table_name
and c.column_name = [column name]
where s.owner = 'PUBLIC'
and s.synonym_name = 'V$DATABASE'
Try this
select *
from dba_tab_columns
where table_name = 'V_%DATABASE%'

Finding list of all the tables those use a common column

I have a requirement where i need to find out all the tables those are having a common column.
My requirement is kind of simillar to below Example:
A school Teacher is assigned to many tasks for many divisions. Each of the division is maintained as a table.So all the division tables should have a column that can point to Teacher Id.But the name of the column may be different. For Ex: DivA-TeacherId, DivB-TeacherId .... , DivN-TeacherId
Also there is a table called Teacher which contains the details of teachers.
Table Teacher - Column TeacherId (Primary Key)
The teacher moves out of the school and a new teacher replaces him and takes the same roles and responsibilities of the old teacher.
So here we need to update all the dependancy tables with new teacher.
We may have 100 number of tables. So its difficult to findout all those tables manually .
Is there a query, we can find all those tables which have dependancy upon this column, so that those can be updated with new TeacherId.(Please note that, the naming of this column may not be same in all the dependancy tables.But all those column names may have a common substring "TeacherId")
Please suggest if any query can be used to findout the solution for above one.
Let's understand it with an example.
SQL> SELECT a.owner,
2 a.table_name,
3 b.owner primary_owner,
4 b.table_name primary_table
5 FROM user_constraints a,
6 user_constraints b
7 WHERE a.table_name = 'EMP'
8 AND a.r_constraint_name = b.constraint_name
9 /
OWNER TABLE_NAME PRIMARY_OWNER PRIMARY_TABLE
---------- ---------- --------------- ---------------
SCOTT EMP SCOTT DEPT
SQL>
The above query makes use of the referential integrity. The table DEPT references table EMP. The column names has nothing to do with table reference.
In your case, replace EMP with your table name. And the query will list all the tables referencing your table.
You can read the documentation for *_CONSTRAINTS
select uc.constraint_name fk_ref_to_source,
ucc1.table_name table_ref_to_source,
ucc1.column_name column_ref_to_source,
ucc2.table_name source_table,
ucc2.column_name source_column
FROM user_constraints uc, user_cons_columns ucc1, user_cons_columns ucc2
WHERE uc.constraint_name = ucc1.constraint_name
AND uc.r_constraint_name = ucc2.constraint_name
AND ucc1.position = ucc2.position -- Correction for multiple column primary keys.
AND uc.constraint_type = 'R'
AND ucc2.table_name = 'TEACHER'
ORDER BY ucc1.table_name, uc.constraint_name;
user_constraints contains information about user constraints
user_cons_columns contains information about columns which form the constraint
This query will generate updates for your case:
SELECT 'update ' || ucc1.table_name || ' set ' || ucc1.column_name || ' = newTeacherId ' || ' where ' || ucc1.column_name || ' oldTeacherId;' sql
FROM user_constraints uc, user_cons_columns ucc1, user_cons_columns ucc2
WHERE uc.constraint_name = ucc1.constraint_name
AND uc.r_constraint_name = ucc2.constraint_name
AND ucc1.position = ucc2.position -- Correction for multiple column primary keys.
AND uc.constraint_type = 'R'
AND ucc2.table_name = 'TEACHER'
AND ucc2.column_name = 'TEACHERID';
You cann use the system table ALL_TAB_COLUMNS
select * from all_tab_columns
where column_name LIKE '%Teacher%'

Find if a column has unique constraint

In a hypothetical scenario, I am an user with no table creation privileges. I want to know if a column in a table has UNIQUE CONSTRAINT. Is it possible to look it up in the DICTIONARY? How would I go about it?
Both answers given here miss one way to enforce uniqueness on a column: by creating a unique index (without defining a unique constraint on the column). See these two links (one, two) if you are not familiar with this option.
This check should be performed additionally to the unique constraint check:
select count(*) from
USER_IND_COLUMNS cols
where cols.table_name='YOUR_TABLE_NAME'
and cols.COLUMN_NAME='YOUR_COLUMN';
To check for a unique constraint use the already provided method:
select count(*) cnt
from user_constraints uc
where uc.table_name='YOUR_TABLE_NAME'
and uc.constraint_type='U';
Alternatively you can also look in the ALL_CONSTRAINTS and ALL_IND_COLUMNS views.
for unique constraints you can do something like:
select cons.constraint_type,
all_cols.owner, all_cols.constraint_name,
all_cols.table_name,
all_cols.column_name,
all_cols.position
from all_cons_columns col
inner join all_cons_columns all_cols
on col.owner = all_cols.owner
and col.constraint_name = all_cols.constraint_name
inner join all_constraints cons
on col.owner = cons.owner
and col.constraint_name = cons.constraint_name
where col.owner = 'SCHEMA'
and col.table_name = 'FOO'
and col.column_name = 'ID'
and cons.constraint_type in ('U', 'P')
order by owner, constraint_name, position;
set the owner, table and column of interest and it will show you all constraints that cover that column
Note that this won't show all cases where a unique index exists on a column (as its possible to have a unique index in place without a constraint being present).
example:
SQL> create table foo(id number, id2 number, constraint foo_con unique(id, id2), constraint foo_con2 unique(id));
Table created.
now list all constraints that cover id:
SQL> col column_name format a20
SQL> col constraint_name format a20
SQL> col table_name format a15
SQL> select cons.constraint_type,
2 all_cols.owner, all_cols.constraint_name,
3 all_cols.table_name,
4 all_cols.column_name,
5 all_cols.position
6 from all_cons_columns col
7 inner join all_cons_columns all_cols
8 on col.owner = all_cols.owner
9 and col.constraint_name = all_cols.constraint_name
10 inner join all_constraints cons
11 on col.owner = cons.owner
12 and col.constraint_name = cons.constraint_name
13 where col.owner = user
14 and col.table_name = 'FOO'
15 and col.column_name = 'ID'
16 and cons.constraint_type in ('U', 'P')
17 order by owner, constraint_name, position;
C OWNER CONSTRAINT_NAME TABLE_NAME COLUMN_NAME POSITION
- ------------------------------ -------------------- --------------- -------------------- ----------
U DTD_TRADE FOO_CON FOO ID 1
U DTD_TRADE FOO_CON FOO ID2 2
U DTD_TRADE FOO_CON2 FOO ID 1
select count(*) cnt
from user_constraints
where table_name=your_table_name
and constraint_type='U';
If count = 0 then there is not UNIQUE constraint else there is UNIQUE constraint on your table.
Here is a query that I just tried. It lists each uniqueness constraint, identified by the index that enforces it, and the columns that are unique:
select x.index_name, c.column_name, c.column_position
from USER_INDEXES x join USER_IND_COLUMNS c
on x.index_name = c.index_name and x.table_name = c.table_name
left join USER_CONSTRAINTS uc
on x.index_name = uc.index_name and x.table_name = uc.table_name
where x.status = 'VALID' and
(x.uniqueness = 'UNIQUE' or
uc.constraint_type = 'U' and uc.status = 'ENABLED' and uc.validated = 'VALIDATED')
and x.table_name='<your table name_in_caps>'
order by x.index_name, c.column_position;
It seems to work for primary keys, unique indexes, and added uniqueness constraints.

SQL Query for primary key, its data type, and its column name?

As the title suggest, I was curious if somebody knew how to query for a the primary key of a table, its data type and the name of the primary key column. Earlier today, I asked for the primary key column alone and that works well. However, I'm not sure how to pull up its data type and column name as well. Any help would be appreciated.
Thanks!
This should do it:
SELECT ac.constraint_name, acc.column_name, acc.position
, atc.data_type, atc.data_length
FROM all_constraints ac JOIN all_cons_columns acc
ON (ac.CONSTRAINT_NAME = acc.CONSTRAINT_NAME)
JOIN all_tab_cols atc ON (ac.owner = atc.owner AND
ac.table_name = atc.TABLE_NAME AND
acc.COLUMN_NAME = atc.COLUMN_NAME)
WHERE ac.owner = 'table_owner'
AND ac.table_name = 'your_table'
AND ac.constraint_type = 'P'
ORDER BY acc.position;
Use Query the tables user_tab_columns or all_tab_columns:
select column_name, data_type, data_length from user_tab_columns
where table_name = 'MY_TABLE';
select * from all_tab_columns
where owner = 'THE_SCHEMA_OWNER';