How to get Column list of Synonym in Oracle - oracle

I need to get column list of SYNONYMS in ORACLE. The table on which synonym is created is in other schema. Can anyone help me in this problem?

This will return a list of all synonyms in the db:
select * from DBA_SYNONYMS
order by synonym_name
This will return a list of synonyms with a 'like' name:
select * from DBA_SYNONYMS
where upper(synonym_name) like upper('%SYNONYM_NAME_HERE%')
order by synonym_name
Relevant column names in response:
SYNONYM_NAME
TABLE_NAME

Here is a query that I use to see synonyms and their targets.
You will need SELECT privileges on DBA_SYNONYMS and DBA_OBJECTS.
select decode(owner, 'PUBLIC', 'PUBLIC SYNONYM', 'SYNONYM') as objtype,
decode(owner, 'PUBLIC', '', owner) as objowner,
synonym_name as objname,
synonym_name || ' => ' ||
case
when db_link is null then '(' || (
select o1.object_type from dba_objects o1 where o1.owner = table_owner and o1.object_name = table_name and o1.object_type in ('VIEW','TABLE','SYNONYM','SEQUENCE','FUNCTION','PROCEDURE','PACKAGE','MATERIALIZED VIEW','JAVA CLASS','TYPE')
and not exists (select 1 from dba_objects o2 where o2.owner = o1.owner and o2.object_name = o1.object_name and o1.object_type = 'TABLE' and o2.object_type = 'MATERIALIZED VIEW')
) || ') ' || table_owner || '.' || table_name
else decode(table_owner, null, '', table_owner || '.') || table_name || decode(db_link, null, '', '#' || db_link)
end as objdesc
from dba_synonyms
where OWNER != 'PUBLIC'
order by 1,2,3,4
It's a bit wordy, but it makes nice output like this:
OBJTYPE OBJOWNER OBJNAME OBJDESC
------- ----------- -------------------- -----------------------------------------------------------------------------
SYNONYM SYSTEM PRODUCT_USER_PROFILE PRODUCT_USER_PROFILE => (TABLE) SYSTEM.SQLPLUS_PRODUCT_PROFILE
SYNONYM SYSTEM TAB TAB => (VIEW) SYS.TAB
This is actually part of a larger query I use for finding objects of various types, hence some of the redundant information.
I filtered out PUBLIC because that is one huge list.

it's never too late to respond
select * from all_tab_columns#&SYNONYM_DB_LINK
where upper(table_name) like '&TARGET_TABLE_NAME'
order by owner, table_name, column_id

In OWNER is the synonym owner
select * from all_synonyms
where table_owner=upper(:table_owner) and table_name=upper(:table_name)
What do you mean under "Column list"?

select * from all_tab_cols where table_name in
(select TABLE_NAME from all_synonyms where owner = <SCHEMA_NAME> )

Related

How to get table structure in oracle with constraints?

using
DBMS_METADATA.GET_DDL('TABLE','PERSON') from DUAL
is not working. how to get the meta details of whole schema?
In SQL Developer, simply run
ddl person
We'll run the DBMS_METADATA pl/sql block for you.
You can shape the DDL being generated by using the SET DDL command.
Then you can see what we're doing down here in the Log panel.
select DBMS_METADATA.GET_DDL('TABLE', OBJECT_NAME, OWNER)
from all_objects
where owner = :OWNER
and object_name = :NAME
and object_type = 'TABLE'
union all
select dbms_metadata.GET_DEPENDENT_DDL('COMMENT', TABLE_NAME, OWNER)
from (
select table_name, owner
from all_col_comments
where owner = :OWNER
and table_name = :NAME
and comments is not null
union
select table_name, owner
from sys.all_TAB_comments
where owner = :OWNER
and table_name = :NAME
and comments is not null
)
union all
select DBMS_METADATA.GET_DDL('INDEX', INDEX_NAME, OWNER)
from (
select index_name, owner
from sys.all_indexes
where table_owner = :OWNER
and table_name = :NAME
and generated = 'N'
minus select index_name, owner
from sys.all_constraints
where owner = :OWNER
and table_name = :NAME
)
union all
select dbms_metadata.GET_DDL('TRIGGER', trigger_name, owner)
from all_triggers
where table_owner = :OWNER
and table_name = :NAME
Disclaimer: I'm a product manager at Oracle, SQL Developer is one of those products I am responsible for.

