0% found this document useful (0 votes)
29 views32 pages

SQL Objects and PLSQL

This document discusses SQL objects and PL/SQL datatypes beyond basic datatypes. It covers PL/SQL record types, SQL object types, constructor methods, PL/SQL collection types, SQL collection types, functions returning collections, pipelined functions, and collection operators like MULTISET. It provides examples of using record types, object types, collections, and pipelined functions in both SQL and PL/SQL.

Uploaded by

pavanreddy16
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
Download as pptx, pdf, or txt
0% found this document useful (0 votes)
29 views32 pages

SQL Objects and PLSQL

This document discusses SQL objects and PL/SQL datatypes beyond basic datatypes. It covers PL/SQL record types, SQL object types, constructor methods, PL/SQL collection types, SQL collection types, functions returning collections, pipelined functions, and collection operators like MULTISET. It provides examples of using record types, object types, collections, and pipelined functions in both SQL and PL/SQL.

Uploaded by

pavanreddy16
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1/ 32

Beyond Basic Datatypes

SQL Objects and PL/SQL


Who am I ?
 Gary Myers
 Oracle developer since 1994
 Database Consultant with SMS M&T
 Blogger since 2004
Now at blog.sydoracle.com
 Twitter at syd_oracle
 Guest editor at Log Buffer
 "Oracle" badge at Stackoverflow forums
 Find me at LinkedIn…
What is PL/SQL
 PL/SQL is an EXTENSION to SQL
 PL/SQL is procedural
 Closely tied to the database
 Runs under the oracle shadow process
 Mostly in the PGA
BEWARE Shared Server (eg APEX)
PL/SQL Datatypes
 As an extension, PL/SQL recognizes all
SQL datatypes (except LONG)
 That includes user-defined datatypes
 User-defined datatypes includes Oracle
supplied ones such as Spatial (MDSYS)
and Multimedia (ORDSYS).
PL/SQL specific datatypes
 Boolean, PLS_INTEGER etc
 Only within PL/SQL
 Cannot be used to ‘talk’ to SQL.
Avoid as function parameters

 Some potential for better performance


and/or memory consumption
PL/SQL Record Types
CREATE PROCEDURE TEST
TYPE typ_rec is RECORD
(id NUMBER,
val VARCHAR2(20));
t_rec1 typ_rec;
t_rec2 typ_rec;
BEGIN
t_rec1.id := 5;
t_rec1.val := 'TEST';
t_rec2 := t_rec1;
t_rec1 := null;
END;
SQL Object Type
CREATE TYPE typ_rec is OBJECT
(id NUMBER,
val VARCHAR2(20));
/
SELECT typ_rec(1,’test’)
FROM DUAL;
Constructor Methods
CREATE TYPE holt AS OBJECT
(record_type varchar2(1),
record_column varchar2(10) ,
CONSTRUCTOR FUNCTION holt
( i_record_type in varchar2 default null,
i_record_column in varchar2 default null)
return self as result);
Constructor Method Body
CREATE OR REPLACE TYPE body holt is
CONSTRUCTOR FUNCTION holt
(i_record_type in varchar2 default null,
i_record_column in varchar2 default null)
return self as result is
begin
self.record_type := i_record_type;
self.record_column := i_record_column;
RETURN;
end holt;
end;
PL/SQL using SQL Type
declare
v_holt holt;
begin
v_holt := holt(
i_record_type => 'a',
i_record_column => 'B');
end;
/
PL/SQL Collection Types
CREATE PROCEDURE TEST
TYPE typ_coll_vc10 is TABLE
OF VARCHAR2(10) INDEX BY
PLS_INTEGER;
tc_val typ_coll_vc10;
BEGIN
tc_val(1) := 'TEST';
END;
SQL Collection Types
 SQL Collection types cannot have
member functions.

 They do have functionality equivalent to


a default constructor though

 You can create an object that includes a


collection
SQL collection as Table
 You can select from a collection using
