Another year goes by, and most likely, another data access framework has been invented. It will claim to be the fastest, smartest way to talk to the database, and just like all those that came before it, it will not be. Because the best database access tool has been there for more than 30 years now, and that is PL/SQL. Although we all sometimes fall prey to the mindset of “Oh look, a shiny new tool, we should start using it," the performance and simplicity of PL/SQL remain unmatched. This session looks at the failings of other data access languages, why even a cursory knowledge of PL/SQL will make you a better developer, and how to get the most out of PL/SQL when it comes to database performance.
56. 56
SQL> create or replace
2 function simplepk(i int) return int is
3 res int;
4 begin
5 select pk
6 into res
7 from parse_demo
8 where pk = i;
9 return res;
10 end;
SimplePK
63. 63
SQL> create or replace
2 procedure simpleapi(i1 int, i2 int, o1 out int, o2 out int, o3 out int) is
3 begin
4 select region_id into o1 from customer where id = i1;
5
6 for i in ( select order_id from cust_orders where cust_id = i2 )
7 loop
8 o2 := i.order_id;
9 end loop;
10
11 select count(*) into o3 from order_items where order_id = o2;
12 end;
SimpleAPI
73. 73
SQL> create or replace
2 procedure MY_PROC is
3 begin
...
...
24 select any piece of old crap from dual;
...
...
75 end;
76 /
Warning: Procedure created with compilation errors.
79. 79
select ename
from emp
where empno = 6543
select ename
from emp
where empno = 6543
and 1=0
union all
select table_name
from all_tables
where table_name like '%SECURITY%'
select ename
from emp
where empno = 6543
and 1=0
union all
select username
from app_security
where ...
rs = stmt.executeQuery(
"select ename from emp where empno = " + v_empno );
80. 80
begin
select ename
into v_ename
from emp
where empno = v_empno;
begin
dbms_sql.parse(
v_cur,
'select ename from emp where empno = '||v_empno,
dbms_sql.native );
dbms_sql.define_column(v_cur, 1, v_ename, 30);
l_status := dbms_sql.execute(v_cur);
while ( dbms_sql.fetch_rows(v_cur) > 0 ) loop
dbms_sql.column_value(v_cur, 1, v_ename);
end loop;
112. 123
SQL> desc DBA_DEPENDENCIES
Name Null? Type
----------------------------- -------- --------------------
OWNER NOT NULL VARCHAR2(128)
NAME NOT NULL VARCHAR2(128)
TYPE VARCHAR2(19)
REFERENCED_OWNER VARCHAR2(128)
REFERENCED_NAME VARCHAR2(128)
REFERENCED_TYPE VARCHAR2(19)
REFERENCED_LINK_NAME VARCHAR2(128)
DEPENDENCY_TYPE VARCHAR2(4)
113. 124
SQL> create or replace
2 procedure MY_PROC is
3 v_ename scott.emp.ename%type;
4 begin
5 select ename
6 into v_ename
7 from scott.emp
8 where 1=0;
9 end;
10 /
SQL> select name, referenced_name
2 from dba_dependencies
3 where name = 'MY_PROC';
NAME REFERENCED_NAME
-------------------- -------------------------------------
MY_PROC STANDARD
MY_PROC EMP
146. 158
PROCEDURE customer_bet(
p_transaction_ts IN timestamp
,p_bet_type IN bet.bet_type%TYPE
,p_store IN bet.store%TYPE
,p_accountnum IN bet.bet_account_num%TYPE
,p_amount IN bet.amount%TYPE
...
);
PROCEDURE pay_winner(
p_transaction_ts IN timestamp
,p_bet_seq IN bet.bet_seq%TYPE
,p_bet_type IN bet.bet_type%TYPE
,p_store IN bet.store%TYPE
,p_accountnum IN bet.bet_account_num%TYPE
,p_amount_to_pay IN bet.paid_payout%TYPE
,p_amount_to_refund IN bet.paid_refunds%TYPE
...
);
150. 162
"We added one procedure to solve one problem,
then another procedure to solve another problem,
and very quickly...now they want PLSQL everywhere"
- Office Hours, June 2019