Unable to view tablespace name for a partitioned table - oracle

I am unable to get the tablespace information for a partitioned table.
I have tried querying tablespace_name from dba_tables but the value was null. Let me know the reason to this and also from where can I view the tablespace_name for a partitioned table.
select tablespace_name
from dba_tables
where table_name = 'XXXXX';
The result was null.
Please let me know how can I get the tablespace information coz I am trying to move the partitions to a new tablespace.Also let me know the impact of it.

The reason is that you could have each partition in a different tablespace, so the information at a table level does not exist and you need to check the partitions.
Oracle doc for this
You may need DBA_TAB_PARTITIONS
select tablespace_name
from dba_tab_partitions
where table_name='...'
and table_owner = '...'

Related

Is "Create Table" or "Create Any Table" Privilages grant the user a quota implicitly?

I am working on our database users privileges, and I am facing a confusing issue. I first created a user (user1) without any quota and grant him the role CONNECT which have the system privilege (Create Session). After that I grant him the (Create Table) privilege. The user try to create a table and he succeeded to create a table in his tablespace!! my questions are:
Based on my understanding, the user must have a quota to create any objects, how this user created the table?
Is there any privilege or roles that give the user a quota implicitly?
Regards,
A quota isn't being granted implicitly. But creating a table doesn't necessarily require any storage, and so doesn't necessarily require a quota:
create table t42 (id number);
Table T42 created.
select segment_type, bytes from user_segments where segment_name = 'T42';
no rows selected
Adding data to the table does require storage, and therefore a quota:
insert into t42 (id) values (1);
1 row inserted.
select segment_type, bytes from user_segments where segment_name = 'T42';
SEGMENT_TYPE BYTES
------------------ ----------
TABLE 65536
If the owner doesn't have a quota on the tablespace then they will get an error when they try to insert; which is the case when they do have a quota and try to exceed it too of course (though the error will be different).
This behaviour is due to deferred segment creation; the default behaviour is controlled by an initialisation parameter. You can override that during table creation with the segment creation clause.
drop table t42 purge;
Table T42 dropped.
create table t42 (id number) segment creation immediate;
Table T42 created.
select segment_type, bytes from user_segments where segment_name = 'T42';
SEGMENT_TYPE BYTES
------------------ ----------
TABLE 65536
Read more in the documentation.
Incidentally, if you create a table with deferred segment creation then dbms_metadata.get_ddl shows that; if you then insert a row to force a segment to be created, dbms_metadata.get_ddl changes to SEGMENT CREATION IMMEDIATE. Which might not be expected. Truncating the table with the DROP ALL STORAGE clause will remove the segments, and revert the DDL to SEGMENT CREATION DEFERRED. Just something I noticed in passing.

Finding tablespace size on oracle without dba_* metatables

