create table cars ( name varchar2(100), start_year number, end_year number); insert into cars values('Swift',2007,2009); insert into cars values('Swift',2009,2011); insert into cars values('Swift',2011,2013); insert into cars values('Maruti',2009,2011); insert into cars values('Maruti',2013,2015);
commit; with r as (select distinct name,start_year+r year from cars, lateral(select rownum-1 r from dual connect by level <=end_year-start_year+1) order by 1,2) select name,min(year) s_year,max(year) e_year from r group by name,year-rownum;
Data Setup: create table tx_data(dt date, amnt number); insert into tx_data values(to_date('20-JUL-2019','DD-MON-YYYY'),100); insert into tx_data values(to_date('25-JUL-2019','DD-MON-YYYY'),200); insert into tx_data values(to_date('30-JUL-2019','DD-MON-YYYY'),300); commit; Query: with d1 as ( select min(dt) mi,max(dt) mx, max(dt)-min(dt) num from tx_data), dt_range as (select level-1+mi dt from d1 connect by level <=num+1) select dt_range.dt, last_value(amnt ignore nulls) over(order by dt_range.dt) amnt from dt_range left outer join tx_data on (dt_range.dt = tx_data.dt)
create table t1(c varchar2(1)); insert into t1 values('A'); insert into t1 values('B'); insert into t1 values('C'); create table t2(c varchar2(1)); insert into t2 values('D'); insert into t2 values('E'); insert into t2 values('F'); commit; ---------------------------------------------------- with t as (select c from t1 union select c from t2) select a1.c||'-'||a2.c output from t a1, t a2 where a1.c < a2.c; ---------------------------------------------------- with t as (select c from t1 union select c from t2) select distinct least(a1.c,a2.c), greatest(a1.c,a2.c) output from t a1, t a2 where a1.c <> a2.c order by 1; ----------------------------------------------------
A compound trigger combines the following triggers into one single trigger:
Before statement trigger
Before row trigger
After row trigger
After statement trigger
Advantages of “Compound trigger”?
Consolidating the individual triggers into single compound trigger
Global variables to share across timing events
Effectively load the changes to another table using bulk collect
To avoid mutating table error
CREATE OR REPLACE TRIGGER emp_comp_trigger FOR INSERT OR UPDATE OR DELETE ON EMP COMPOUND TRIGGER g_variable VARCHAR2(50) := 'DEMO ON COMPOUND TRIGGER'; BEFORE STATEMENT IS l_variable VARCHAR2(50) := ' BEFORE STATEMENT '; BEGIN dbms_output.put_line(l_variable||g_variable); END BEFORE STATEMENT; BEFORE EACH ROW IS l_variable VARCHAR2(50) := ' BEFORE EACH ROW '; BEGIN dbms_output.put_line(l_variable||g_variable); END BEFORE EACH ROW; AFTER EACH ROW IS l_variable VARCHAR2(50) := ' AFTER EACH ROW '; BEGIN dbms_output.put_line(l_variable||g_variable); END AFTER EACH ROW; AFTER STATEMENT IS l_variable VARCHAR2(50) := ' AFTER STATEMENT '; BEGIN dbms_output.put_line(l_variable||g_variable); END AFTER STATEMENT; END emp_comp_trigger; / CREATE OR REPLACE TRIGGER emp_comp_trigger FOR INSERT OR UPDATE OR DELETE ON EMP COMPOUND TRIGGER g_variable VARCHAR2(50) := 'DEMO ON COMPOUND TRIGGER'; BEFORE STATEMENT IS l_variable VARCHAR2(50) := ' BEFORE STATEMENT '; BEGIN if INSERTING then dbms_output.put_line(l_variable||g_variable||' INSERT '); elsif UPDATING then dbms_output.put_line(l_variable||g_variable||' UPDATE '); elsif DELETING then dbms_output.put_line(l_variable||g_variable||' DELETE '); end if; END BEFORE STATEMENT; END emp_comp_trigger; /
Grade based on employee salary(Subscriber Comments Reply Video 20 Grade based on employee salary)
CREATE TABLE emp_t (
empno number,
ename varchar2(100), sal number
);
insert into emp_t values (1,'KING',100);
insert into emp_t values (2,'BLAKE',500);
insert into emp_t values (3,'CLARK',1200);
insert into emp_t values (4,'JONES',2500);
insert into emp_t values (5,'SCOTT',3000);
insert into emp_t values (6,'FORD',700);
insert into emp_t values (7,'SMITH',1700);
insert into emp_t values (8,'ALLEN',2600);
insert into emp_t values (9,'WARD',400);
insert into emp_t values (10,'MARTIN',1500);
commit;
----------------------------------------------------------------
select EMPNO, ENAME, SAL,
case when sal >0 and sal <=1000 then 'A'
when sal >1000 and sal <=2000 then 'B'
else 'C' end grade
from emp_t;
----------------------------------------------------------------
select EMPNO, ENAME, SAL,
decode(ceil(SAL/1000),1,'A',2,'B','C')
from emp_t;
----------------------------------------------------------------
select EMPNO, ENAME, SAL,r.g
from emp_t,(select 0 mi,1000 mx,'A' g from dual
union
select 1001 mi,2000 mx,'B' g from dual
union
select 2001 mi,999999 mx,'C' g from dual) R
where sal >=mi and sal <=mx
order by 1;
----------------------------------------------------------------
Find the last two recharge amount for each customer ( Subscriber Comments Reply Video 19 Get the last two recharged amount)
Data Setup Scripts:
CREATE TABLE recharge_detail (
recharge_date DATE,
cust_name VARCHAR2(100),
recharge_amount NUMBER
);
insert into recharge_detail values( to_date('01/01/2019','DD/MM/YYYY'), 'Ragu',100);
insert into recharge_detail values( to_date('01/02/2019','DD/MM/YYYY'), 'Ragu',150);
insert into recharge_detail values( to_date('01/03/2019','DD/MM/YYYY'), 'Ragu',120);
insert into recharge_detail values( to_date('01/04/2019','DD/MM/YYYY'), 'Ragu',170);
insert into recharge_detail values( to_date('01/01/2019','DD/MM/YYYY'), 'Ravi',299);
insert into recharge_detail values( to_date('01/02/2019','DD/MM/YYYY'), 'Ravi',399);
insert into recharge_detail values( to_date('01/03/2019','DD/MM/YYYY'), 'Ravi',150);
insert into recharge_detail values( to_date('01/04/2019','DD/MM/YYYY'), 'Ravi',199);
insert into recharge_detail values( to_date('01/01/2019','DD/MM/YYYY'), 'Siva',100);
insert into recharge_detail values( to_date('01/02/2019','DD/MM/YYYY'), 'Siva',200);
insert into recharge_detail values( to_date('01/03/2019','DD/MM/YYYY'), 'Siva',400);
insert into recharge_detail values( to_date('01/04/2019','DD/MM/YYYY'), 'Siva',200);
commit;
-------------------------------------------------------------------------------------------------------------
select RECHARGE_DATE, CUST_NAME, RECHARGE_AMOUNT,
decode(rank() over(partition by cust_name order by Recharge_Date desc ),1,RECHARGE_AMOUNT,2,RECHARGE_AMOUNT) last_two_recharge_amount
from recharge_detail
order by CUST_NAME,RECHARGE_DATE;
-------------------------------------------------------------------------------------------------------------
select RECHARGE_DATE, CUST_NAME, RECHARGE_AMOUNT,
case when rank() over(partition by cust_name order by Recharge_Date desc ) in(1,2) then RECHARGE_AMOUNT end
from recharge_detail
order by CUST_NAME,RECHARGE_DATE;
-------------------------------------------------------------------------------------------------------------
SELECT
cust_name,
MAX(DECODE(r,1,recharge_amount) ) last_recharge,
MAX(DECODE(r,2,recharge_amount) ) last_2nd_recharge
FROM
(
SELECT
cust_name,
recharge_amount,
RANK() OVER(PARTITION BY cust_name ORDER BY recharge_date DESC ) r
FROM
recharge_detail
)
GROUP BY
cust_name;
create table emp1(empno number, ename varchar2(100)); create table emp2(empno1 number, ename1 varchar2(100), empno2 number, ename2 varchar2(100)); insert into emp1 values(1,'KING'); insert into emp1 values(2,'BLAKE'); insert into emp1 values(3,'CLARK'); insert into emp1 values(4,'JONES'); insert into emp1 values(5,'SCOTT'); insert into emp1 values(6,'FORD'); insert into emp1 values(7,'SMITH'); insert into emp1 values(8,'ALLEN'); insert into emp1 values(9,'WARD'); insert into emp1 values(10,'MARTIN'); insert into emp1 values(11,'SIVA'); commit; ------------------ insert into emp2 with d as (select empno,ename, round(count(1) over()/2) - (row_number() over(order by empno)) r from emp1), d1 as (select empno,ename,r from d where r >=0), d2 as (select empno,ename,abs(r) r from d where r <0) select d1.empno,d1.ename,d2.empno,d2.ename from d1 full outer join d2 on (d1.r = d2.r) order by d1.r desc; ------------------ insert into emp2 with d as (select empno,ename, round(count(1) over()/2) - (row_number() over(order by empno)) r from emp1), d1 as (select empno,ename,r from d where r >=0), d2 as (select empno,ename,abs(r) r from d where r <0) select d1.empno,d1.ename,d2.empno,d2.ename from d1 left outer join d2 on (d1.r = d2.r) order by d1.r desc;
WITH t AS ( SELECT 'WELCOME TO SQL CLASS' d FROM dual ) SELECT LISTAGG(s) WITHIN GROUP(ORDER BY l DESC) FROM ( SELECT level l,substr(d,level,1) s FROM t CONNECT BY level <= length(d) );
select regexp_substr('A,BB,CCC,DDDD','[^,]+',1,1) from dual; select regexp_substr('A,BB,CCC,DDDD','[^,]+',1,2) from dual; select regexp_substr('A,BB,CCC,DDDD','[^,]+',1,3) from dual;
select regexp_substr('A,BB,CCC,DDDD','[^,]+',1,4) from dual; ------------------------------------------------------------- WITH t AS ( SELECT '3,10,5,1,7,55,75,100,42,12,17' d FROM dual ) SELECT LISTAGG(s,',') WITHIN GROUP( ORDER BY to_number(s)) FROM( SELECT regexp_substr(d,'[^,]+',1,level) s FROM t CONNECT BY level <= regexp_count(d,',') + 1 ); ------------------------------------------------------------- WITH t AS ( SELECT '15 3 6 2 4 7 99 10 76 101 55 15 33 18' d FROM dual ) SELECT LISTAGG(s,' ') WITHIN GROUP(ORDER BY to_number(rtrim(ltrim(s) ) )) FROM( SELECT regexp_substr(regexp_replace(d,'\D+',','),'[^,]+',1,level) s FROM t CONNECT BY level <= regexp_count(regexp_replace(d,'\D+',','),',') + 1 );
------------------------------------------------------------- WITH t AS ( SELECT 'WELCOME' d FROM dual ) SELECT LISTAGG(d) WITHIN GROUP( ORDER BY d ) FROM( SELECT substr(d,level,1) d FROM t
Write a SQL to find the list of
combinations, where the third rolled dice value is equal to sum of first and
second rolled value
with t as ( select level r from dual connect by level <=6) select t1.r ROLL1,t2.r ROLL2,t1.r + t2.r ROLL3 from t t1,t t2 where t1.r + t2.r in( 6,5,4,3,2) order by t1.r + t2.r desc; with t as (select level r from dual connect by level<=6) select t1.r as ROLL1, t2.r as ROLL2, t3.r as ROLL3 from t t1, t t2, t t3 where (t3.r = t1.r+t2.r) order by 3 desc; with t as ( select level r from dual connect by level <=6) select t1.r ROLL1,t2.r ROLL2,t1.r + t2.r ROLL3 from t t1,t t2 where t1.r + t2.r <= 6 order by t1.r + t2.r desc;
Write a SQL Find the list of
combinations, where any roll value is equal to sum of other two rolled values
with t as (select level r
from dual connect by level<=6) select t1.r as ROLL1, t2.r as ROLL2, t3.r as ROLL3 from t t1, t t2, t t3 where (t3.r = t1.r+t2.r or t2.r = t1.r+t3.r or t1.r = t2.r+t3.r) order by 3 desc;
-------------------------------------------------------------------- set serveroutput on DECLARE CURSOR lc_emp_name IS SELECT ename FROM emp WHERE deptno=10; lv_emp_name varchar2(30); BEGIN OPEN lc_emp_name; LOOP FETCH lc_emp_name into lv_emp_name; EXIT WHEN lc_emp_name%notfound; dbms_output.put_line(lv_emp_name); END LOOP; CLOSE lc_emp_name; END; / -------------------------------------------------------------------- CREATE OR REPLACE PROCEDURE PRINT_LIST(p_in varchar2) as TYPE REF_CUR_TYPE IS REF CURSOR; lv_ref_cur REF_CUR_TYPE; lv_name VARCHAR2(30); BEGIN IF p_in='ENAME' THEN OPEN lv_ref_cur FOR SELECT ename FROM emp; ELSIF p_in='DNAME' THEN OPEN lv_ref_cur FOR 'SELECT dname FROM dept'; ELSIF p_in='JOB' THEN OPEN lv_ref_cur FOR SELECT distinct job FROM emp; ELSE OPEN lv_ref_cur FOR SELECT 'INVALID INPUT' FROM dual; END IF; LOOP FETCH lv_ref_cur INTO lv_name; EXIT WHEN lv_ref_cur%notfound; dbms_output.put_line(lv_name); END LOOP; END; / set serveroutput on EXEC PRINT_LIST('ENAME'); EXEC PRINT_LIST('DNAME'); EXEC PRINT_LIST('JOB'); EXEC PRINT_LIST('ABC'); -------------------------------------------------------------------- CREATE OR REPLACE PROCEDURE PROC_GET_LIST(p_in varchar2,p_out_cur out SYS_REFCURSOR) as lv_name VARCHAR2(30); BEGIN IF p_in='ENAME' THEN OPEN p_out_cur FOR SELECT ename FROM emp; ELSIF p_in='DNAME' THEN OPEN p_out_cur FOR 'SELECT dname FROM dept'; ELSIF p_in='JOB' THEN OPEN p_out_cur FOR SELECT distinct job FROM emp; ELSE OPEN p_out_cur FOR SELECT 'INVALID INPUT' FROM dual; END IF; END; / CREATE OR REPLACE PROCEDURE PROC_PRINT_LIST(p_in varchar2) AS TYPE lc_ref_cur_type IS REF CURSOR; lc_ref_cur lc_ref_cur_type; lv_name VARCHAR2(30); BEGIN PROC_GET_LIST(p_in,lc_ref_cur); LOOP FETCH lc_ref_cur INTO lv_name; EXIT WHEN lc_ref_cur%notfound; dbms_output.put_line(lv_name); END LOOP; END; / set serveroutput on exec PROC_PRINT_LIST('ENAME'); exec PROC_PRINT_LIST('DNAME'); exec PROC_PRINT_LIST('JOB'); exec PROC_PRINT_LIST('ABC'); -------------------------------------------------------------------- CREATE OR REPLACE PACKAGE emp_pkg AS CURSOR emp_list IS SELECT * FROM emp; CURSOR emp_list_10 IS SELECT * FROM emp WHERE deptno = 10; CURSOR emp_list_20 IS SELECT * FROM emp WHERE deptno = 20; END emp_pkg; / DECLARE lv_emp_rec emp%rowtype; BEGIN OPEN emp_pkg.emp_list; FETCH emp_pkg.emp_list into lv_emp_rec; dbms_output.put_line('ENAME = '||lv_emp_rec.ename); dbms_output.put_line('SAL = '||lv_emp_rec.sal); END; --------------------------------------------------------------------
SET SERVEROUTPUT ON DECLARE type ty_varchar_list is table of VARCHAR2(30); lv_name_list ty_varchar_list := ty_varchar_list (); BEGIN SELECT ename BULK COLLECT INTO lv_name_list FROM emp WHERE deptno = 10; FOR i IN lv_name_list.first..lv_name_list.last LOOP dbms_output.put_line('lv_name_list ('||i||')= '||lv_name_list(i) ); END LOOP; dbms_output.put_line('Third Name = '||lv_name_list(3) ); dbms_output.put_line('First Name = '||lv_name_list(1) ); dbms_output.put_line('Second Name = '||lv_name_list(2) ); END; /
SET SERVEROUTPUT ON DECLARE lv_name_list sys_refcursor; lv_name varchar2(30); BEGIN get_emp_list_as_refcur(10,lv_name_list); LOOP FETCH lv_name_list into lv_name; EXIT WHEN lv_name_list%notfound; dbms_output.put_line('lv_name = '||lv_name); END LOOP; END loop; /
create or replace type ty_varchar_list is table of VARCHAR2(30); / CREATE OR REPLACE PROCEDURE get_emp_list_as_coll (pin_deptno IN NUMBER, pout_name_list OUT ty_varchar_list) AS lv_varchar_list ty_varchar_list := ty_varchar_list (); BEGIN SELECT ename BULK COLLECT INTO lv_varchar_list FROM emp WHERE deptno = pin_deptno; pout_name_list := lv_varchar_list; END; / SET SERVEROUTPUT ON DECLARE lv_name_list ty_varchar_list := ty_varchar_list(); BEGIN get_emp_list_as_coll(10,lv_name_list); FOR i IN lv_name_list.first..lv_name_list.last LOOP dbms_output.put_line(lv_name_list(i) ); END LOOP; END loop; / Python Script to call the procedure
import cx_Oracle as orcl
con = orcl.connect('DEVUSER2/devuser2@ORCLPDB')
dbObjType = con.gettype("TY_VARCHAR_LIST")
pyobj = dbObjType.newobject()
cur.callproc("get_emp_list_as_coll", (10,pyobj,)) # Call the Procedurecur.close() # Close the Cursor
con.close() # Close the Connectionprint("Printing the values of collection as list:")
print(pyobj.aslist())
Example 4: (CUROSR) CREATE OR REPLACE PROCEDURE get_emp_list_as_refcur (pin_deptno NUMBER,pout_name_list OUT sys_refcursor) AS BEGIN open pout_name_list for SELECT ename FROM emp WHERE deptno = pin_deptno; END; / SET SERVEROUTPUT ON DECLARE lv_name_list sys_refcursor; lv_name varchar2(30); BEGIN get_emp_list_as_refcur(10,lv_name_list); LOOP FETCH lv_name_list into lv_name; EXIT WHEN lv_name_list%notfound; dbms_output.put_line('lv_name = '||lv_name); END LOOP; END loop; /
Python Script to call the procedure
import cx_Oracle as orcl
con = orcl.connect('DEVUSER2/devuser2@ORCLPDB')cur = con.cursor()
refcur = con.cursor()
cur.callproc("get_emp_list_as_refcur", (10,refcur,))print("Printing the values from REFCURSOR:")
for row in refcur:
print(row)
cur.close() # Close the Cursor