how to save group by result to variable or another table in oracle? - oracle

I'm not familiar with stored procedure yet. For optimize a time consuming operation of select count(1). I want to save the result to another table or dictionary data structure.
and I can quickly fetch the value of a given keyword.
Such as:
select name, count(1)
from mytable where ... group by name
How to save pairs of name and count to another table or a dictionary data structure?

Related

Is there a way to set the default sort statement for a table in Oracle PLSQL?

I have a log table like this:
fill_logs(
log_id number,
text varchar2(1000),
executed_on date,
...
)
It saves a log of some operations. And when I query this table I want this query to be sorted in descending order of the executed_on column by default. Sounds stupid, but I don't want to write order by clause every time.
So create a view SELECT * FROM FILL_LOGS ORDER BY EXECUTED_ON and use that view instead of the table.

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).

ORACLE SQL Query to fetch all table names IN DB whereever given value is treated as PK

Just want to know is this possible.
Say that if i have value 'X' and iam sure that this is referenced in some other tables as PK value but not sure about exactly which table is that, so i would like to know the list of those tables.
Pseudo query of above what i mentioned
SELECT TABLE_NAME FROM DBA_TABLES WHERE <<ATLEAST ONE OF THE TABLE ROW PK VALUE IS MATCHING EQUAL TO 'X'>>;

Get the no. of rows returned from sys_refcursor

I am writing an Oracle stored procedure with an OUT parameter as SYS_REFCURSOR.
The procedure does something like below:
open ref_cursorA for select * from tableA
save the no. of records retrieved to another table.
return the ref_cursorA for generating an Excel report.
However, there is no way to know the number of rows retrieved before fetching from the cursor, but I really need to save the no. of rows retrieved in the s.p. What should I do in this scenario?
When you open a cursor, the query hasn't been executed yet. It will be executed when you fetch the result rows. And most likely the execution will be piecewise, i.e. a few rows at a time.
So the number of rows is only know when the last row has been fetched.
If you really need the number of rows in your stored procedure, you'll have to execute an additional query that just counts the number of rows before you open and return the cursor for the main query:
select count(*) into var from tableA
Save the the number of rows in a separate table
open ref_cursorA for select * from tableA
return cursorA
Note:.Depending on your transaction isolation level, the COUNT(*) query will return a slightly different count if data is inserted and deleted at the same time.

Hive based data warehousing task- add sequence number to records

I have a use case where in i need to implement SQL based data warehousing activities using Hive.
The software would generate a bunch of csv files. When it transforms into SQL table, an unique id called session is assigned for each csv file and loaded into a SQL table. Let's say, I have 3 columns in csv files. I will have four columns in the SQL table wherein the first column represent the session. This means that, values stored in first csv file is written into the SQL table with the sessios id '1', and values from the second csv file is appended to the SQL table with the session id '2', and so on.
In Hive,
I stored these csv files in hdfs directory and want to create one hive table with the additional columns that represents the session id. I am not sure how I can do it. Any help or clue will be highly appreciated.
Try below approaches:
Using Random session id:
create external table on top of source dataset:
create external table staging (a string, b string, c string) location 'xyz';
Assign a unique id to each row:
insert into table destination as select reflect("java.util.UUID", "randomUUID") AS session_id, s.* from staging;
Using sequence number as session id:
create external table on top of source dataset:
create external table staging (a string, b string, c string) location 'xyz';
first time data load:
CREATE TABLE IF NOT EXISTS max_session_id (session_id int);
Append a sequence id to each record:
insert into table destination
select cast(coalesce(t.session_id,0) + row_number() over () as INT) as session_id, t1.*
from max_session_id t join destination t1 on 1=1;
Maintain max session id in separate table:
DROP TABLE IF EXISTS tmp_max_session_id;
CREATE TABLE tmp_max_session_id AS SELECT COALESCE(MAX(session_id), 0) AS session_id FROM destination;
INSERT OVERWRITE TABLE max_session_id SELECT * FROM tmp_max_session_id;
if you want to tag a same session id per file then add each file as a partition, you may store reflect("java.util.UUID", "randomUUID") or max_session_id in separate table while adding partition use newly generated session_id as partition id.

Resources