get an column name from the table by passing value in oracle

I want a query in oracle to get the column name from the table by passing value.
Means that In most of the case - We write the query like that - select * from table where column = 'value'. But in my case i don't know the column name.
Can any one suggest me.
Thanks in advance...
You can try to build a dynamic query to check all the tables of your DB.
setup:
create table tab1 ( v1 varchar2(100), n1 number, v1b varchar2(100));
create table tab2 ( v2 varchar2(100), n2 number, v2b varchar2(100));
create table tab3 ( v3 varchar2(100), n3 number, v3b varchar2(100));
insert into tab1 values ('Maria', 1, 'aa');
insert into tab1 values ('xx', 2, 'bb');
insert into tab2 values ('yy', 3, 'Maria');
insert into tab2 values ('zz', 3, 'cc');
insert into tab3 values ('WW', 4, 'DD');
build the dynamic query:
select 'select table_name,
matches from (' || listagg(statement, ' UNION ALL ') within group (order by table_name) || ')
where matches > 0'
from (
select 'select ''' || table_name ||
''' as TABLE_NAME, count(1) as MATCHES from ' || table_name || ' WHERE ' ||
listagg(column_name || ' = ''Maria''', ' OR ') within group (order by column_name) as statement,
table_name
from user_tab_columns col
where data_type = 'VARCHAR2'
group by table_name
)
This will return a query, that you can run to check all the tables; in my example, this will build the query (not formatted) :
SELECT table_name, matches
FROM (SELECT 'TAB1' AS TABLE_NAME, COUNT(1) AS MATCHES
FROM TAB1
WHERE V1 = 'Maria'
OR V1B = 'Maria'
UNION ALL
SELECT 'TAB2' AS TABLE_NAME, COUNT(1) AS MATCHES
FROM TAB2
WHERE V2 = 'Maria'
OR V2B = 'Maria'
UNION ALL
SELECT 'TAB3' AS TABLE_NAME, COUNT(1) AS MATCHES
FROM TAB3
WHERE V3 = 'Maria'
OR V3B = 'Maria')
WHERE matches > 0;
Running this query will give:
TABL MATCHES
---- ----------
TAB1 1
TAB2 1
Please notice that I used USER_TAB_COLUMNS, thus searching only in the tables of the login schema; if you want to search in different schemas, you can use ALL_TAB_COLUMNS or DBA_TAB_COLUMNS, depending on what you need and on the privileges of you user; see here for something more.
Also, consider that USER_TAB_COLUMNS will get the colums of tables and views; if you want to limit your search to tables, you can join USER_TAB_COLUMNS(ALL_TAB_COLUMNS, DBA_TAB_COLUMNS) to USER_TABLES (ALL_TABLES, DBA_TABLES) by TABLE_NAME, or TABLE_NAME and OWNER If you decide to use ALL or DBA tables:
SQL> create view vTab1 as select * from tab1;
View created.
SQL> select count(1)
2 from user_tab_columns
3 where table_name = 'VTAB1';
COUNT(1)
----------
3
SQL> select count(1)
2 from user_tab_columns
3 inner join user_tables using(table_name)
4 where table_name = 'VTAB1';
COUNT(1)
----------
0
SQL>
select table_name from user_Tables where table_name = 'bogus';

show the schema of a table in oracle

