Oracle: Script to verify that objects belong to their tablespaces - sql

I have 2 tablespaces, one to store tables and other on to store indexes. I created a script that can be run in any of my schemas and it will move objects (tables or indexes) to their respective tablespaces.
However, I am failing to come up with a script that will verify that objects have been moved to the correct tablespaces (meaning tables have been moved to the table tablespace, and indexes have been moved to the index tablespace).
Any thoughts?

You can use the query below to get the information through a spesific schema :
select t.table_name, t.tablespace_name as "TS Name For Table",
i.index_name, i.tablespace_name as "TS Name For Indexes"
from user_tables t
join user_indexes i on i.table_name = t.table_name
order by t.table_name, i.index_name;

Related

How to list all tables that have data in it?

I have around 2000 tables that most of them are not in use and do not have any data in them.
I know how to list all tables as below
SELECT owner, table_name FROM ALL_TABLES
But I do not know how to list the one that has at least one row of data in it.
Is there anyway to do that?
There are a few ways you could do this:
Brute-force and count the rows in every table
Check the table stats
Check if there is any storage allocated
Brute force
This loops through the tables, counts the rows, and spits out those that are empty:
declare
c integer;
begin
for t in (
select table_name from user_tables
where external = 'NO'
and temporary = 'N'
) loop
execute immediate
'select count(*) from ' || t.table_name
into c;
if c = 0 then
dbms_output.put_line ( t.table_name );
end if;
end loop;
end;
/
This is the only way to be sure there are no rows in the table now. The main drawback to this is it could take a looooong time if you a many tables with millions+ rows.
I've excluded:
Temporary tables. You can only see data inserted in your session. If they're in use in another session you can't see this
External tables. These point to files on the database server's file system. The files could be temporarily missing/blank/etc.
There may be other table types with issues like these - make sure you double check any that are reported as empty.
Check the stats
If all the table stats are up-to-date, you can check the num_rows:
select table_name
from user_tables ut
where external = 'NO'
and temporary = 'N'
and num_rows = 0;
The caveat with this is this figures may be out-of-date. You can force a regather now by running:
exec dbms_stats.gather_schema_stats ( user );
Though this is likely to take a while and - if gathering has been disabled/deferred - might result in unwanted plan changes. Avoid doing this on your production database!
Check storage allocation
You can look for tables with no segments allocated with:
select table_name
from user_tables ut
where external = 'NO'
and temporary = 'N'
and segment_created = 'NO';
As there's no space allocated to these, there's definitely no rows in them! But a table could have space allocated but no rows in it. So it may omit some of the empty tables - this is particularly likely for tables that did have rows in the past, but are empty now.
Final thoughts
It's worth remembering that a table with no rows now could still be in use. Staging tables used for daily/weekly/monthly loads may be purged at the end of the process; removing these will still break your apps!
There could also be code which refers to empty tables which work as-is, but would error if you drop the table.
A better approach would be to enable auditing, then run this for "a while". Any tables will no audited access in the time period are probably safe to remove.

sqlplus list object name and size in kb of each object in a schema

