In Oracle I want to create a "routing interface" which insert into separate tables based on parameter - oracle

I need to find a solution to the following problem: there should be a common and single "interface" that I can use in an insert into statement, something like this: insert into INTERFACE (fields) select ...
But there are many tables with the same structure behind the interface which should decide based on list of values (coming in a field) where to put the data. The tables are partitioned by range interval (daily) right now.
I was thinking about having a composite partitioned table which cannot be SELECT-ed to avoid mixing different type of data in a single select query, but creating views on the top of it. In this case the table should be partitioned like this: partition by list FIELD subpartition by range interval. But oracle 12 does not support this.
Any idea how to solve this? (There is a reason why I need a single interface and why I have to store data separately.)
Thank you in advance!

The INSERT ALL syntax can help easily route data to specific tables based on conditions:
create table interface1(a number, b number);
create table interface2(a number, b number);
insert all
when a <= 1 then
into interface1
else
into interface2
select '1' a, 2 b from dual;

Related

How to create table in Hive with specific column values from another table

I am new to Hive and have some problems. I try to find a answer here and other sites but with no luck... I also tried many different querys that come to my mind, also without success.
I have my source table and i want to create new table like this.
Were:
id would be number of distinct counties as auto increment numbers and primary key
counties as distinct names of counties (from source table)
You could follow this approach.
A CTAS(Create Table As Select)
with your example this CTAS could work
CREATE TABLE t_county
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS TEXTFILE AS
WITH t AS(
SELECT DISTINCT county, ROW_NUMBER() OVER() AS id
FROM counties)
SELECT id, county
FROM t;
You cannot have primary key or foreign keys on Hive as you have primary key on RBDMSs like Oracle or MySql because Hive is schema on read instead of schema on write like Oracle so you cannot implement constraints of any kind on Hive.
I can not give you the exact answer because of it suppose to you must try to do it by yourself and then if you have a problem or a doubt come here and tell us. But, what i can tell you is that you can use the insertstatement to create a new table using data from another table, I.E:
create table CARS (name string);
insert table CARS select x, y from TABLE_2;
You can also use the overwrite statement if you desire to delete all the existing data that you have inside that table (CARS).
So, the operation will be
CREATE TABLE ==> INSERT OPERATION (OVERWRITE?) + QUERY OPERATION
Hive is not an RDBMS database, so there is no concept of primary key or foreign key.
But you can add auto increment column in Hive. Please try as:
Create table new_table as
select reflect("java.util.UUID", "randomUUID") id, countries from my_source_table;

How can I merge two tables using ROWID in oracle?