The following mysql query returns the constraints and the default values along with column_name, is_null and other details -
mysql query - select TABLE_NAME, COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, COLUMN_TYPE, COLUMN_KEY, EXTRA from INFORMATION_SCHEMA.COLUMNS where TABLE_SCHEMA = 'DB_NAME'
I want to write a similar query in Oracle, the following query returns data_type and is_null but doesn't return constraints and default values -
Oracle query - SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, NULLABLE FROM DBA_TAB_COLUMNS where owner = 'USERNAME'
How can I extract those information from an oracle table.
Note: I don't want to use describe table
Select tc.TABLE_NAME, tc.COLUMN_NAME, tc.DATA_TYPE, tc.NULLABLE, tc.DATA_DEFAULT,
con.cons
from DBA_TAB_COLUMNS tc
left join
( select listagg( cc.constraint_name, ',') within group (order by cc.constraint_name) cons,
table_name, owner , column_name
from DBA_CONS_COLUMNS cc
group by table_name, owner , column_name ) con
on con.table_name = tc.table_name and
con.owner = tc.owner and
con.column_name = tc.column_name
where tc.owner = 'USERNAME'
order by 1 ,2
There can be multiple constraints (or none) for each column. Because of that left join is used and listagg function to display all constraint in one column.
TABLE_NAME COLUMN_NAME DATA_TYPE NULLABLE DATA_DEFAULT CONS
AQ$_QUEUE_TABLES OBJNO NUMBER N AQ$_QUEUE_TABLES_PRIMARY,SYS_C001643
AQ$_QUEUE_TABLES SCHEMA VARCHAR2 N SYS_C001640
AQ$_QUEUE_TABLES SORT_COLS NUMBER N SYS_C001645
AQ$_QUEUE_TABLES TABLE_COMMENT VARCHAR2 Y
AQ$_QUEUE_TABLES TIMEZONE VARCHAR2 Y
You can still try to use this below snippet to get the requested details. Hope this helps.
Note : This is for indexed columns as I thought you might need this too
SELECT DISTINCT col.owner,
col.table_name,
col.DATA_TYPE,
Col.Column_Name,
DECODE(nullable,'Y','Yes','N','No') nullable,
high_value(col.table_name,col.column_name), -- This is own created function to deal with LONG datatype columns
Ind.Index_Name
FROM SYS.All_Tab_Cols col,
All_Ind_Columns ind
WHERE Col.Table_Name = Ind.Table_Name
AND Col.Column_Name = Ind.Column_Name(+)
AND Col.Table_Name = UPPER('<TABLE_NAME>')
AND Col.Owner = '<SCHEMA_NAME>';

Which Oracle view contains all constraints together?

I'm trying to get CONSTRAINTS from user_objects table like this:
select CASE object_type
WHEN 'DATABASE LINK' then 'dblinks'
WHEN 'FUNCTION' then 'functions'
WHEN 'INDEX' then 'indexes'
WHEN 'PACKAGE' then 'packages'
WHEN 'PROCEDURE' then 'procedures'
WHEN 'SEQUENCE' then 'sequences'
WHEN 'TABLE' then 'tables'
WHEN 'TRIGGER' then 'triggers'
WHEN 'VIEW' then 'views'
WHEN 'SYNONYM' then 'synonyms'
WHEN 'GRANT' then 'grants'
WHEN 'CONSTRAINT' then 'constraints'
ELSE object_type
END||'|'||
CASE object_type
WHEN 'DATABASE LINK' then 'DB_LINK'
ELSE object_type
END||'|'||object_name
from user_objects
where object_name not like 'BIN$%'
and object_type not like '%PARTITION'
and object_type not in ('PACKAGE BODY')
order by object_type
;
select distinct object_type
from user_objects
;
But..... USER_OBJECTS has only these types FUNCTION
INDEX, PACKAGE, PACKAGE BODY, PROCEDURE, SEQUENCE, TABLE, TRIGGER, VIEW because select distinct object_type from user_objects; returned them. So this query is not giving my the constraints at all.
Is there a way to get all constraints from Oracle? Which Oracle view should I use?
select * from user_constraints
Constraints aren't objects. So they're in a different view, namely USER_CONSTRAINTS. For foreign constraints, you'll need a self join:
select * from user_constraints c
left join user_constraints r on r.owner = c.r_owner and r.constraint_name = c.r_constraint_name
where c.constraint_type = 'R';
Some details can also be found in USER_CONS_COLUMNS.