the syntax

SELECT column_value
from TABLE(

tab_varchar_4000( 'a','b','c')
);
FREE
There's a default collection type in
the database, granted to public

SYS.DBMS_DEBUG_VC2COLL

select * from
table(sys.dbms_debug_vc2coll
('a','b','c'))
Functions returning collections
CREATE FUNCTION gen_dates
(i_start in date, i_end in date)
RETURN tab_varchar_4000 IS
v_tab tab_varchar_4000 :=
tab_varchar_4000();
BEGIN
v_tab.extend(1 + i_end - i_start );
FOR i in 0..( i_end - i_start ) LOOP
v_tab(i+1) := i_start + i;
END LOOP;
RETURN v_tab;
END;
Pipelined functions
CREATE FUNCTION gen_dates
RETURN tab_varchar_4000 PIPELINED IS
CURSOR c_1 is
select sysdate dt from dual
connect by level < 100;
BEGIN
FOR i in c_1 LOOP
PIPE ROW (to_char(i.dt));
END LOOP;
RETURN;
END;
Wouldn't it be nice….
procedure p_test is
Begin
dbms_output.put_line('point 1');
. . .
dbms_output.put_line('point 2');
. . .
End;
Does not allow DML
Function p_test
return tab_varchar_4000 pipelined is
Begin
pipe row('point 1');
update….
pipe row('point 2');
End;
Must be at the top level
Procedure process_records is
procedure debug (p_text in varchar2)
is
begin
pipe row (p_text);
end;
Begin
. . .
End;
Warning – No Data Found
TABLE() functions
complete with a
NO_DATA_FOUND
It gets worse
Non-existent collection elements
also return a no_data_found
Pipelined Functions and
PL/SQL Collections
A PL/SQL collection type can also be used
in a pipelined function

It implicitly creates three SQL level-types


(starting with SYS_PLSQL_object_id)

These types can be amended with ALTER


TYPE (but that's not a good idea)
INDEX BY VARCHAR2
Added in 9iR2

Allows a degree of caching in PL/SQL

Useful if you have an expensive calculation


that you can reuse (much like the function
result cache in 11g).
SQL collection operators
COLLECT will aggregate up a set of data
items into an on-the-fly collection
select collect('test')
from dual connect by level < 10;
You can CAST that collection to your own
collection type, if compatible.

Beware of CHAR / VARCHAR2


incompatibilities
Like any Aggregate Function
DISTINCT
select collect(distinct
to_char(sysdate))
from dual connect by level < 5;
GROUP BY
select cast(collect(object_name) as
tab_varchar_4000) t
from user_objects
group by object_type;
Collections and Sets
Definition :
A collection is a set if it doesn't
have duplicates
SET testing
select 1 a from dual
where mset('a','b','a') is a set;
no rows selected

select 1 a from dual


where mset('a','b') is a set;
A
----------
1
MULTISET operators
Turn a collection into a set.

select
mset('z','a','a','c','d','c')
multiset union distinct
mset()
from dual;

There are also INTERSECT and EXCEPT


(not MINUS)
SET comparison
select 1 from dual
where 'a' member mset('a','b');
1

select 1 from dual


where mset('a') submultiset mset('a','b');
1

select 1 a from dual


where mset('a','c') submultiset
mset('a','b');
no rows selected
Collection comparison
You can compare simple collections
in PL/SQL with an equals operator

declare
x1 mset := mset('a','b');
x2 mset := mset('b','a');
begin
if x1 = x2 then
dbms_output.put_line('Match');
end if;
end;
Multiset operators in PL/SQL
declare
x1 mset := mset('a','b');
x2 mset := mset('b');
x3 mset;
begin
x3 := x1 multiset except x2;
dbms_output.put_line(x3.count
|| '.'||x3(1));
end;
Final Thought
For complex logic
SQL*Plus embedded
in shell scripts is
NOT
a good idea

You might also like