8 Oracle PLSQL Part2 m8 Slides
8 Oracle PLSQL Part2 m8 Slides
!!
Pankaj Jain
!
@twit_pankajj
Why Call Functions From SQL?
! !
Parallel Query
Increases Efficiency Extends SQL
Execution
of SQL
Where Can They Appear?
!
▪ Conditions !
SELECT count(*)
□ WHERE FROM employee
WHERE get_dept_name(emp_dept_id) = 'IT';
□ HAVING
!
! UPDATE employee
Do Not Place Anything in
SET emp_loc = ‘WA’
WHERE get_dept_name(emp_dept_id) = 'IT'; This Space
(Add watermark during editing)
Note: Warning will not appear
during Slide Show view.
Where Can They Appear?
▪ INSERT Statement
□ VALUES INSERT INTO employee (emp_id,
emp_name,
emp_dept_id )
! VALUES ( 5,
‘John',
! get_dept_id('IT'));
!
!
▪ Update Statement
!
□ SET Clause UPDATE employee
SET emp_dept_id = get_dept_id('IT')
! WHERE emp_id = 10;
Do Not Place Anything in
This Space
(Add watermark during editing)
Note: Warning will not appear
during Slide Show view.
Where Can They Appear?
!
▪ Others
□ ORDER BY
□ GROUP BY
!
SELECT count(*),
get_dept_name(emp_dept_id),
FROM employee
GROUP BY get_dept_name(emp_dept_id);
CREATE OR REPLACE
FUNCTION get_dept_name(p_dept_id in NUMBER) RETURN VARCHAR2 AS
CURSOR cur_get_dept_name IS
SELECT dept_name
FROM departments
WHERE dept_id = p_dept_id;
l_dept_name departments.dept_name%TYPE;
BEGIN
OPEN cur_get_dept_name;
FETCH cur_get_dept_name INTO l_dept_name;
CLOSE cur_get_dept_name;
! UPDATE employee SET emp_dept_id = p_dept_id WHERE emp_id = 10;
! COMMIT;
RETURN l_dept_name;
END get_dept_name; Do Not Place Anything in
This Space
(Add watermark during editing)
ORA-14551: cannot perform a DML operation inside a query Note: Warning will not appear
during Slide Show view.
ORA-14552: cannot perform a DDL, commit or rollback inside a query or DML
DML Statement
Restrictions Cannot Alter System or Session
No DML for Parallelized DML Statement
DML on the Same Table
No Transaction Statements
UPDATE employee
SET emp_dept_id = get_dept_id('IT') !
WHERE emp_id = 10;
!
CREATE OR REPLACE
!
FUNCTION get_dept_id(p_dept_name in VARCHAR2) RETURN NUMBER AS
CURSOR cur_get_dept_id IS
SELECT dept_id
FROM departments
WHERE dept_name = p_dept_name;
l_dept_id departments.dept_id%TYPE;
BEGIN
OPEN cur_get_dept_id;
FETCH cur_get_dept_id INTO l_dept_id;
CLOSE cur_get_dept_id;
! UPDATE employee SET emp_dept_id = p_dept_id WHERE emp_id = 10;
! COMMIT;
RETURN l_dept_id;
END get_dept_id; Do Not Place Anything in
This Space
(Add watermark during editing)
Note: Warning will not appear
ORA-04091: table EMPLOYEE is mutating, trigger / function may not see it during Slide Show view.
Deterministic Functions
Required for
Same Result for Function Based
Optimization
Same Input Indexes &
Technique
Values Materialized
Views
! SELECT emp_id,
! emp_sal,
!
CREATE OR REPLACE FUNCTION get_tier(p_sal NUMBER)
RETURN NUMBER AS
get_tier(emp_sal) tier
FROM employee
l_return NUMBER; ORDER BY emp_sal;
BEGIN
IF p_sal < 40000 THEN
EMP_ID EMP_SAL TIER
l_return := 1;
——————————————
ELSIF p_sal < 60000 THEN
20 40000 2
l_return := 2;
50 40000 2
ELSE
10 70000 3
l_return := 3;
60 70000 3
END IF;
DBMS_OUTPUT.PUT_LINE('p_sal '||p_sal);
RETURN l_return; !
EXCEPTION p_sal 40000
WHEN OTHERS THEN p_sal 40000
DBMS_OUTPUT.PUT_LINE(SQLERRM); p_sal 70000
RAISE; p_sal 70000
END get_tier;
! SELECT emp_id,
! emp_sal,
!
CREATE OR REPLACE FUNCTION get_tier(p_sal NUMBER)
RETURN NUMBER DETERMINISTIC AS
get_tier(emp_sal) tier
FROM employee
l_return NUMBER; ORDER BY emp_sal;
BEGIN
IF p_sal < 40000 THEN
EMP_ID EMP_SAL TIER
l_return := 1;
——————————————
ELSIF p_sal < 60000 THEN
20 40000 2
l_return := 2;
50 40000 2
ELSE
10 70000 3
l_return := 3;
60 70000 3
END IF;
DBMS_OUTPUT.PUT_LINE('p_sal '||p_sal);
RETURN l_return; !
EXCEPTION p_sal 40000
WHEN OTHERS THEN p_sal 70000
DBMS_OUTPUT.PUT_LINE(SQLERRM);
RAISE;
END get_tier;
!
! ALTER TABLE employee PARALLEL 3;
!
CREATE OR REPLACE FUNCTION get_tier(p_sal NUMBER)
RETURN NUMBER PARALLEL_ENABLE AS
l_return NUMBER;
BEGIN
SELECT degree
IF p_sal < 40000 THEN
FROM user_tables
l_return := 1;
WHERE table_name='EMPLOYEE';
ELSIF p_sal < 60000 THEN
l_return := 2;
ELSE
l_return := 3;
END IF;
DBMS_OUTPUT.PUT_LINE('p_sal '||p_sal); SELECT /*+ parallel (employee,4) */
RETURN l_return; emp_id,
EXCEPTION emp_sal,
WHEN OTHERS THEN get_tier(emp_sal) tier
DBMS_OUTPUT.PUT_LINE(SQLERRM); FROM employee
RAISE; ORDER BY emp_sal;
END get_tier;
▪ Prior to Oracle8i