Right way to create index organized table - oracle

I am trying to create a index organized table in oracle 11. I create the index organized table and insert the row from another table.
create table salIOT (
mypk ,
cid ,
date,
CONSTRAINT sal_pk PRIMARY KEY (mypk)
) ORGANIZATION INDEX
AS Select * from another table;
But the leaf blocks are empty when I query
SQL> Select owner, index_name, table_name, leaf_blocks from all_indexes where table_name like 'SALIOT';
Am I missing something here?

You still need to gather statistics on the table, something like:
exec dbms_stats.gather_table_stats('ABC', 'IOTTableName')
(assuming 'ABC' is your username; change as needed) - then re-run your SELECT against ALL_INDEXES and you will see how many leaf blocks you have.

Related

In sql without insert values in table, how i can see column of table

SQL> create table justlike(customerid varchar(19),first_name varchar(40),last_name varchar(100),Address varchar(50),city varchar(30),pincode varchar(10),state varchar(20));
Just use:
desc <table_name>;
This will print the description of your table columns
in your case:
desc justlike;
You can always check the table definition, in case you are using Oracle, by running below query -
SELECT * FROM USER_TAB_COLS
WHERE TABLE_NAME = 'JUSTLIKE';
OR you can write a select on table itself -
SELECT * FROM JUSTLIKE;

How to copy all constrains and data form one schema to another in oracle

