how to reach oracle object attributes? - oracle

I have a table that contains oracle COLOR_HISTOGRAM column, it contain values. It is an object type with colorlist and with colorfrequencielist.
How can i reach these attributes if if i want to insert the SI_COLORS to a table?
I declated two types that could contains these values
--CREATE OR REPLACE TYPE colorsList AS VARRAY(100) OF SI_Color;
--CREATE OR REPLACE TYPE colorFrequenciesList AS VARRAY(100) OF DOUBLE PRECISION;
ORDSYS.SI_COLORHISTOGRAM(
ORDSYS.COLORSLIST(
ORDSYS.SI_COLOR(195,157,133),
ORDSYS.SI_COLOR(226,223,215),
ORDSYS.SI_COLOR(191,154,131),
ORDSYS.SI_COLOR(139,94,61),
ORDSYS.SI_COLOR(221,40,43),
ORDSYS.SI_COLOR(85,47,30),
ORDSYS.SI_COLOR(237,45,51),
ORDSYS.SI_COLOR(190,60,47),
ORDSYS.SI_COLOR(66,53,49),
ORDSYS.SI_COLOR(145,66,63),
ORDSYS.SI_COLOR(192,115,111),
ORDSYS.SI_COLOR(64,50,46),
ORDSYS.SI_COLOR(178,151,123),
ORDSYS.SI_COLOR(178,153,129),
ORDSYS.SI_COLOR(170,140,114),
ORDSYS.SI_COLOR(174,150,124),
ORDSYS.SI_COLOR(146,118,106),
ORDSYS.SI_COLOR(189,168,145),
ORDSYS.SI_COLOR(190,171,148),
ORDSYS.SI_COLOR(144,71,57),
ORDSYS.SI_COLOR(86,45,26),
ORDSYS.SI_COLOR(193,109,80),
ORDSYS.SI_COLOR(145,138,136),
ORDSYS.SI_COLOR(130,121,120),
ORDSYS.SI_COLOR(115,80,72),
ORDSYS.SI_COLOR(186,50,37),
ORDSYS.SI_COLOR(193,171,149),
ORDSYS.SI_COLOR(0,0,0)),
ORDSYS.COLORFREQUENCIESLIST(99014.1,67706.4,38034.6,28478.2,5075.64,3302.56,2429.49,856.41,638.462,560.256,520.513,476.923,439.744,296.154,247.436,232.051,194.872,138.462,123.077,110.256,82.0513,75.641,62.8205,51.2821,46.1538,43.5897,32.0513,0))
Any idea highly appreciated.

you can reference the SI_COLOR values like this:
SQL> create table foo(r integer, b integer, g integer);
Table created.
SQL> insert into foo
2 select cl.redvalue, cl.bluevalue, cl.greenvalue
3 from tbl t, table(t.color_histogram.SI_COLORSLIST) cl;
28 rows created.
SQL> select * from foo;
R B G
---------- ---------- ----------
195 133 157
226 215 223
191 131 154
139 61 94
221 43 40
...etc..
for both arrays:
SQL> create table foo(r integer, b integer, g integer, freq number);
Table created.
SQL> insert into foo
2 select cl.redvalue, cl.bluevalue, cl.greenvalue, fl.freq
3 from (select t.rowid rid, cl.redvalue, cl.bluevalue, cl.greenvalue, rownum r
4 from tbl t, table(t.color_histogram.SI_COLORSLIST) cl) cl
5 inner join (select t.rowid rid, rownum r, fl.column_value freq
6 from tbl t, table(t.color_histogram.si_frequencieslist) fl) fl
7 on fl.rid = cl.rid
8 and fl.r = cl.r;
28 rows created.
SQL> select * from foo;
R B G FREQ
---------- ---------- ---------- ----------
195 133 157 1
226 215 223 2
191 131 154 3
139 61 94 4
..etc..
(as they are varrays we can rely on the ordering so rownum is ok).
or pl/sql:
SQL> begin
2 for r_row in (select t.color_histogram
3 from tbl t)
4 loop
5 for idx in 1..r_row.color_histogram.si_colorslist.count
6 loop
7 insert into foo
8 (r, g, b, freq)
9 values (r_row.color_histogram.si_colorslist(idx).redvalue,
10 r_row.color_histogram.si_colorslist(idx).greenvalue,
11 r_row.color_histogram.si_colorslist(idx).bluevalue,
12 r_row.color_histogram.si_frequencieslist(idx));
13 end loop;
14 end loop;
15 end;
16 /
PL/SQL procedure successfully completed.
SQL> select * from foo;
R B G FREQ
---------- ---------- ---------- ----------
195 133 157 1
226 215 223 2
191 131 154 3
139 61 94 4
221 43 40 5
85 30 47 6
etc..