I want to list all the objects names and size in kb of each objects in the a schema(e.g book) but I have no idea how to do it. any good reference that I can take a look?
The DBA_OBJECTS data dictionary view holds information about all the objects in the database. DBA_SEGMENTS holds information on segments (e.g. tables, indexes, materialized views, etc. See the full details in Oracle's documentation). Objects which are not backed by segments are just definitions stored in Oracle's internal tables (e.g. a view is no more than a couple of bytes of data its text takes), so they can probably safely be neglected.
Once we've established that, it's a simple matter of outer joining the two tables:
SELECT object_name, object_type, bytes/1024 AS KB
FROM dba_objects do
LEFT OUTER JOIN dba_segments ds on do.object_name = ds.segment_name
WHERE do.owner = 'BOOK'
Note that unfortunately, there's no ALL_SEGMENTS variant of that table, so you'll have to use a user with permissions on the DBA_* views. Alternatively, you could log in with the user you want to retrieve data for and use the USER_* variant:
SELECT object_name, object_type, bytes/1024 AS KB
FROM user_objects uo
LEFT OUTER JOIN user_segments us on uo.object_name = us.segment_name

Is any tool help me to query table by CONSTRAINTS rule?

I have a big database, the database have more than 1000 tables and have many
table constraints rules. To remember all table constraints rule is too hard for me.Every day i need write many simple sql to query several tables. Writing so many sqls by hand is waste my time. Is there any tool to save my time to help me query table by CONSTRAINTS rule?
if database is Oracle , you didn't try data dictionary ?
USER_CONSTRAINTS / ALL_CONSTRAINTS / DBA_CONSTRAINTS table ?
for query constrains on certain tables that own by current user
SELECT CONSTRAINT_NAME, CONSTRAINT_TYPE, R_CONSTRAINT_NAME, STATUS
FROM USER_CONSTRAINTS
WHERE TABLE_NAME = 'CRUISES';
or you can try all constraints in table that user have right to query using ALL_CONSTRAINTS table
or you can try on database level constraint using DBA_CONSTRAINTS table
both 3 tables share same column structure , so I won't repeat much .
If you want a GUI tool, you could do worse than any of the following products:
SQL Developer (Oracle)
TOAD (Quest)
PL/SQL Developer (Alround Automation)

No indexes found in any table - is that possible?

By executing the following command that will list out all indexes found in my schema, the query returned nothing - suggesting that either no index is created, or probably i do not have sufficient permission.
select * from user_indexes;
Are there any more ways to list the indexes i have in a schema?
Sure it's possible.
Common, even :)
It just means nobody's created any indexes.
If the query returned nothing, it means that you DO have permission ... and there simply aren't any indexes.
Here's a good link on "Managing indexes in Oracle" (it sounds like you're probably running Oracle):
http://download.oracle.com/docs/cd/B19306_01/server.102/b14231/indexes.htm
As paulsm4 say, you do not have any indexes in your schema.
you can use
select * from all_indexes;
and you'll see all your indexes + the others where you have rights.
Florin is correct, USER_INDEXES is a view on ALL_INDEXES that only shows those which were created by you. You can query ALL_INDEXES directly to determine if anyone else has created indexes on the table in question but you will probably want to add a where clause for the table_name as it will list all indexes for all tables in the instance and also only some of the columns.
SELECT TABLE_NAME, INDEX_NAME FROM ALL_INDEXES WHERE TABLE_NAME='XYZ';
You can limit which tables using an IN CLAUSE if there is are several tables you are interested in
SELECT TABLE_NAME, INDEX_NAME FROM ALL_INDEXES WHERE TABLE_NAME IN ('ABC','XYZ');
and you can use a like clause if there is a prefix or suffix
SELECT TABLE_NAME, INDEX_NAME FROM ALL_INDEXES WHERE TABLE_NAME like 'XYZ%';
Also, if you want to see which columns these indexes are on, you can select from ALL_IND_COLUMNS;
SELECT * FROM ALL_IND_COLUMNS WHERE TABLE_NAME='XYZ'
Note that whether a table has indexes or not depends on the data and the usage. A small lookup table that has maybe a hundred rows or less would not need an index whereas a table that contains millions of rows but is queried for just a handful when needed would need an index.

Oracle - drop table constraints without dropping tables

I'm doing some bulk migration of a large Oracle database. The first step of this involves renaming a whole load of tables as a preparation for dropping them later (but I need to keep the data in them around for now). Any foreign key constraints on them need to be dropped - they shouldn't be connected to the rest of the database at all. If I were dropping them now I could CASCADE CONSTRAINTS, but rename simply alters the constraints.
Is there a way I can drop all of the constraints that CASCADE CONSTRAINTS would drop without dropping the table itself?
You can do it with dynamic SQL and the data dictionary:
begin
for r in ( select table_name, constraint_name
from user_constraints
where constraint_type = 'R' )
loop
execute immediate 'alter table '|| r.table_name
||' drop constraint '|| r.constraint_name;
end loop;
end;
If the tables are owned by more than one user you'll need to drive from DBA_CONSTRAINTS and include OWNER in the projection and the executed statement. If you want to touch less than all the tables I'm afraid you'll need to specify the list in the WHERE clause, unless there's some pattern to their names.
You can disable/re-enable constraints without dropping them. Take a look at this article.