I am using Toad for oracle 12c. I need to copy a table and data (40M) from one shcema to another (prod to test). However there is an unique key(not the PK for this table) called record_Id col which has something data like this 3.000*******19E15. About 2M rows has same numbers(I believe its because very large number) which are unique in prod. When I try to copy it violets the unique key of that col. I am using toad "export data to another schema" function to copy the data.
when I execute query in prod
select count(*) from table_name
OR
select count(distinct(record_id) from table_name
Both query gives the exact same numbers of data.
I don't have DBA permission. How do I copy all data without violating unique key of the table.
Thanks in advance!
You can use UPSERT for decisional INSERT or UPDATE or you may write small procedure for this.
you may consider to use NOT EXISTS, but your data is big and it might not be resource efficient.
insert into prod_tab
select * from other_tab t1 where NOT exists (
select 1 from prod_tab t2 where t1.id = t2.id
);
In Oracle you can use a MERGE query for that.
The following query proceeds as follows for each data row :
if the source record_id does not yet exist in the target table, a new record is inserted
else, the existing record is updated with source values
For the sake of the example, I assumed that there are two other columns in the table : column1 and column2.
MERGE INTO target_table t1
USING (SELECT * from source_table t2)
ON (t1.record_id = t2.record_id)
WHEN MATCHED THEN UPDATE SET
t1.column1 = t2.column1,
t1.column2 = t2.column2
WHEN NOT MATCHED THEN INSERT
(record_id, column1, column2) VALUES (t2.record_id, t2.column1, t2.column2)

About create table as select (CTAS)

When we do:
create table big2 as select * from big1;
Are the indexes and constraints also copied over to the new table?
Only NOT NULL constraints are copied. See FAQ.
You can do CREATE TABLE big2 (bigid PRIMARY KEY) AS SELECT * FROM big1 tp create a primary key, but yes, for other indexes you'll want to copy and run the index creation scripts.
Just for info, there is a simple way to remember indices to recreate them after deleting source table:
SELECT DBMS_METADATA.get_ddl('INDEX', index_name)
FROM user_indexes
WHERE TABLE_NAME = 'BIG1';

How to duplicate all data in a table except for a single column that should be changed

I have a question regarding a unified insert query against tables with different data
structures (Oracle). Let me elaborate with an example:
tb_customers (
id NUMBER(3), name VARCHAR2(40), archive_id NUMBER(3)
)
tb_suppliers (
id NUMBER(3), name VARCHAR2(40), contact VARCHAR2(40), xxx, xxx,
archive_id NUMBER(3)
)
The only column that is present in all tables is [archive_id]. The plan is to create a new archive of the dataset by copying (duplicating) all records to a different database partition and incrementing the archive_id for those records accordingly. [archive_id] is always part of the primary key.
My problem is with select statements to do the actual duplication of the data. Because the columns are variable, I am struggling to come up with a unified select statement that will copy the data and update the archive_id.
One solution (that works), is to iterate over all the tables in a stored procedure and do a:
CREATE TABLE temp as (SELECT * from ORIGINAL_TABLE);
UPDATE temp SET archive_id=something;
INSERT INTO ORIGINAL_TABLE (select * from temp);
DROP TABLE temp;
I do not like this solution very much as the DDL commands muck up all restore points.
Does anyone else have any solution?
How about creating a global temporary table for each base table?
create global temporary table tb_customers$ as select * from tb_customers;
create global temporary table tb_suppliers$ as select * from tb_suppliers;
You don't need to create and drop these each time, just leave them as-is.
You're archive process is then a single transaction...
insert into tb_customers$ as select * from tb_customers;
update tb_customers$ set archive_id = :v_new_archive_id;
insert into tb_customers select * from tb_customers$;
insert into tb_suppliers$ as select * from tb_suppliers;
update tb_suppliers$ set archive_id = :v_new_archive_id;
insert into tb_suppliers select * from tb_suppliers$;
commit; -- this will clear the global temporary tables
Hope this helps.
I would suggest not having a single sql statement for all tables and just use and insert.
insert into tb_customers_2
select id, name, 'new_archive_id' from tb_customers;
insert into tb_suppliers_2
select id, name, contact, xxx, xxx, 'new_archive_id' from tb_suppliers;
Or if you really need a single sql statement for all of them at least precreate all the temp tables (as temp tables) and leave them in place for next time. Then just use dynamic sql to refer to the temp table.
insert into ORIGINAL_TABLE_TEMP (SELECT * from ORIGINAL_TABLE);
UPDATE ORIGINAL_TABLE_TEMP SET archive_id=something;
INSERT INTO NEW_TABLE (select * from ORIGINAL_TABLE_TEMP);

Procedure to alter and update table on hierarchical relationship to see if there are any children

I have a hierarchical table on Oracle pl/sql. something like:
create table hierarchical (
id integer primary key,
parent_id references hierarchical ,
name varchar(100));
I need to create a procedure to alter that table so I get a new field that tells, for each node, if it has any children or not.
Is it possible to do the alter and the update in one single procedure?
Any code samples would be much appreciated.
Thanks
You can not do the ALTER TABLE (DDL) and the UPDATE (DML) in a single step.
You will have to do the ALTER TABLE, followed by the UPDATE.
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE hierarchical ADD child_count INTEGER';
--
EXECUTE IMMEDIATE '
UPDATE hierarchical h
SET child_count = ( SELECT COUNT(*)
FROM hierarchical h2
WHERE h2.parent_id = h.id )';
END;
Think twice before doing this though. You can easily find out now if an id has any childs with a query.
This one would give you the child-count of all top-nodes for example:
SELECT h.id, h.name, COUNT(childs.id) child_count
FROM hierarchical h
LEFT JOIN hierarchical childs ON ( childs.parent_id = h.id )
WHERE h.parent_id IS NULL
GROUP BY h.id, h.name
Adding an extra column with redundant data will make changing your data more difficult, as you will always have to update the parent too, when adding/removing childs.
If you just need to know whether children exist, the following query can do it without the loop or the denormalized column.
select h.*, connect_by_isleaf as No_children_exist
from hierarchical h
start with parent_id is null
connect by prior id = parent_id;
CONNECT_BY_LEAF returns 0 if the row has children, 1 if it does not.
I think you could probably get the exact number of children through a clever use of analytic functions and the LEVEL pseudo-column, but I'm not sure.

Resources