Related

How to write a program for multiplication table PL/SQL ask the user input a number

How to write a program for multiplication table PL/SQL ask the user input a number
this is the code display just table without input
Declare
i NUMBER:=0;
x NUMBER;
Begin
loop
i := i+1;
x :=2*i;
dbms_output.put_line('2'||'x'||i||'='||x);
IF i >=10 THEN
EXIT ;
END IF;
END loop;
END;
/
A simple option (ran in SQL*Plus) is
SQL> set ver off
SQL> begin
2 for i in 1 .. 10 loop
3 dbms_output.put_line(&&par_number|| ' x ' || i ||' = '|| &&par_number * i);
4 end loop;
5 end;
6 /
Enter value for par_number: 2
2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10
2 x 6 = 12
2 x 7 = 14
2 x 8 = 16
2 x 9 = 18
2 x 10 = 20
PL/SQL procedure successfully completed.
SQL>
As Koen commented, depending on a client, substitution variable (&&par_number) might need to be modified to a bind variable (:par_number), or you'd enter it into a page item, or some other option.
More info you provide, better answer you get.
You could create the complete multiplication table with just sql and then select whatever you want without using PL/SQL ...
Here is the code: (all ran in SQL Developer)
WITH
nums AS
(
Select LEVEL "N" From Dual Connect By LEVEL <= 10
),
tbl AS
(
Select COL_N * N1 "N1", COL_N * N2 "N2", COL_N * N3 "N3", COL_N * N4 "N4", COL_N * N5 "N5",
COL_N * N6 "N6", COL_N * N7 "N7", COL_N * N8 "N8", COL_N * N9 "N9", COL_N * N10 "N10"
From ( SELECT n2.N "COL_N",n1. N "N", n1.N "ROW_N"
FROM nums n1
INNER JOIN nums n2 ON(1 = 1)
)
PIVOT ( MAX(N) FOR ROW_N IN(1 "N1", 2 "N2", 3 "N3", 4 "N4", 5 "N5", 6 "N6", 7 "N7", 8 "N8", 9 "N9", 10 "N10") )
Order By COL_N
)
... the content is
SELECT N1 "1", N2 "2", N3 "3", N4 "4", N5 "5", N6 "6", N7 "7", N8 "8", N9 "9", N10 "10" FROM tbl
1 2 3 4 5 6 7 8 9 10
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
... and select with variable passed to:
SELECT LPAD(N1, 2, ' ') || ' x ' || LPAD(&&M_NUM, 2, ' ') || ' = ' || LPAD(N1 * &&M_NUM, 3, ' ') "RESULTS"
FROM tbl
-- with &&M_NUM = 6 results:
RESULTS
--------------
1 x 6 = 6
2 x 6 = 12
3 x 6 = 18
4 x 6 = 24
5 x 6 = 30
6 x 6 = 36
7 x 6 = 42
8 x 6 = 48
9 x 6 = 54
10 x 6 = 60
... Or you could get the results in one row (it's 6 again)
SELECT * FROM tbl WHERE N1 = &&M_NUM
N1 N2 N3 N4 N5 N6 N7 N8 N9 N10
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
6 12 18 24 30 36 42 48 54 60
... or in columns ...
SELECT N1, &&M_NUM "MULTIPLYED _BY",
CASE &&M_NUM WHEN 2 THEN N2
WHEN 3 THEN N3
WHEN 4 THEN N4
WHEN 5 THEN N5
WHEN 6 THEN N6
WHEN 7 THEN N7
WHEN 8 THEN N8
WHEN 9 THEN N9
WHEN 10 THEN N10
END "RESULT"
FROM tbl
N1 MULTIPLYED _BY RESULT
---------- -------------- ----------
1 6 6
2 6 12
3 6 18
4 6 24
5 6 30
6 6 36
7 6 42
8 6 48
9 6 54
10 6 60
... or anything else you like...

PL/SQL how can ı fixed process flag id=4 wrong printing and how can I error message

Create table
create table curexample_test (id number, x number, y number, result number, process_flag varchar2(1), error_message varchar2(400))
insert into curexample_test
select 1, 20,4,null,null,null from dual
union
select 2, 15,3,null,null,null from dual
union
select 3, 36,9,null,null,null from dual
union
select 4, 7,0,null,null,null from dual
union
select 5, 105,15,null,null,null from dual
select * from curexample_test
Create function
create or replace function divider(n1 in number, n2 in number)
return number
is
pragma autonomous_transaction;
n3 number;
begin
if n2 = 0 then
n3 :=null;
update curexample_test set process_flag = 'E' where n3 = null ;
else
n3 :=n1 / n2;
update curexample_test set process_flag = 'S' where n3 !=0 ;
end if;
COMMIT;
return n3;
end;
Call function
select id,x,y , divider(x,y) as result,process_flag,error_message from curexample_test;
We rarely perform DML within a function; use a procedure, if you have to do that.
As of your code:
WHERE clauses in UPDATE statements have to be fixed
if you want to store the RESULT, fix the SET clause as well
if you're comparing something to NULL, then it isnt e.g. where n3 = null but where n3 IS NULL
SQL> CREATE OR REPLACE FUNCTION divider (n1 IN NUMBER, n2 IN NUMBER)
2 RETURN NUMBER
3 IS
4 PRAGMA AUTONOMOUS_TRANSACTION;
5
6 n3 NUMBER;
7 BEGIN
8 IF n2 = 0
9 THEN
10 n3 := NULL;
11
12 UPDATE curexample_test
13 SET result = n3, process_flag = 'E'
14 --WHERE n3 = NULL;
15 WHERE x = n1
16 AND y = n2;
17 ELSE
18 n3 := n1 / n2;
19
20 UPDATE curexample_test
21 SET result = n3, process_flag = 'S'
22 -- WHERE n3 != 0;
23 WHERE x = n1
24 AND y = n2;
25 END IF;
26
27 COMMIT;
28 RETURN n3;
29 END;
30 /
Function created.
Testing:
SQL> SELECT id,
2 x,
3 y,
4 divider (x, y) AS result,
5 process_flag,
6 error_message
7 FROM curexample_test;
ID X Y RESULT PROCESS_FLAG ERROR_MESSAGE
---------- ---------- ---------- ---------- --------------- --------------------
1 20 4 5
2 15 3 5
3 36 9 4
4 7 0
5 105 15 7
Table contents is then
SQL> select * from curexample_test;
ID X Y RESULT PROCESS_FLAG ERROR_MESSAGE
---------- ---------- ---------- ---------- --------------- --------------------
1 20 4 5 S
2 15 3 5 S
3 36 9 4 S
4 7 0 E
5 105 15 7 S
SQL>

How to iterate through dict with multiple columns in PL/SQL to take values from it and inject them into where statement in query

I've got problem as follows:
In oracle database I would like to run query which iterate through some kind of dictionary and take values from it to fill in where statement in query and return set of records for each single query, meaning if dict has 3 rows it should return three sets of record and union them afterwards. I have following tables:
dict(table)
country | filter_value
US | y
GE | N
UK | Y,N
data(table 1)
seller_id | country | flag | type
1 | US | y | w
2 | US | n | w
3 | GE | y | w
4 | GE | n | w
5 | UK | y | w
6 | UK | n | w
7 | PT | y | w
8 | GR | n | w
data(table 2)
seller_id | country | flag | type
19 | US | y | d
28 | US | n | d
33 | GE | y | d
44 | GE | n | d
54 | UK | y | d
66 | UK | n | d
71 | PT | y | d
82 | GR | n | d
and I would like to run something like this:
union_data=empty table
for row in dict:
select * from data(table1) where country=row.country and flag in (row.filter_value)
select * from data(table2) where country=row.country and flag in (row.filter_value)
union results from this both queries is one table meaning this union_data
I'm completely new in PL/SQL and to be honest don't know which functionality would work out the issue.
There are (at least) two options.
The first one is simpler and looks like this: create a function (returns a refcursor) which accepts country, finds filter value and applies both "parameters" to select statement(s):
SQL> create or replace function f_test (par_country in varchar2)
2 return sys_refcursor
3 is
4 l_filter_value dict.filter_value%type;
5 l_rc sys_refcursor;
6 begin
7 select filter_value
8 into l_filter_value
9 from dict
10 where country = par_country;
11
12 open l_rc for
13 select seller_id, country, flag, type
14 from data
15 where country = par_country
16 and flag = l_filter_value
17 union all
18 select seller_id, country, flag, type
19 from data2
20 where country = par_country
21 and flag = l_filter_value;
22
23 return l_rc;
24 end;
25 /
Function created.
Testing:
SQL> select f_test('US') from dual;
F_TEST('US')
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
SELLER_ID COUNTRY FLAG TYPE
---------- ---------- ---- ----
1 US Y W
19 US Y D
SQL>
If that's too simple (meaning: you can't/don't want to do it that way), use dynamic SQL. The principle is similar to previous. This example includes "what if DICT table contains both Y,N in filter_value" - in that case, split fetched filter_value to rows (that's what hierarchical subqueries do).
SQL> create or replace function f_test (par_country in varchar2)
2 return sys_refcursor
3 is
4 l_filter_value dict.filter_value%type;
5 l_rc sys_refcursor;
6 begin
7 select filter_value
8 into l_filter_value
9 from dict
10 where country = par_country;
11
12 open l_rc for
13 select seller_id, country, flag, type
14 from data
15 where country = par_country
16 and flag in (select regexp_substr(l_filter_value, '[^,]+', 1, level)
17 from dual
18 connect by level <= regexp_count(l_filter_value, ',') + 1
19 )
20 union all
21 select seller_id, country, flag, type
22 from data2
23 where country = par_country
24 and flag in (select regexp_substr(l_filter_value, '[^,]+', 1, level)
25 from dual
26 connect by level <= regexp_count(l_filter_value, ',') + 1
27 );
28
29 return l_rc;
30 end;
31 /
Function created.
Testing:
SQL> select f_test('US') from dual;
F_TEST('US')
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
SELLER_ID COUNTRY FLAG TYPE
---------- ---------- ---- ----
1 US Y W
19 US Y D
SQL> select f_test('UK') from dual;
F_TEST('UK')
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
SELLER_ID COUNTRY FLAG TYPE
---------- ---------- ---- ----
5 UK Y W
6 UK N W
54 UK Y D
66 UK N D
SQL>

