I'm new to Oracle db, and i wonder if i can find out the datatype and datasize...
I mean : let's say i have the column "location" of type varchar2(20) in table "products".
Could i write a query that would return me in the result "varchar2" and "20" ?
Thank you!
Check out user_tab_columns.
select data_type, data_length
from user_tab_columns
where table_name = 'PRODUCTS'
and column_name = 'LOCATION';
Do you need to find out the type and size of a column for the purpose of understanding the data, or are you writing a program that needs to know it at runtime?
If you only need to know it for your knowledge, typing desc tablename in SQLPlus will tell you about the columns in the table.
If you need to find out the type and size programmatically, what language are you using ... PL/SQL? Java?
Note that selecting from USER_TAB_COLUMNS will only list the columns in tables in your own schema. For other tables you'll need to look at ALL_TAB_COLUMNS (or DBA_TAB_COLUMNS, if the DBA has allowed you to access it). Note that your employer or client may disallow stored procedures or packages from being compiled against either.
SELECT CHAR_LENGTH FROM USER_TAB_COLUMNS WHERE TABLE_NAME = <TABLENAME> AND COLUMN_NAME = <COLUMNNAME>;
The answer to this question was useful to me. But, there is one important difference needs to be considered while taking data_length when the column type is NVARCAHR2. The data_length returned for NVARCHA2 column is doubled.
This is due to the character encoding being used.
Oracle documentation says:
The number of bytes can be up to two times size for AL16UTF16
encoding and three times size for UTF8 encoding.
So, ideal query would be the following:
select table_name, column_name,
data_type, NVL(char_col_decl_length, data_length)
from user_tab_columns where table_name='T51_NOCOMP';
I do the following from sqlplus for oracle:
SELECT COLUMN_NAME,DATA_TYPE,DATA_LENGTH
FROM ALL_TAB_COLUMNS
WHERE TABLE_NAME = 'YOUR_TABLE_NAME'
AND COLUMN_NAME = 'YOUR';`
Hope it works for you too!
Related
Is it possible to add a metadata field at column-level (in the Oracle Data Dictionary)?
The purpose would be to hold a flag identifying where individual data items in a table have been anonymised.
I'm an analyst (not a DBA) and I'm using Oracle SQL Developer which surfaces (and enables querying of) the COLUMN_NAME, DATA_TYPE, NULLABLE, DATA_DEFAULT, COLUMN_ID, and COMMENTS metadata fields of our Oracle DB (see pic).
I'd be looking to add another metadata field at this level (essentially, to add a second 'COMMENTS' field) to hold the 'Anonymisation' flag, to support easy querying of our flagged-anonymised data.
If it's possible (and advisable / supportable), I'd be grateful for any advice for describing the steps required to enable this, which I can then discuss with our Developer and DBA.
Short answer: NO.
But where could you keep that information?
In your data model.
Oracle provides a free data modeling solution, Oracle SQL Developer Data Modeler. It provides the ability to mark table/view columns as sensitive or PII.
Those same models can be stored back in your database so they can be accessed via SQL.
Once you've marked up all of your sensitive attributes/columns, and store it back into the database, you can query it back out.
Disclaimer: I work for Oracle, I'm the product manager for Data Modeler.
[TL;DR] Don't do it. Find another way.
If it's advisable
NO
Never modify the data dictionary; (unless Oracle support tells you to) you are likely to invalidate your support contract with Oracle and may break the database and make it unusable.
If it's possible
Don't do this.
If you really want to try it then still don't.
If you really, really want to try it then find a database you don't care about (the don't care about bit is important!) and log on as a SYSDBA user and:
ALTER TABLE whichever_data_dictionary_table ADD anonymisation_flag VARCHAR2(10);
Then you can test whether the database breaks (and it may not break immediately but at some point later), but if it does then you almost certainly will not get any support from Oracle in fixing it.
Did we say, "Don't do it"... we mean it.
As you already know, you shouldn't do that.
But, nothing prevents you from creating your own table which will contain such an info.
For example:
SQL> CREATE TABLE my_comments
2 (
3 table_name VARCHAR2 (30),
4 column_name VARCHAR2 (30),
5 anonymisation VARCHAR2 (10)
6 );
Table created.
Populate it with some data:
SQL> insert into my_comments (table_name, column_name)
2 select table_name, column_name
3 from user_tab_columns
4 where table_name = 'DEPT';
3 rows created.
Set the anonymisation flag:
SQL> update my_comments set anonymisation = 'F' where column_name = 'DEPTNO';
1 row updated.
When you want to get such an info (along with some more data from user_tab_columns, use (outer) join:
SQL> select u.table_name, u.column_name, u.data_type, u.nullable, m.anonymisation
2 from user_tab_columns u left join my_comments m on m.table_name = u.table_name
3 and m.column_name = u.column_name
4 where u.column_name = 'DEPTNO';
TABLE_NAME COLUMN_NAME DATA_TYPE N ANONYMISATION
---------- --------------- ------------ - ---------------
DEPT DEPTNO NUMBER N F
DSV DEPTNO NUMBER N
DSMV DEPTNO NUMBER Y
EMP DEPTNO NUMBER Y
SQL>
Advantages: you won't break the database & you'll have your additional info.
Drawbacks: you'll have to maintain the table manually.
I need a way to figure out how to get the list of columns in alphabetical order when using the DESCRIBE command in SQL Developer. Something like desc table order by Name; this won't work of course but something along these lines.
a_horse_with_no_name and Littlefoot are BOTH right, but where does that leave you?
If you'd like, you can create a new command that will get you what you want.
In SQLcl -
SQL> alias alphadesc=select column_name, data_type, column_id
2 from user_tab_columns
3 where table_name = upper(:tablename)
4* order by column_name;
We can take advantage of the ALIAS command, used to basically create shortcuts for predefined bits of SQL or PL/SQL.
you're in sql developer - you could do this there as well, either using the ALIAS feature (would need to go into your login default script for connections, or you could create a code template)
PS SQLcl is our modern take on SQLPlus, it's available as a small standalone, but it's also in your SQL Developer / bin directory
You can't change the way the result of a DESCRIBE command are displayed, but you could query the system catalog directly:
select column_name, data_type, column_id
from user_tab_columns
where table_name = 'YOUR_TABLE'
order by column_name
If the current user does not own the table you are looking at, use all_tab_columns but you have to provide the owner name as well:
select column_name, data_type, column_id
from all_tab_columns
where table_name = 'YOUR_TABLE'
and owner = 'SOME_USER'
order by column_name
I presume you want to query USER_TAB_COLUMNS.
In its simplest way, that would be
select *
from user_tab_columns
where table_name = 'SOME_TABLE_NAME'
order by column_name;
I created a table in oracle like
CREATE TABLE suppliers AS (SELECT * FROM companies WHERE id > 1000);
I would like to know the complete select statement which was used to create this table.
I have already tried get_ddl but it is not giving the select statement. Can you please let me know how to get the select statement?
If you're lucky one of these statements will show the DDL used to generate the table:
select *
from gv$sql
where lower(sql_fulltext) like '%create table suppliers%';
select *
from dba_hist_sqltext
where lower(sql_text) like '%create table%';
I used the word lucky because GV$SQL will usually only have results for a few hours or days, until the data is purged from the shared pool. DBA_HIST_SQLTEXT will only help if you have AWR enabled, the statement was run in the last X days that AWR is configured to hold data (the default is 8), the statement was run after the last snapshot collection (by default it happens every hour), and the statement ran long enough for AWR to think it's worth saving.
And for each table Oracle does not always store the full SQL. For security reasons, DDL statements are often truncated in the data dictionary. Don't be surprised if the text suddenly cuts off after the first N characters.
And depending on how the SQL is called the case and space may be different. Use lower and lots of wildcards to increase the chance of finding the statement.
TRY THIS:
select distinct table_name
from
all_tab_columns where column_name in
(
select column_name from
all_tab_columns
where table_name ='SUPPLIERS'
)
you can find table which created from table
Can someone tell me how I can get the number of rows in each table in my oracle database? I have found several queries, but none of them worked because I am using oracle 7 and sqlplus 3.2 and basically all what I found didn't work on it. I just need something that would work on sqlplus 3.2.
Required:
Table Name Rows
Table 1 0
Table 2 5
...
Is it possible to do it with something like a loop? Or what exactly should I do?
if SELECT table_name, num_rows from all_tables doesn't give you what you need.
You could use dynamic SQL and counts as Rahul selected.
Run the below to get results which dynamically build a union on all tables, then run the results as it's own query to get final results.
SELECT 'SELECT ' ||t.name || ' as tName, count(*) as Row_Cnt
FROM ' || t.name || ' UNION ALL '
FROM ALL_TABLES t
Just be sure to remove the last union statement on the last query.
Also note: if you don't have access to see the table, it will not come out in this list!
---Updated ------
So if all_tables doesn't exist none of this will work. Since I don't have a oracle 7 instance handy... could you see if SELECT * FROM dictionary returns anything that might produce a list of all the tables? If you find a view or table object use it in place of all_tables above.
I'm reading the docs for oracle 7 now but finding little easily searchable. thus a guess and check method may go faster.
I am using Oracle 11g. I want to be able to determine whether a particular sequence exists or not. I have tried the code below but it is not working. (It is returning 0 as count value when there should be more):
SELECT COUNT(*)
FROM user_sequences
WHERE sequence_name = 'SCHEMA.SEQUENCE_NAME';
If anyone knows why this is, please help me.
If you are running the query as user MP then try it like this:
SELECT COUNT(*)
FROM user_sequences
WHERE sequence_name = 'SEQ_SSO_KEY_AUTHENTICATION';
else, try it like this:
SELECT COUNT(*)
FROM all_sequences
WHERE sequence_name = 'SEQ_SSO_KEY_AUTHENTICATION'
AND sequence_owner = 'MP' ;
Also, keep in mind that you may not be granted to see all sequences in DB.
In this case scripts provided above may not work, and you should run something like
SELECT COUNT(*) FROM DBA_SEQUENCES;
But this also may not work if you have no access to DBA_SEQUENCES view.
Check Oracle docs.
For newer/11g versions, the following query works. One suggestion, I couldn't initially make it work because I was using lowercase letters for sequence names. Making it all caps returned expected value
SELECT * FROM all_objects ao WHERE ao.owner = 'SCHEMA_NAME' AND ao.OBJECT_TYPE ='SEQUENCE'
AND ao.OBJECT_NAME ='CAPITAL_SEQ_NAME';