Compare two schemas and update the old schema with the new columns of new schema

I've an Oracle database with two schemas. One is old and another is new. I would like to update the old schema with the new columns of the new schema.
I get the tables which have changes with the following query.
select distinct table_name
from
(
select table_name,column_name
from all_tab_cols
where owner = 'SCHEMA_1'
minus
select table_name,column_name
from all_tab_cols
where owner = 'SCHEMA_2'
)
With this query I get the tables. How can I update the old schema tables with the new columns? I don't need the data, just the columns.
A schema comparison tool is a good idea. The database schema is far more complicated than most people give credit, and every difference between two database schemas has the potential to cause bugs.
If you're still keen to do it yourself, the best approach I've found is to extract the schema definitions to text, then run a text compare. As long as everything is sorted alphabetically, you can then use Compare Documents feature in Microsoft Word (or FC.EXE, DIFF or equivalent), to highlight the differences.
The following SQLPlus script outputs the schema definition alphabetically, to allow comparison. There are two sections. The first section lists each column, in the format:
table_name.column_name: data_type = data_default <nullable>
The second section lists indexes and constraints, as follows:
PK constraint_name on table_name (pk_column_list)
FK constraint_name on table_name (fk_column_list)
CHECK constraint_name on table_name (constraint_definition)
The script serves as a useful references for extracting some of the Oracle schema details. This can be good knowledge to have when you're out at client sites and you don't have your usual tools available, or when security policies prevent you from accessing a client site database directly from your own PC.
set serveroutput on;
set serveroutput on size 1000000;
declare
rowcnt pls_integer := 0;
cursor c_column is
select table_name, column_name, data_type,
data_precision, data_length, data_scale,
data_default, nullable,
decode(data_scale, null, null, ',') scale_comma,
decode(default_length, null, null, '= ') default_equals
from all_tab_columns where owner = 'BCC'
order by table_name, column_name;
cursor c_constraint is
select c.table_name, c.constraint_name,
decode(c.constraint_type,
'P','PK',
'R','FK',
'C','CHECK',
c.constraint_type) constraint_type,
c.search_condition,
cc.column_1||cc.comma_2||cc.column_2||cc.comma_3||cc.column_3||cc.comma_4||cc.column_4||
cc.comma_5||cc.column_5||cc.comma_6||cc.column_6||cc.comma_7||cc.column_7 r_columns
from all_constraints c,
( select owner, table_name, constraint_name, nvl(max(position),0) max_position,
max( decode( position, 1, column_name, null ) ) column_1,
max( decode( position, 2, decode(column_name, null, null, ',' ), null ) ) comma_2,
max( decode( position, 2, column_name, null ) ) column_2,
max( decode( position, 3, decode(column_name, null, null, ',' ), null ) ) comma_3,
max( decode( position, 3, column_name, null ) ) column_3,
max( decode( position, 4, decode(column_name, null, null, ',' ), null ) ) comma_4,
max( decode( position, 4, column_name, null ) ) column_4,
max( decode( position, 5, decode(column_name, null, null, ',' ), null ) ) comma_5,
max( decode( position, 5, column_name, null ) ) column_5,
max( decode( position, 6, decode(column_name, null, null, ',' ), null ) ) comma_6,
max( decode( position, 6, column_name, null ) ) column_6,
max( decode( position, 7, decode(column_name, null, null, ',' ), null ) ) comma_7,
max( decode( position, 7, column_name, null ) ) column_7
from all_cons_columns
group by owner, table_name, constraint_name ) cc
where c.owner = 'BCC'
and c.generated != 'GENERATED NAME'
and cc.owner = c.owner
and cc.table_name = c.table_name
and cc.constraint_name = c.constraint_name
order by c.table_name,
decode(c.constraint_type,
'P','PK',
'R','FK',
'C','CHECK',
c.constraint_type) desc,
c.constraint_name;
begin
for c_columnRow in c_column loop
dbms_output.put_line(substr(c_columnRow.table_name||'.'||c_columnRow.column_name||': '||
c_columnRow.data_type||'('||
nvl(c_columnRow.data_precision, c_columnRow.data_length)||
c_columnRow.scale_comma||c_columnRow.data_scale||') '||
c_columnRow.default_equals||c_columnRow.data_default||
' <'||c_columnRow.nullable||'>',1,255));
rowcnt := rowcnt + 1;
end loop;
for c_constraintRow in c_constraint loop
dbms_output.put_line(substr(c_constraintRow.constraint_type||' '||c_constraintRow.constraint_name||' on '||
c_constraintRow.table_name||' ('||
c_constraintRow.search_condition||
c_constraintRow.r_columns||') ',1,255));
if length(c_constraintRow.constraint_type||' '||c_constraintRow.constraint_name||' on '||
c_constraintRow.table_name||' ('||
c_constraintRow.search_condition||
c_constraintRow.r_columns||') ') > 255 then
dbms_output.put_line('... '||substr(c_constraintRow.constraint_type||' '||c_constraintRow.constraint_name||' on '||
c_constraintRow.table_name||' ('||
c_constraintRow.search_condition||
c_constraintRow.r_columns||') ',256,251));
end if;
rowcnt := rowcnt + 1;
end loop;
end;
/
Unfortunately, there are a few limitations:
Embedded carriage returns and whitespace in data_defaults, and check constraint definitions, may be highlighted as differences, even though they have zero effect on the schema.
Does not include alternate keys, unique indexes or performance indexes. This would require a third SELECT statement in the script, referencing all_ind_columns and all_indexes catalog views.
Does not include security details, synonyms, packages, triggers, etc. Packages and triggers would be best compared using an approach similar to the one you originally proposed. Other aspects of the schema definition could be added to the above script.
The FK definitions above identify the referencing foreign key columns, but not the PK or the table being referenced. Just one more detail I never got around to doing.
Even if you don't use the script. There's a certain techie pleasure in playing with this stuff. ;-)
Matthew
I'm afraid I can't do more for you at the moment, but this should give you a basic idea.
It selects ADD and DROP column statements that you could execute after carefully reviewing them.
It does not handle
created/dropped tables
data type/precision changes of existing columns (ALTER TABLE MODIFY)
DEFAULT VALUES (so you can't apply it on a table with data when new column is NOT NULL)
Check constraints, Foreign Key constraints
I tried it with some basic data-types (NUMBER, VARCHAR2, DATE) and it worked. Good luck :)
SELECT 'ALTER TABLE ' || LOWER(table_name)
|| ' ADD ' || LOWER(column_name) || ' ' || data_type
|| CASE WHEN data_type NOT IN ('DATE') THEN '(' || data_length || ')' END
|| CASE WHEN nullable='Y' THEN ' NOT NULL' END
|| ';' cmd
FROM all_tab_cols c2
WHERE owner = 'SCHEMA_1'
AND NOT EXISTS ( SELECT 1
FROM all_tab_cols c1
WHERE owner = 'SCHEMA_2'
AND c1.table_name = c2.table_name
AND c1.column_name = c2.column_name )
UNION ALL
SELECT 'ALTER TABLE ' || LOWER(table_name)
|| ' DROP COLUMN ' || LOWER(column_name) || ';'
FROM all_tab_cols c2
WHERE owner = 'SCHEMA_2'
AND NOT EXISTS ( SELECT 1
FROM all_tab_cols c1
WHERE owner = 'SCHEMA_1'
AND c1.table_name = c2.table_name
AND c1.column_name = c2.column_name )
ORDER BY cmd;
I started writing an answer for this but my list of caveats became longer than the answer so I decided to scrap it.
You should go for a schema comparison tool.
There are free versions available - take a look at this question on Server Fault:
https://serverfault.com/questions/26360/how-can-i-diff-two-oracle-10g-schemas
My suggestion would be to download Oracle's SQL Developer and use the built-in schema diff tool (although this requires that you have the Change Management Pack license).

Resources