Fetch data from columns using max over another column using Oracle analytic functions

I need to fetch the sum between bal and res columns for each different account (acc) using the max(timestamp), look at this:
ID ACC BAL RES TIMESTAMP
--------------------------
1 100 70 0 1430238709
2 101 4 0 1430238710
3 102 0 0 1430238720
4 103 3 1 1430238721
5 100 22 1 1430238731
6 101 89 0 1430238732
7 102 101 1 1430238742
8 103 105 1 1430238753
9 100 106 0 1430238763
10 101 100 1 1430238774
11 102 1 1 1430238784
12 103 65 0 1430238795
What I need is for MAX(timestamp) <= 1430238763, the sum: bal + res grouped by acc like this:
ACC TOT
-------
100 106
101 89
102 102
103 106
I know how to do it using subqueries, but I would like to try Analytics.
Regards
How about:
Select * from (
Select t.*, max(TIMESTAMP) over (partition by id) mx
from tab t
)
where mx=TIMESTAMP;
hth
your query is not solve without sub query.
select acc,sum(bal + res) from table_name where timestamp in
(select acc,max(timestamp) from table_Name group by acc having hax(timestamp)<=1430238763)
Regards.

Can i find out if a column is a primary key through Oracle ALL_TAB_COLS view?

Can i find out if a column is a primary or foreign key through Oracle's ALL_TAB_COLS view?
select *
from all_tab_cols
where table_name = 'ALL_TAB_COLS'
;
1 SYS ALL_TAB_COLS OWNER VARCHAR2 30 N 1 <Long> CHAR_CS 30 NO NO 30 B NO YES NO NO 1 1
2 SYS ALL_TAB_COLS TABLE_NAME VARCHAR2 30 N 2 <Long> CHAR_CS 30 NO NO 30 B NO YES NO NO 2 2
3 SYS ALL_TAB_COLS COLUMN_NAME VARCHAR2 30 N 3 <Long> CHAR_CS 30 NO NO 30 B NO YES NO NO 3 3
4 SYS ALL_TAB_COLS DATA_TYPE VARCHAR2 106 Y 4 <Long> CHAR_CS 106 NO NO 106 B NO YES NO NO 4 4
5 SYS ALL_TAB_COLS DATA_TYPE_MOD VARCHAR2 3 Y 5 <Long> CHAR_CS 3 NO NO 3 B NO YES NO NO 5 5
6 SYS ALL_TAB_COLS DATA_TYPE_OWNER VARCHAR2 30 Y 6 <Long> CHAR_CS 30 NO NO 30 B NO YES NO NO 6 6
7 SYS ALL_TAB_COLS DATA_LENGTH NUMBER 22 N 7 <Long> NO NO 0 NO YES NO NO 7 7
8 SYS ALL_TAB_COLS DATA_PRECISION NUMBER 22 Y 8 <Long> NO NO 0 NO YES NO NO 8 8
9 SYS ALL_TAB_COLS DATA_SCALE NUMBER 22 Y 9 <Long> NO NO 0 NO YES NO NO 9 9
10 SYS ALL_TAB_COLS NULLABLE VARCHAR2 1 Y 10 <Long> CHAR_CS 1 NO NO 1 B NO YES NO NO 10 10
11 SYS ALL_TAB_COLS COLUMN_ID NUMBER 22 Y 11 <Long> NO NO 0 NO YES NO NO 11 11
12 SYS ALL_TAB_COLS DEFAULT_LENGTH NUMBER 22 Y 12 <Long> NO NO 0 NO YES NO NO 12 12
13 SYS ALL_TAB_COLS DATA_DEFAULT LONG 0 Y 13 <Long> CHAR_CS 0 NO NO 0 NO YES NO NO 13 13
14 SYS ALL_TAB_COLS NUM_DISTINCT NUMBER 22 Y 14 <Long> NO NO 0 NO YES NO NO 14 14
15 SYS ALL_TAB_COLS LOW_VALUE RAW 32 Y 15 <Long> NO NO 0 NO YES NO NO 15 15
16 SYS ALL_TAB_COLS HIGH_VALUE RAW 32 Y 16 <Long> NO NO 0 NO YES NO NO 16 16
17 SYS ALL_TAB_COLS DENSITY NUMBER 22 Y 17 <Long> NO NO 0 NO YES NO NO 17 17
18 SYS ALL_TAB_COLS NUM_NULLS NUMBER 22 Y 18 <Long> NO NO 0 NO YES NO NO 18 18
19 SYS ALL_TAB_COLS NUM_BUCKETS NUMBER 22 Y 19 <Long> NO NO 0 NO YES NO NO 19 19
No - you can't since this information is not part of that view, see http://download.oracle.com/docs/cd/B13789_01/server.101/b10755/statviews_1179.htm
To find out the primary key column(s) of a table see http://www.techonthenet.com/oracle/questions/find_pkeys.php - the information is in the Views all_constraints + all_cons_columns .
To find foreign key information try:
SELECT cols.table_name, cols.column_name, cols.position, cons.status, cons.owner
FROM all_constraints cons, all_cons_columns cols
WHERE cons.constraint_type = 'R'
AND cons.constraint_name = cols.constraint_name
ORDER BY cols.table_name, cols.position;
The below query of Oracle DB, will list you all such table names present in your current schema which have the given column (YOUR_COLUMN_NAME) declared as primary key/composite key:
SELECT cols.table_name,
cols.column_name,
cols.position,
cons.status,
cons.owner
FROM all_constraints cons,
all_cons_columns cols
WHERE cons.constraint_type = 'P'
AND cols.column_name = '<GIVE_YOUR_COLUMN_NAME_HERE>'
AND cons.constraint_name = cols.constraint_name
AND cons.owner = cols.owner
ORDER BY cols.table_name,cols.position;
This is what I did to determine whether or not a column was part of a primary key (Assuming Primary keys have not been given fancy names):
select a.*, b.CONSTRAINT_NAME
from ALL_TAB_COLS a
left join
(select CONSTRAINT_NAME,table_name,column_name from ALL_CONS_COLUMNS
where OWNER= '<USER_YOU_WANT>'
and (CONSTRAINT_NAME like '%PK'
or CONSTRAINT_NAME like 'PK%'
or CONSTRAINT_NAME like '%PK%')
and CONSTRAINT_NAME not like 'BIN%') B on a.COLUMN_NAME=B.COLUMN_NAME and a.TABLE_NAME=B.TABLE_NAM
WHERE a.OWNER='<USER_YOU_WANT>'
;

Resources