Why an entry is created in user_tab_cols when we create a function based on a column of a table?
create table t1(a varchar2(100), b number);
select * from user_tab_cols where table_name = 'T1'; -- Two rows coming
create index idx1 on t1(upper(a));
select * from user_tab_cols where table_name = 'T1'; -- Three rows coming
What is the reason to put an entry in user_tab_cols?
The extra column is a virtual column that Oracle has added to store the value of the indexed expression. From the Oracle documentation:
Oracle Database represents the index expression as a virtual column
You can easily verify in SQL*Plus that the extra column is virtual. In fact, it is also a 'hidden' column:
SQL> select column_name, hidden_column, virtual_column from user_tab_cols where table_name = 'T1';
COLUMN_NAME HID VIR
------------------------------ --- ---
A NO NO
B NO NO
SYS_NC00003$ YES YES
The name of the virtual column may be different on your machine.
user_tab_columns filters out hidden columns, as explained in the Oracle documentation for user_tab_cols. So, if you don't wish to see this column, you can query user_tab_columns instead of user_tab_cols:
SQL> select column_name from user_tab_columns where table_name = 'T1';
COLUMN_NAME
------------------------------
A
B
SQL>
Related
I created a table with an invisible column:
CREATE C39293.JUNK (
id NUMBER,
JUNKCOL VARCHAR2(50) INVISIBLE
);
Verified that the table was created :
select * from all_tab_columns where table_name = 'JUNK'
Output:
1 THE_OWNER_SCHEMA JUNK JUNKCOL VARCHAR2 50 Y (WideMemo) CHAR_CS 50 NO NO 50 B NO YES NONE NO NO
2 THE_OWNER_SCHEMA JUNK ID NUMBER 22 Y 1 (WideMemo) NO NO 0 NO YES NONE NO NO
I expected this view to show me all invisible columns it did not.
select * from dba_unused_col_tabs;
No Records found
How do I query all the invisible columns in the database?
SELECT table_name, column_name, hidden_column
FROM user_tab_cols
WHERE hidden_column='YES';
Or, as you asked for all columns in the database:
SELECT owner, table_name, column_name, hidden_column
FROM all_tab_cols
WHERE hidden_column='YES';
EDIT:
ALL_TAB_COLS is nicely explained in another question
How do I get all table names and its column names in oracle? The Table names should be printed first followed by all the column name, then the next table and its columns, and so on and so forth.
If you are dba you can see all tables in DB;
select * from all_tab_columns
order by table_name;
The query below, in the middle column (str), has the data the way you requested it. However, without the info in the first and/or the last column, it is not clear how you will know which values are table names and which are columns under them.
It would make a lot more sense to have table name in one column (repeated for each of its columns), then the column name and then the order. This would be just the second member of the union all operation.
The query below works for the tables in your schema. If you want to do this for all the tables you have access to, use all_tables and all_tab_columns; if you have DBA privileges, use dba_tables and dba_tab_columns (but in these cases, don't you need to know the schema/owner, not just the table name?)
select table_name as tbl, table_name as str, 0 as ord from user_tables
union all
select table_name, column_name, column_id from user_tab_columns
order by tbl, ord
;
SELECT table_name, column_name
FROM all_tab_cols
order by table_name, column_name
The following query on the standard view user_tab_col:
select * from user_tab_cols;
returns on Oracle the columns column_name and qualified_col_name.
What is the difference?
qualified_col_name indicates full column path for XML tables. Basically it stores the expression for this column. For regular columns it will be equal to column_name.
If you run:
select owner, table_name, column_name, data_type, qualified_col_name
from all_tab_cols
where column_name <> qualified_col_name;
you will see returned columns from XML tables in XDB schema.
For example:
OWNER TABLE_NAME COLUMN_NAME DATA_TYPE QUALIFIED_COL_NAME
XDB XDB$SIMPLE_TYPE SYS_NC00074$ XDB$APPINFO_LIST_T "XMLDATA"."RESTRICTION"."MIN_INCLUSIVE"."ANNOTATION"."APPINFO"
Update:
For object tables qualified_col_name stores expression of type casting and accessing to attribute. For example:
create or replace type test1_obj as object(
n1 number,
n2 number,
s1 varchar2(10),
s2 varchar2(20)
)
not final;
create or replace type test2_obj under test1_obj(
d1 date,
d2 date
)
not final;
create table object_table of test1_obj;
select column_name, data_type, qualified_col_name
from user_tab_cols
where table_name = 'OBJECT_TABLE'
order by internal_column_id;
For last 2 hidden system columns reserved for instances of type test2_obj we can see:
COLUMN_NAME DATA_TYPE QUALIFIED_COL_NAME
SYS_NC00010$ DATE TREAT(SYS_NC_ROWINFO$ AS "TEST"."TEST2_OBJ")."D1"
SYS_NC00011$ DATE TREAT(SYS_NC_ROWINFO$ AS "TEST"."TEST2_OBJ")."D2"
My database has a lot of tables. How can I display all the table names along with the count of column names in each table?
myoutput:
------------
table_name count(*)
---------- --------
table_t1 12
x_a 5
Y_k 23
samptabl 0
Use USER_TAB_COLS view to get the column_count.
SELECT table_name, count(*) column_count
FROM user_tab_cols
GROUP BY table_name;
If you want the name of the table with the number of columns in it, use DBA's answer here.
If you want name of the table and the number of rows in it, use the following:
SELECT table_name, num_rows
FROM user_tables;
The numbers of rows in this query represent the numbers when the table was last analyzed. To return the latest numbers run ANALYSE tablename before running this query.
If you want to know all table_names and columns count in your Entire Database then here is the query.
Query : SELECT TABLE_NAME,COUNT(COLUMN_NAME) as No_Of_Cols
FROM ALL_TAB_COLS
GROUP BY TABLE_NAME;
Thanks,
Venu.
SELECT table_name, count(*) column_count
FROM all_tables
GROUP BY table_name;
I very new to PL SQL and I have encountered a problem. Hopefully its not too hard to solve and I'm just going about it all wrong.
My problem is this: I have two tables with a different amount of columns. I need to run a check to see what the different columns are and then add them to one of the tables.
For example:
Table 1 has 1 column called name.
Table 2 has 2 columns called name and id.
(name has the same data type in both tables)
In this case, I would need to run a script that will check table 1 and 2, see that table 1 is missing the 'id' column and then add it to table 1.
Is this possible?
so far I have this:
SELECT TABLE_NAME, COLUMN_NAME FROM user_tab_columns WHERE table_name = 'TEST_TBL' OR TABLE_NAME ='TEST_TBL1'
which returns the columns for both tables. I have looked everywhere on the internet with no luck at all. I have tried to do intersect and join but with no luck.
If anyone has any help or could point me in the right direction I would appreciate it so much!
To get the different columns
SELECT TABLE_NAME, COLUMN_NAME FROM user_tab_columns
where table_name = 'Table1' AND COLUMN_NAME NOT IN ( SELECT COLUMN_NAME FROM USER_TAB_COLUMNS WHERE TABLE_NAME='table2')
UNION
SELECT TABLE_NAME, COLUMN_NAME FROM user_tab_columns
where table_name = 'table2' AND COLUMN_NAME NOT IN ( SELECT COLUMN_NAME FROM USER_TAB_COLUMNS WHERE TABLE_NAME='table1');