I know that ROWID is distinct for each row in different tables.But,I am seeing somewhere that two tables are being merged using rowid.So,I also tried to see it,but I am getting the blank output.
I have person table which looks as:
scrowid is the column which contains rowid as:
alter table ot.person
add scrowid VARCHAR2(200) PRIMARY KEY;
I populated this person table as:
insert into ot.person(id,name,age,scrowid)
select id,name, age,a.rowid from ot.per a;
After this I also created another table ot.temp_person by same steps.Both table has same table structure and datatypes.So, i wanted to see them using inner join and I tried them as:
select * from ot.person p inner join ot.temp_person tp ON p.scrowid=tp.scrowid
I got my output as empty table:
Is there is any possible way I can merge two tables using rowid? Or I have forgotten some steps?If there is any way to join these two tables using rowid then suggest me.
Define scrowid as datatype ROWID or UROWID then it may work.
However, in general the ROWID may change at any time unless you lock the record, so it would be a poor key to join your tables.
I think perhaps you misunderstood the merging of two tables via rowid, unless what you actually saw was a Union, Cross Join, or Full Outer Join. Any attempt to match rowid, requardless of you define it, doomed to fail. This results from it being an internal definition. Rowid in not just a data type it is an internal structure (That is an older version of description but Oracle doesn't link documentation versions.) Those fields are basically:
- The data object number of the object
- The data block in the datafile in which the row resides
- The position of the row in the data block (first row is 0)
- The datafile in which the row resides (first file is 1). The file
number is relative to the tablespace.
So while it's possible for different tables to have the same rowid, it would be exteremly unlikely. Thus making an inner join on them always return null.

Fastest access to collection in PLSQL for updating values associated with a record

I'm trying to cache data to memory for fast access on 3 different keys in PLSQL. The problem is not really existent in any language that has pointers, but i'm struggling with PLSQL as of there is none that I'm aware of. I need to do this because I have a very large looping function that updates data in a very fine grained way and would last quite an eternity otherwise.
The basic idea is that I have a collection in memory sorted by key_1. I'd want to make changes to a value of the first record which would influence the key_1 value of the record itself and several other specific values of records in the collection which have the same key_2 and has any key_3 values as the record I modified. After the modification I'd just bubble sort the modified first row to it's place instead of using a time consuming query.
So basically a record looks like this:
create type t_num_tbl is table of number;
create type rec_type as object
(
key_1 number,
key_2 varchar2(30),
key_3 t_num_tbl
);
and the collection is like this:
create type rec_typetbl is table of rec_type;
v_rectbl rec_typetbl := rec_typetbl();
If I modify a record I'd have to give out a select/update that looks something like this to be able to modify the associated records:
SELECT *
FROM table(v_rectbl)t
WHERE t.key_2 = modifiedrec.key_2
AND
(SELECT count(*)
FROM table(t.key_3)
JOIN table(modifiedrec.key_3) USING (column_value)) > 1;
The main problem here is that the data is not indexed in the memory and the access is just not fast enough for my purpose.
Are there any solutions in PLSQL that could compare to the performance of using a pointer array in a record to the associated elements of the collection? The associations are known beforehand since key_2, key_3 values don't change.
First, I can recommend against your design and would rather see you use the RDBMS the way it is designed (i.e. indexed access).
Having said that, every Oracle table has a rownum pseudo column that is a pointer to a row (i.e. that's how indexes internally reference specific rows in a table). If you have the record, you can save the rownum in your data structure to get back to it quickly (don't persist the rownum long term as oracle can change the rownum when tables/rows are re-organized).

Creating instances of global temporary table

I created a GTT at schema level
CREATE GLOBAL TEMPORARY TABLE schema1.gtt1
(
col1 type1,
col2 type2,
...
)
ON COMMIT PRESERVE ROWS;
Now I can reference the table from within a PLSQL block/procedure/function very easily:
INSERT INTO schema1.gtt1
select col1, col2, ... from ...;
but what if in the same PLSQL block I want to insert values in another global temporary table (GTT) with the same structure as the one I created?
Do I have to create another GTT, and give it another name even if it has the very same structure (I think it would be awkward)? or can I somehow create multiple instances of a GTT?
Don't know if it's relevant but I'll be joining the GTT's with other tables, within the same PLSQL block.
You have 2 tables, A and B with same structure. (GTT but accessed from same session so we can ignore this)
Your question do I have to insert in both at runtime or can I use only one?
This is a question that only you can answer based on the meaning of what you insert and your need to differentiate the records.
If you need to make the difference between these 2 record sets (what you insert in A and what in B) but you have no key to make this distinction than you would need to: add a new column in structure like "source" or insert into different tables.
There is no "multiple instances" concept of GTT within session so this won't do the trick.

Insert into oracle database

Hi I have a database with loads of columns and I want to insert couple of records for testing, now in order to insert something into that database I'd have to write large query .. is it possible to do something like this
INSERT INTO table (SELECT FROM table WHERE id='5') .. I try to insert the row with ID 5 but I think this will create a problem because it will try to duplicate a record, is it possible to change this ID 5 to let say 1000 then I'd be able to insert data without writing complex query and while doing so avoiding replication of data .. tnx
In PL/SQL you can do something like this:
declare
l_rec table%rowtype;
begin
select * into l_rec from table where id='5';
l_rec.id := 1000;
insert into table values l_rec;
end;
If you have a trigger on the table to handle the primary key from a sequence (:NEW.id = seq_sequence.NEXTVAL) then you should be able to do:
INSERT INTO table
(SELECT columns_needed FROM table WHERE whatever)
This will allow you to add in many rows at one (the number being limited by the WHERE clause). You'll need to select the columns that are required by the table to be not null or not having default values. Beware of any unique constraints as well.
Otherwise you'll be looking at PL/SQL or some other form of script to insert multiple rows.
For each column that has no default value or you want to insert the values other than default, you will need to provide the explicit name and value.
You only can use an implicit list (*) if you want to select all columns and insert them as they are.
Since you are changing the PRIMARY KEY, you need to enumerate.
However, you can create a before update trigger and change the value of the PRIMARY KEY in this trigger.
Note that the trigger cannot reference the table itself, so you will need to provide some other way to get the unique number (like a sequence):
CREATE TRIGGER trg_mytable_bi BEFORE INSERT ON mytable FOR EACH ROW
BEGIN
:NEW.id := s_mytable.nextval;
END;
This way you can use the asterisk but it will always replace the value of the PRIMARY KEY.

Resources