I need to find the current tablespace size for a db in Oracle 10g. Looking around, I've found many scripts that determine size using tables like dba_extents, but the database I'm using has none of these dba_* tables.
(I'm using this as a proxy for finding table size, which is complicated because most of the table size is in blobs.)
The DBA_* views are part of the "Static Data Dictionary Views" Generally there are three versions of every view, DBA_ that shows everything, ALL_ that shows what you have access to, and USER_ that will show what you own, and will not have the OWNER column.
For example DBA_TABLES has all tables, ALL_TABLES are the table you can select from, and USER_TABLES are the tables you own.
The views are documented in "Static Data Dictionary Views". A good resource if you need to translate from DBA_ to ALL_ or USER_.
Unfortunately _EXTENTS only comes in a DBA and USER version. So if want information on objects you can access but do not own, you will need to ask your resident DBA for help.
The dba_* views are part of the data dictionary, which exists in every Oracle database. They're in the sys schema, and if you can't query them, it probably just means you don't have SELECT access to them.
If the table you want to check is in your schema, you can replace e.g. dba_extents with user_extents and the query should work.
Here's my suggestion for a script to tell the size of a table in your schema (indexes included):
select segment_name, segment_type, bytes/1024/1024 as size_in_mb
from user_segments
where segment_name = :YOUR_TABLE
or segment_name in (select segment_name from user_lobs where table_name = :YOUR_TABLE)
or segment_name in (select index_name from user_indexes where table_name = :YOUR_TABLE);

Oracle - Move all tables and reclaim free space

I have this query:
select file_id, block_id first_block, block_id+blocks-1 last_block,
segment_name
from dba_extents
where tablespace_name = 'USERS'
union all
select file_id, block_id, block_id+blocks-1, 'free'
from dba_free_space
where tablespace_name = 'USERS'
order by file_id, first_block DESC;
It shows lot of "free" segments in between. There are lot of tables which are coming in between.
I move the tables using:
Alter table table_name move;
I have 2000 such tables. Is there a way on how I can move it altogether so I can reclaim all the free space from the tablespace?
To achieve your goal you have to move all objects in the tablespace, not just tables.
At least you have to move tables and then rebuild all their indexes because when you move a table all indexes built on this table are invalidated.
You can not move all tables all together but you can obtain all commands in the following way:
select 'alter table ' ||table_name ||' move;'
from dba_tables where tablespace_name = 'YOURTABLESPACENAME';
To rebuild indexes:
select 'alter index ' ||index_name ||' rebuild;'
from dba_indexes where tablespace_name = 'YOURTABLESPACENAME' and status <>'VALID';
Be careful: this procedure is not complete, you can have indexes of different kind.
Note: to obtain best results you should move objects in a different tablespace.
A simpler approach can be the one explained here: this article describe how to use the shrink command against Oracle database tables to reclaim wated space.
If you want a detailed procedure give me the result of the following query:
select distinct segment_type from dba_segments where tablespace_name='YOURTABLESPACENAME';

How to specify tablespace_name in SQLPlus Oracle select

My setup looks like this
SQL> SELECT tablespace_name, table_name
FROM all_tables
WHERE tablespace_name = 'MYSPACE';
TABLESPACE_NAME TABLE_NAME
-------------------------- ------------------------------
MYSPACE MYTABLENAME
MYSPACE MYOTHERTABLENAME
Now I'd like to SELECT * FROM MYSPACE.MYTABLENAME; but that's apparently not how you do it.
ERROR at line 1:
ORA-00942: table or view does not exist
My expected result would be to get all records from that table. Like I would if it was MySQL.
Thanks
You are selecting from tablespace, which is not the same as your Owner/Schema name. Thats why. For example the tablespace SYSTEM has owner SYS. You do select from Sys.xxx;
Ok.
SELECT owner, tablespace_name, table_name
FROM all_tables
WHERE tablespace_name = 'MYSPACE';
And then
select * from [ owner ].[ table_name ];
(worth to mention: select .. from dba_tables / user_tables)
Tables are not owned by a tablespace. A tablespace is a logical storage storage structure. When you create a table (or index) you specify which tablespace its contents should be stored in. Unless you're doing DBA tasks, you don't really need to know which tablespace(s) your data is stored in.
You may just be confusing terms. Tables are owned by schemas. If you query the owner column instead of tablespace_name you might see something like:
SQL> SELECT owner, table_name
FROM all_tables
WHERE tablespace_name = 'MYSPACE';
OWNER TABLE_NAME
-------------------------- ------------------------------
MYUSER MYTABLENAME
MYUSER MYOTHERTABLENAME
And you can then query from that with
SELECT * FROM MYOWNER.MYTABLENAME;
Of course, if the owner is actually you anyway, then you don't need to prefix the table name with the schema; you can just select FROM MYTABLENAME. (You may also have synonyms or session settings that make the schema prefix unnecessary, but that's getting a a bit off-topic). And if you own the table you'll see it in USER_TABLES as well.

Table not created in specific tablespace - Oracle

I am a moderate user of Oracle and I had to create some of the tables in specified table space as shown below.
create table t_abc tablespace abc_tbspc as select * from abc;
create table t_xyz tablespace abc_tbspc as select * from xyz;
After running these through jobs (file containing around 5 tables to be created in a single tablespace), I could see that the table t_abc is created in abc_tbspc ; but the table t_xyz is assigned to null when I query the all_tables. Not sure why the 2nd table is not created in the specified tablespace even though there is abundant space in the table space.
TABLESPACE_NAME will be null for one of these reasons:
Temporary Temporary tables use a temporary tablespace.
Index Organized Index-organized tables store data in an index, not in a heap.
Partitioned Each partition could have a different tablespace, there is not necessarily one tablespace for the whole table.
External External tables do not store their data in a tablespace.
Your code should not meet one of the conditions above; did you leave out some details? I ran the query below to look for other cases where TABLESPACE_NAME is null but could not find any.
select *
from dba_tables
where tablespace_name is null
and (temporary is null or temporary <> 'Y') -- #1
and (iot_type is null or iot_type <> 'IOT') -- #2
and (partitioned is null or partitioned <> 'YES') -- #3
and (owner, table_name) not in -- #4
(select owner, table_name from dba_external_tables)

Resources