SlideShare une entreprise Scribd logo
1  sur  92
Télécharger pour lire hors ligne
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	
All About
PL/SQL Collections	
1	
Steven	Feuerstein	
Oracle	Developer	Advocate	for	PL/SQL	
Oracle	CorporaDon	
	
Email:	steven.feuerstein@oracle.com	
TwiLer:	@sfonplsql	
Blog:	stevenfeuersteinonplsql.blogspot.com	
YouTube:	PracDcally	Perfect	PL/SQL
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	2	
Resources	for	Oracle	Database	Developers	
•  Official	home	of	PL/SQL	-	oracle.com/plsql	
•  SQL-PL/SQL	discussion	forum	on	OTN	
hLps://community.oracle.com/community/database/developer-tools/sql_and_pl_sql	
•  PL/SQL	and	EBR	blog	by	Bryn	Llewellyn	-	hLps://blogs.oracle.com/plsql-and-ebr	
•  Oracle	Learning	Library	-	oracle.com/oll		
•  Weekly	PL/SQL	and	SQL	quizzes,	and	more	-	plsqlchallenge.oracle.com	
•  Ask	Tom	-	asktom.oracle.com	–	'nuff	said	
•  LiveSQL	-	livesql.oracle.com	–	script	repository	and	12/7	12c	database	
•  oracle-developer.net	-	great	content	from	Adrian	Billington	
•  oracle-base.com	-	great	content	from	Tim	Hall
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	3	
Agenda	
•  IntroducDon	and	overview		
•  Defining	and	using	collecDon	types	
•  Using	collecDon	methods	
•  Working	with	associaDve	arrays	
•  Working	with	nested	tables	
•  Working	with	varrays	
•  Using	collecDons	inside	SQL	
•  Benefits	of	Non-SequenDal	Indexing	
•  Using	String	Indexes	with	AssociaDve	Arrays	
•  Working	with	Nested	CollecDons	
•  Using	MULTISET	Operators	with	Nested	Tables	
•  Best	PracDces	for	CollecDons
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	4	
PL/SQL	Collec>ons	
•  A	collecDon	is	an	"ordered	group	of	elements,	
all	of	the	same	type."	(PL/SQL	User	Guide)	
– In	short,	a	"homogeneous"	list	of	"stuff"	
•  CollecDons	are	similar	to	single-dimensional	
arrays	in	other	programming	languages.	
– With	lots	of	subtle	differences,	as	well.	
•  CollecDons	almost	always	consume	Process	
Global	Area	memory.	
•  CollecDons	should	be	a	"go	to"	datatype	for	
Oracle	Database	developers	
1	 Apple	
22	 Pear	
100	 Orange	
10023	 Apricot
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	5	
System Global Area (SGA) of RDBMS Instance
PL/SQL	in	Shared	Memory	
Shared	Pool	
Large	Pool	
Reserved	Pool	
show_emps	calc_totals	 upd_salaries	
Select *
from emp
Shared	SQL	
Pre-parsed	
Update emp
Set sal=...
Library	cache	
Session	1	memory		(PGA/UGA)	
emp_rec emp%rowtype;
tot_tab tottabtype;
Session	2	memory		(PGA/UGA)	
emp_rec emp%rowtype;
tot_tab tottabtype;Session	1	 Session	2
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	6	
How	PL/SQL	uses	the	SGA,	PGA	and	UGA	
• The	SGA	contains	informaDon	that	can	be	shared	across	
sessions	connected	to	the	instance.	
– In	PL/SQL,	this	is	limited	to	package	staDc	constants.	
• The	User	Global	Area	contains	session-specific	data	that	
persists	across	server	call	boundaries	
– Package-level	data	
• The	Process	Global	Area	contains	session-specific	data	that	is	
released	when	the	current	server	call	terminates:	"local"	data.	
PACKAGE Pkg is
  Nonstatic_Constant CONSTANT PLS_INTEGER := My_Sequence.Nextval;
  Static_Constant    CONSTANT PLS_INTEGER := 42;
END Pkg;
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	7	
Calcula>ng	PGA	and	UGA	Consump>on	
• Oracle	keeps	track	of	and	shows	the	PGA	and	UGA	consumpDon	for	a	
session	in	the	v_$sesstat	dynamic	view.	
• With	the	correct	privileges,	PL/SQL	developers	can	analysis	their	code's	
memory	usage.	
show_pga_uga.sql
grantv$.sql
plsql_memory.pkg
plsql_memory_demo.sql
SELECT n.name, s.VALUE
FROM sys.v_$sesstat s, sys.v_$statname n
WHERE s.statistic# = n.statistic# AND s.sid = my_session.sid
AND n.name IN ('session uga memory', 'session pga memory')
BEGIN
plsql_memory.start_analysis;
run_my_application;
plsql_memory.show_memory_usage;
END;
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	8	
Why	use	collec>ons?	
• Generally,	to	manipulate	lists	of	informaDon	in	memory.		
– Of	course,	you	can	use	relaDonal	tables,	too.	
– CollecDon	manipulaDon	is	generally	much	faster	than	using	SQL	to	modify	the	
contents	of	tables.		
• CollecDons	enable	other	key	features	of	PL/SQL	
– BULK	COLLECT	and	FORALL	use	them	to	boost	mulD-row	SQL	performance	
– Serve	up	complex	datasets	of	informaDon	to	non-PL/SQL	host	environments	using	
table	func/ons.
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	9	
Different	Types	of	Collec>ons	
• Three	types	of	collecDons	
– AssociaDve	array	
– Nested	table	
– Varray	(varying	arrays)	
• AssociaDve	array	is	a	PL/SQL-only	datatype.	
• Nested	tables	and	varrays	can	be	used	within	PL/SQL	blocks	and	also	from	
within	SQL.	
– Column	tables	
– Table	funcDons
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	10	
Glossary	of	Terms	
•  Element
– A collection is made up of one or more elements, all of the same type. Also referred to
as "row."
– Can be of almost any valid PL/SQL type.
•  Index value
– The "location" in the collection in which an element is found. Also referred to as "row
number."
– Usually an integer, can also be a string (associative arrays only)
•  Dense
– Every index value between lowest and highest has a defined element.
•  Sparse
– One or more elements between lowest and highest index values may be undefined
(gaps).
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	11	
Defining	collec>on	types	
• Before	you	can	manipulate	a	collecDon	variable,	you	need	a	collecDon	
type	on	which	to	declare	the	variable.	
• Oracle	pre-defines	several	collecDon	types	in	various	supplied	packages.	
• DBMS_SQL	
– Dynamic	SQL-specific	types	
– Generic	types	(list	of	strings,	numbers,	etc.).	
• DBMS_OUTPUT	
– List	of	strings
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	12	
Defining	collec>on	types	
• Declare	all	collecDon	type	with	a	TYPE	statement.	
• AssociaDve	arrays	use	IS	TABLE	OF	and	the	INDEX	BY	clause.	
• Nested	tables	use	IS	TABLE	OF,	without	any	indexing	clause.	
• Varrays	use	IS	VARRAY	OF	syntax.	
TYPE coll_name IS TABLE OF element_type INDEX BY index_type;
TYPE coll_name IS TABLE OF element_type;
TYPE coll_name IS VARRAY (limit) OF element_type;
Associa>on	array	type	
Nested	table	type	
Varray	type
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	13	
Scope	for	Collec>on	Types	
• You	can	define	collecDon	types	in:	
– Local	block	–	can	be	used	only	in	that	block	
– Package		-	available	for	use	by	any	session	with	execute	authority	on	that	package	
– Schema	–	in	the	SQL	layer,	possible	only	for	nested	tables	and	varrays	
• Avoid	"reinvenDng"	collecDon	types	in	many	places	in	your	code.	
– They	are	excellent	candidates	for	shared	code	elements.
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	14	
Local	collec>on	types	
• TYPE	statement	found	in	declaraDon	secDon	of	block	(anonymous,	nested,	
subprogram)	
• It	is	defined	and	then	destroyed	each	Dme	the	block	is	executed.	
• You	should	avoid	local	types;	it	will	likely	lead	to	redundancies	in	your	
code.	
DECLARE
TYPE strings_t IS TABLE OF VARCHAR2(100);
PROCEDURE my_procedure
IS
TYPE strings_t IS TABLE OF VARCHAR2(100);
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	15	
Package-level	Types	
• When	defined	in	the	package	specificaDon,	it	becomes	a	"globally"	
available	type.	
– Any	session	with	EXECUTE	authority	on	the	package	can	use	the	type	to	declare	
collecDons.	
• In	the	package	body,	can	only	be	used	by	subprograms	of	that	package.	
• Excellent	repository	for	applicaDon-specific	types	
PACKAGE my_types
IS
TYPE strings_t IS TABLE OF VARCHAR2(100);
colltypes.pks
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	16	
Schema-level	Types	
• Defined	in	the	schema,	independent	of	any	PL/SQL	program	unit.	
• Any	session	with	EXECUTE	authority	on	type	can	use	it	to	declare	
collecDon	variables.	
– CollecDons	of	this	type	can	also	be	directly	referenced	inside	SQL	statements.	
• Can	only	be	used	with	nested	tables	and	varrays.	
– AssociaDve	arrays	are	PL/SQL-specific,	cannot	be	defined	at	the	schema	level	(SQL	
layer).	
CREATE OR REPLACE TYPE strings_t IS TABLE OF VARCHAR2(100)
GRANT EXECUTE ON strings_t TO PUBLIC
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	17	
Declaring	collec>on	variables	
• Once	you	have	defined	your	collecDon	type,	you	can	define	a	variable	
based	on	that.	
– The	same	as	for	any	type	of	data	in	PL/SQL	
CREATE TYPE hire_dates_t IS TABLE OF DATE;
CREATE PACKAGE my_types IS
TYPE strings_t IS TABLE OF VARCHAR2(100);
END my_types;
DECLARE
l_names my_types.string_t;
l_dates hire_dates_t;
l_dates HR.hire_dates_t;
l_strings DBMS_SQL.varchar2_table;
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	18	
Collec>on	Methods	
• The	term	method	is	used	to	describe	procedures	and	funcDons	that	
defined	in	a	class	or	object	type.	
– You	invoke	a	method	by	aLaching	it,	using	dot	notaDon,	to	the	name	of	the	type/
class	or	to	an	instance	of	the	class.	
• CollecDon	methods	are	procedures	and	funcDons	that	are	a6ached	to	a	
collecDon	variable.	
– First	introducDon	of	object-oriented	syntax	in	PL/SQL	–	way	back	in	Oracle	7.3.4!	
	
method_vs_proc.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	19	
Methods	that	retrieve	informa>on	
• COUNT:	number	of	elements	currently	defined	in	collecDon.	
• EXISTS:	TRUE	if	the	specified	index	values	is	defined.	
• FIRST/LAST:	lowest/highest	index	values	of	defined	rows.	
• NEXT/PRIOR:	defined	index	value	ater/before	the	specified	index	value	.	
• LIMIT:	max.	number	of	elements	allowed	in	a	VARRAY.
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	20	
The	COUNT	Method	
• Returns	0	if	the	collecDon	is	empty.	
• Otherwise	returns	the	number	of	defined	index	values.	
• You	cannot	ask	for	a	count	of	elements	between	a	range	of	index	values.	
Too	bad...	
BEGIN
IF my_collection.COUNT > 0
THEN
/* We have some data in the collection */
...
END IF;
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	21	
Checking	for	element	existence	
• If	you	try	to	read	an	element	at	an	undefined	index	value,	Oracle	raises	
the	NO_DATA_FOUND	excepDon.	
– A	poor	decision	on	Oracle's	part.	
• Use	the	EXISTS	method	to	check	to	see	if	the	index	value	is	defined.	
BEGIN
IF my_collection.EXISTS (l_index)
THEN
DBMS_OUTPUT.PUT_LINE (my_collection (l_index));
END IF;
collection_exists.sql
plsqlloops.sp
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	22	
Naviga>ng	Through	Collec>ons	
• One	of	the	most	common	acDons	on	collecDons	is	looping	through	the	
contents.	
• You	can	use	WHILE,	simple	and	FOR	loops	to	perform	this	navigaDon.	
• The	characterisDcs	of	your	collecDon	will	determine	which	sort	of	loop	to	
use.
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	23	
Choose	the	Right	Loop	
• FOR	loop	
– Only	use	this	loop	when	you	want	to	iterate	through	every	element	between	the	low	
and	high	index	values.	
– Do	not	use	with	sparse	collecDons.	
• WHILE	and	simple	loops	
– Best	fit	for	sparse	collecDons	and	when	you	want	to	condi/onally	exit	from	your	loop.
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	24	
Naviga>on	methods	and	FOR	loops	
• With	FOR	loops,	you	will	use:	
– COUNT	–	when	the	first	index	value	in	the	collecDon	is	1.	
– FIRST	and	LAST	when	FIRST	may	not	be	one.	
BEGIN
FOR indx IN 1 .. my_collection.COUNT
LOOP
do_something_with (my_collection (indx));
END LOOP;
END;
BEGIN
FOR indx IN my_collection.FIRST .. my_collection.LAST
LOOP
do_something_with (my_collection (indx));
END LOOP;
END;
plsqlloops.sp
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	25	
Naviga>on	methods	&	WHILE/simple	loops	
• With	WHILE	and	simple	loops,	you	will	use	
– FIRST	and	NEXT	to	move	from	first	to	last	
– LAST	and	PRIOR	to	move	from	last	to	first	
rowind PLS_INTEGER := my_collection.FIRST;
BEGIN
LOOP
EXIT WHEN rowind IS NULL;
rowind := my_collection.NEXT (rowind);
END LOOP;
END;
rowind PLS_INTEGER := my_collection.LAST;
BEGIN
LOOP
EXIT WHEN rowind IS NULL;
rowind := my_collection.PRIOR (rowind);
END LOOP;
END;
plsqlloops.sp
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	26	
The	LIMIT	Method	
• Only	the	varray	has	a	pre-defined	upper	limit	on	the	number	of	elements	
that	can	defined	in	it.	
– Well,	the	other	collecDons	types	theore/cally	have	an	upper	limit,	but	you'll	never	
reach	it.	
• Use	the	LIMIT	method	to	determine	what	that	limit	is.	
DECLARE
TYPE max_of_five_t IS VARRAY (5) OF NUMBER;
l_list max_of_five_t := max_of_five_t();
BEGIN
DBMS_OUTPUT.put_line (l_list.LIMIT);
END;
varray_limit.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	27	
Methods	that	change	a	collec>on	
• DELETE	deletes	one	or	more	rows	from	an	associaDve	array	or	nested	
table.	
• EXTEND	adds	rows	to	the	end	of	a	nested	table	or	varray.	
• TRIM	removes	rows	from	a	varray	or	nested	table.
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	28	
The	DELETE	Method	
• You	can	delete	one	or	more	rows	from	an	associaDve	array	or	
nested	table	using	DELETE.	
• Try	to	DELETE	from	a	varray	and	you	will	see	"PLS-00306:	wrong	
number	or	types	of	arguments	in	call	to	'DELETE'"	
• Low	and	high	index	values	do	not	have	to	exist.	
BEGIN
-- Delete all rows
myCollection.DELETE;
-- Delete one (the last) row
myCollection.DELETE (myCollection.LAST);
-- Delete a range of rows
myCollection.DELETE (1400, 17255);
END;
delete.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	29	
Make	room	for	new	elements	w/	EXTEND	
• Use	EXTEND	only	with	varrays	and	nested	tables.	
• Tell	Oracle	to	add	N	number	of	new	elements	to	the	end	of	the	collecDon.	
• "Bulk"	extends	faster	than	individual	extends.	
– If	you	know	you	will	need	10,000	elements,	do	the	extend	in	a	single	step.	
• OpDonal:	specify	the	value	of	all	new	elements	from	an	exisDng	element.	
– Default	value	is	NULL.	
extend.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	30	
Trimming	elements	from	end	of	collec>on	
• Use	TRIM	only	with	varrays	and	nested	tables.	
– Not	to	be	confused	with	the	TRIM	funcDon!	
• You	can	trim	one	or	mulDple	elements.	
– Default	is	1.	
– "ORA-06533:	Subscript	beyond	count"	error	if	you	to	trim	more	than	is	in	the	
collecDon.	
• TRIM	is	the	only	way	to	remove	elements	from	a	varray.	
– DELETE	is	not	supported.	
trim.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	31	
Conclusions	–	Collec>on	Methods		
• Methods	make	it	much	easier	to	work	with	collecDons.	
• You	can	get	informaDon	about	the	collecDons	and	also	change	their	
contents.	
• When	you	use	the	navigaDon	methods,	make	sure	you	choose	the	
appropriate	type	of	loop	to	iterate	through	the	elements.
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	32	
Associa>ve	Arrays	
•  A	variable	declared	from	an	associaDve	array	type.	
•  An	unbounded	set	of	key-value	pairs.		
•  Each	key	is	unique,	and	serves	as	the	subscript	of	the	
element	that	holds	the	corresponding	value.		
•  You	can	access	elements	without	knowing	their	posiDons	
in	the	array,	and	without	traversing	the	array.	
1	 Apple	
22	 Pear	
100	 Orange	
10023	 Apricot	
DECLARE
TYPE list_of_names_t IS TABLE OF employees.last_name%TYPE
INDEX BY PLS_INTEGER;
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	33	
Associa>ve	Array	Background	
• It	was	the	first	type	of	collecDon	available	in	PL/SQL.	
• First	introduced	in	Oracle7	as	a	"PL/SQL	table"	(hence,	the	TABLE	OF	
syntax).	
• Renamed	in	Oracle8	to	"index-by	table"	when	nested	tables	and	varrays	
were	added.	
• In	9.2,	renamed	to	"associaDve	array"	with	the	advent	of	string	indexing.	
• Can	only	be	used	in	a	PL/SQL	context.
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	34	
Characteris>cs	of	Associa>ve	Arrays	
• TABLE	OF	datatypes	can	be	almost	any	valid	PL/SQL	type	(details	
to	follow).		
• INDEX	BY	type	can	be	integer	or	string.	
– This	means	you	can	essenDally	index	by	anything!	
– But	index	values	can	never	be	NULL.	
• AssociaDve	arrays	can	be	sparse.	
– Can	populate	elements	in	non-consecu/ve	index	values.	
– Easily	used	to	emulate	primary	keys	and	unique	indexes.	
DECLARE
TYPE list_of_names_t IS TABLE OF employees.last_name%TYPE
INDEX BY PLS_INTEGER;
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	35	
Simple	associa>ve	array	example	
DECLARE
TYPE list_of_names_t IS TABLE OF VARCHAR2 (20)
INDEX BY PLS_INTEGER;
happyfamily list_of_names_t;
l_index_value PLS_INTEGER := 88;
BEGIN
happyfamily (1) := 'Eli';
happyfamily (-15070) := 'Steven';
happyfamily (3) := 'Chris';
happyfamily (l_index_value) := 'Veva';
l_index_value := happyfamily.FIRST;
WHILE (l_index_value IS NOT NULL)
LOOP
DBMS_OUTPUT.put_line ( 'Value at index '
|| l_index_value
|| ' = '
|| happyfamily (l_index_value)
);
l_index_value := happyfamily.NEXT (l_index_value);
END LOOP;
END;
assoc_array_example.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	36	
Associa>ve	array	of	records	example	
• It	is	very	easy	to	"emulate"	a	relaDonal	table	inside	one's	PL/SQL	code.	
– Or	use	any	other	kind	of	record	type.	
DECLARE
TYPE employees_aat IS TABLE OF employees%ROWTYPE
INDEX BY PLS_INTEGER;
l_employees employees_aat;
BEGIN
FOR employee_rec IN (SELECT * FROM employees)
LOOP
l_employees (l_employees.COUNT + 1) := employee_rec;
END LOOP;
END;
collection_of_records.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	37	
Valid	TABLE	OF	datatypes	
• You	can	create	an	associaDve	array	of	almost	any	PL/SQL	or	SQL	datatype.	
– All	scalar	types,	including	Boolean	
– CollecDon	of	object	types	
– CollecDon	of	other	collecDons	
• There	are	some	restricDons:	
– Cannot	have	a	TABLE	OF	cursor	variables	or	excepDons.	
aa_table_of_invalid_types.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	38	
Valid	Index	Values	
• No	prac/cal	limit	to	number	of	elements	you	can	
define	in	an	associaDve	array.	
• Integer	index	values	range	from		
-2,147,483,647	to	2,147,483,647	
– This	is	the	BINARY_INTEGER	range.		
– That's	almost	4.3	billion	elements!	
• String	index	values	can	have	any	value;	you	are	only	restricted	by	
maximum	number	of	elements	allowed	in	a	collecDon.	
– Which	you	will	never	reach.	
aa_limits.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	39	
More	details	on	valid	INDEX	BY	types	
• The	INDEX	BY	clause	defines	the	indexing	for	the	collecDon.	
• You	can	define	the	index	datatype	of	your	associaDve	
array	type	to	be:	
– BINARY_INTEGER	and	any	sub-type	derived	from	
BINARY_INTEGER	
– VARCHAR2(n),	where	n	is	between	1	and	32767	
– %TYPE	against	a	database	column	that	is	consistent	with	the	
above	rules	
– A	SUBTYPE	against	any	of	the	above.	
indexby_options.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	40	
Nested	Tables	and	Varrays	
• Added	in	Oracle8	as	part	of	the	object	model.	
• Types	can	be	defined	in	PL/SQL	or	a	schema-level	type.	
• You	must	ini/alize	before	using	the	collecDon.	
– There	are	some	excepDons,	as	with	BULK	COLLECT.	
• You	must	extend	to	make	room	for	new	elements.	
– There	are	some	excepDons,	as	with	BULK	COLLECT.	
• Columns	in	relaDonal	tables	can	be	of	type	nested	table	or	varray.	
– Oh,	but	the	denormalizaDon!
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	41	
Nested	Tables	
•  A	nested	table	is	a	type	of	collecDon,	which,	according	
to	Oracle	documentaDon,	"models	an	unordered	set	of	
elements."	
– It	is	a	"mulDset":	like	a	relaDonal	table,	there	is	no	inherent	
order	to	its	elements,	and	duplicates	are	allowed/
significant.	
•  From	a	pracDcal	standpoint,	you	can	access	nested	
table	elements	through	an	integer	index.	
•  MULTISET	operators	allow	set-level	operaDons	on	
nested	tables.	
1	 Apple	
2	 Pear	
3	 Orange	
4	 Apricot	
CREATE OR REPLACE TYPE list_of_names_t IS TABLE OF NUMBER;
5	 Pear	
Unordered set
of elements
Integer index
also available
nested_table_example.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	42	
Varrays	
• A	varray	(short	for	"variable	size	array)	is	a	
type	of	collecDon	that	has	an	upper	bound	on	
its	number	of	elements.		
• This	upper	limit	is	set	when	the	type	is	
defined,	but	can	also	be	adjusted	at	runDme.	
• Always	dense,	can	only	trim	from	end	of	
varray.	
• Other	than	that,	quite	similar	to	a	nested	
table.	
1	 Apple	
2	 Pear	
3	 Orange	
4	 Apricot	
CREATE OR REPLACE TYPE list_of_names_t IS VARRAY (5) OF NUMBER;
5	 Pear	
And no more
elements can fit in
this varray.
varray_example.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	43	
Ini>alizing	Nested	Tables	and	Varrays	
• Before	you	can	use	a	nested	table,	it	must	be	iniDalized.	
– IniDalize	them	explicitly	with	a	constructor	funcDon,	same	name	as	type,	
provided	by	Oracle	
– Provide	a	list	of	values	or	iniDalize	it	as	empty.	
DECLARE
TYPE numbers_t IS VARRAY (5) OF NUMBER;
salaries numbers_t := numbers_t (100, 200, 300);
BEGIN
DECLARE
TYPE numbers_t IS TABLE OF NUMBER;
salaries numbers_t;
BEGIN
salaries := numbers_t (100, 200, 300);
Initialize in
execution
section
Initialize in
declaration with
values
DECLARE
TYPE numbers_t IS TABLE OF NUMBER;
salaries numbers_t := numbers_t ();
Initialize empty
in declaration
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	44	
Valid	TABLE	OF	and	VARRAY	datatypes	
• For	PL/SQL-defined	types,	you	can	create	nested	table	of	almost	any	PL/
SQL	or	SQL	datatype.	
– All	scalar	types,	including	Boolean;	collecDon	of	object	types;	collecDon	of	other	
collecDons	
• There	are	some	restricDons:	
– Cannot	have	a	TABLE	OF	or	VARRAY	OF	cursor	variables	or	excepDons.	
• Schema-level	types	can	only	use	SQL	datatypes.	
nt_table_of_invalid_types.sql
va_table_of_invalid_types.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	45	
Collec>on	as	Column	Type	
• If	the	type	is	defined	at	schema	level,	it	can	be	used	as	a	column	type.	
– Must	also	provide	a	STORE	AS	clause.	
• The	order	of	elements	in	the	column	is	not	preserved.	
• Can	specify	storage	characterisDcs	of	collecDon.	
• See	separate	lesson	for	details	on	using	collecDons	in	SQL.	
CREATE TABLE family
(
surname VARCHAR2 (1000)
, parent_names parent_names_t
, children_names child_names_t
)
NESTED TABLE children_names
STORE AS parent_names_tbl [storage_clause]
NESTED TABLE parent_names
STORE AS children_names_tbl [storage_clause]
nested_table_example.sql
varray_example.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	46	
Changing	Upper	Limit	on	Varray	
• You	specify	an	upper	limit	at	the	Dme	the	varray	type	is	define.	
• You	can	also	change	this	limit	at	runDme	with	an	ALTER	TYPE	command.	
ALTER TYPE my_varray_t MODIFY LIMIT 100 INVALIDATE
/
BEGIN
EXECUTE IMMEDIATE
'ALTER TYPE my_varray_t MODIFY LIMIT 100 CASCADE';
END;
/
varray_change_limit.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	47	
Using	Collec>ons	Inside	SQL	
• Define	your	collecDon	type	at	the	schema	level	&	collecDons	
declared	with	that	type	can	be	referenced	in	the	SQL	layer.	
– As	a	column	in	a	relaDonal	table	
– By	selecDng	from	that	collecDon	in	a	SELECT	statement	(note:	as	of	12.1,	
you	can	do	this	with	associaDve	arrays	indexed	by	integer).	
• Oracle	offers	ways	to	"translate"	between	a	collecDon	format	
and	a	relaDonal	table	format.	
– TABLE:	collecDon	->	relaDonal	table	
– MULTISET:	relaDonal	table	->	collecDon
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	48	
Using	the	TABLE	Operator	
• Use	TABLE	to	work	with	data	in	a	collecDon	as	if	it	were	data	
in	a	database	table.	
– Oracle	refers	to	this	as	"un-nesDng".	
– Especially	useful	when	you	would	like	to	apply	SQL	operaDons	to	a	PL/
SQL	collecDon	(ie,	one	not	stored	in	a	database	table).	
• You	do	not	need	to	explicitly	CAST	the	collecDon.	
– Oracle	will	figure	out	the	type	automaDcally.	
collections_in_sql.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	49	
Changing	collec>on	contents	with	TABLE	
• You	can	use	TABLE	to	query	the	contents	of	a	collecDon	inside	
SQL.	
• You	can	also	change	the	contents	of	a	nested	table	column	value	
with	TABLE.	
– But	varrays	have	to	be	changed	"en	masse"	–	the	while	varray	is	replace;	
cannot	modify	individual	elements.	
UPDATE TABLE (SELECT children_names
FROM family
WHERE surname = 'Feuerstein')
SET COLUMN_VALUE = 'Eli Silva'
WHERE COLUMN_VALUE = 'Eli'
/
nested_table_change.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	50	
Using	the	MULTISET	Operator	
• MULTISET	is	the	inverse	of	TABLE,	converDng	a	set	of	table,	view,	
query)	into	a	VARRAY	or	nested	table.	
– Use	MULTISET	to	emulate	or	transform	relaDonal	joins	into	collecDons,	with	
potenDal	client-server	performance	impact.	
DECLARE
CURSOR bird_curs IS
SELECT b.genus, b.species,
CAST ( MULTISET (SELECT bh.country FROM bird_habitats bh
WHERE bh.genus = b.genus
AND bh.species = b.species)
AS country_tab_t)
FROM birds b;
bird_row bird_curs%ROWTYPE;
BEGIN
OPEN bird_curs;
FETCH bird_curs into bird_row;
END;
collections_in_sql_multiset.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	51	
Non-Sequen>al	Indexing	
• SomeDmes	you	simply	want	to	add	items	to	the	end	of	a	list.	
– This	makes	sense	if	the	order	in	which	items	were	added	is	significant.	
• But	how	do	you	find	a	specific	element	in	the	list?	
– With	sequenDal	indexing,	you	have	to	scan	through	the	contents	to	find	a	match.	
• And	what	if	you	want	to	find	elements	in	a	collecDon	using	more	than	one	
"index"?	
– CollecDons	have	just	one	index.	Period.	
string_tracker0.*
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	52	
Taking	advantage	of	non-sequen>al	indexing	
• AssociaDve	arrays	can	be	sparse.	
– Certainly,	any	string-indexed	collecDon	is	not	sequenDally	filled.		
• Valid	index	values	for	an	associaDve	array	cover	a	very	wide	range	of	
integers.	
– Very	oten	primary	keys	of	tables	are	sequence-generated	integers	that	fall	within	
this	range.	
• Combine	these	two	features	and	you	have	a	powerful	and	relaDvely	simple	
mechanism	for	emulaDng	relaDonal	table	keys.	
collection_of_records.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	53	
Emula>ng	Primary	Key	in	Collec>on	
• Many	tables	rely	on	sequence-generated	integer	values	for	their	primary	
keys.	
– It	is	possible	that	this	sequence	value	could	exceed	2**31-1,	but	it	is	rarely	the	case.	
• Primary	keys	generally	are	not	"densely"	allocated.		
– Sequences	are	allocated	in	groups,	rows	are	deleted.	
• These	scenarios	mesh	perfectly	with	the	features	of	an	integer-indexed	
associaDve	array.	
emulate_primary_key1.sql
emulate_primary_key2.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	54	
"Mul>ple	Indexes"	on	a	Collec>on	
• Most	relaDonal	tables	have	mulDple	indexes	defined	in	order	to	opDmize	
query	performance	(for	various	WHERE	clauses).	
• What	if	I	need	to	do	the	same	thing	in	a	collecDon?	
• You	can	only	have	a	single	index	on	an	associaDve	array	(INDEX	BY...).	
– But	you	could	create	other	collecDons	that	serve	as	indexes	into	the	"original"	
collecDon.	
emulate_indexes.sql
genaa.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	55	
Lots	of	ways	to	index	associa>ve	arrays	
• Prior	to	Oracle9i	Release	2,	you	could	only	index	by	
BINARY_INTEGER.	
• You	can	now	define	the	index	on	your	associaDve	array	to	be:	
– Any	sub-type	derived	from	BINARY_INTEGER	
– VARCHAR2(n),	where	n	is	between	1	and	32767	
– %TYPE	against	a	database	column	that	is	consistent	with	the	above	rules	
– A	SUBTYPE	against	any	of	the	above.	
• This	means	that	you	can	now	index	on	string	values!	(and	
concatenated	indexes	and...)
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	56	
Examples	of	New	TYPE	Variants	
• All	of	the	following	are	valid	TYPE	declaraDons	in	Oracle9i	Release	
2	and	higher	
– You	cannot	use	%TYPE	against	an	INTEGER	column,	because	INTEGER	is	not	a	
subtype	of	BINARY_INTEGER.	
DECLARE
TYPE array_t1 IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
TYPE array_t2 IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
TYPE array_t3 IS TABLE OF NUMBER INDEX BY POSITIVE;
TYPE array_t4 IS TABLE OF NUMBER INDEX BY NATURAL;
TYPE array_t5 IS TABLE OF NUMBER INDEX BY VARCHAR2(64);
TYPE array_t6 IS TABLE OF NUMBER INDEX BY VARCHAR2(32767);
TYPE array_t7 IS TABLE OF NUMBER INDEX BY
employee.last_name%TYPE;
TYPE array_t8 IS TABLE OF NUMBER INDEX BY
types_pkg.subtype_t;
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	57	
Working	with	string-indexed	collec>ons	
• The	syntax	for	using	string	indexing	is	the	same.		
– And	all	the	same	methods	are	available.	
• But	the	type	of	data	returned	by	FIRST,	LAST,	NEXT	and	PRIOR	
methods	is	VARCHAR2.	
• The	longer	the	string	values,	the	more	Dme	it	takes	Oracle	to	
"hash"	or	convert	that	string	to	the	integer	that	is	actually	used	
as	the	index	value.	
– RelaDvely	small	strings,	say	under	100	characters,	do	not	incur	too	large	a	
penalty.	
assoc_array*.sql
assoc_array_perf.tst
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	58	
An	example	of	string	indexing	
• I	generate	test	code	and	declare	variables.	So	I	need	to	make	sure	that	I	do	not	
declare	the	same	variable	more	than	once.	
•  There	are	lots	of	ways	to	do	this,	but	string-indexed	collecDons	make	it	really	
easy!	
FOR indx IN 1 .. l_variables.COUNT
LOOP
If varname_already_used THEN
-- DO NOTHING
ELSE
add_variable_declaration;
mark_varname_as_used;
END IF;
END LOOP;
string_tracker0.*
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	59	
String	Tracker	without	string	indexing	
• Two	subprograms	are	needed....	
– string_in_use:	returns	TRUE	if	the	string	was	previously	used.	
– mark_as_used:	mark	the	specified	string	as	being	used.	
• Most	"obvious"	implementaDon:	add	each	string	to	a	list	of	used	strings.	
• Then	search	through	the	list	for	a	match.	
string_tracker0.*
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	60	
String	Tracker	with	string	indexing	
• Rather	than	add	each	string	to	a	list	of	used	strings,	why	not	use	the	string	
as	the	index?	
CREATE OR REPLACE PACKAGE BODY string_tracker
IS
TYPE used_aat IS TABLE OF BOOLEAN INDEX BY VARCHAR2(32767);
g_names_used used_aat;
FUNCTION string_in_use ( value_in IN VARCHAR2 )
RETURN BOOLEAN
IS BEGIN
RETURN g_names_used.EXISTS ( value_in );
END string_in_use;
PROCEDURE mark_as_used (value_in IN VARCHAR2) IS
BEGIN
g_names_used ( value_in ) := TRUE;
END mark_as_used;
END string_tracker;
string_tracker1.*
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	61	
Conver>ng	from	Integer	to	String	Indexing	
• Suppose	I	am	emulaDng	my	primary	key	in	a	collecDon	index	for	a	batch	
job.	
– Much	beLer	performance!		
– But	my	primary	key	values	are	approaching		
2**31-1	(the	maximum	allowed	in	an	collecDon).	
• Must	I	abandon	the	collecDon	technique?	
• No!	You	can	convert	to	a	string	index.	
– Now	the	only	limitaDon	is	the	number	of	elements	defined	in	the	collecDon.	
– You	are	much	more	likely	to	run	out	of	memory	before	you	get	anywhere	near	
2**31-1	elements.		
emulate_primary_key.sql
int_to_string_indexing.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	62	
Mul>level	(a.k.a.,	Nested)	Collec>ons	
• A	mulDlevel	collecDon	type	is	a	type	whose	element	is,	directly	or	
indirectly,	another	collecDon.	
• Usages	for	mulDlevel	collecDons:	
– Model	normalized	data	structures	in	PL/SQL	collecDons	
– Emulate	mulDdimensional	arrays.	
• The	syntax	for	working	with	mulDlevel	collecDons	can	be	hard	to	parse	(in	
your	head).	
multilevel_collections.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	63	
String	Tracker	Version	2	
• I	introduced	the	string_tracker	package	in	"Working	with	String-Indexed	
CollecDons."	
– Keeps	track	of	the	names	of	variables	already	generated	in	test	code.	
– That	worked	fine	for	a	single	list.	What	if	I	need	to	keep	track	of	mulDple	lists,	and	
lists	within	lists?	
• Let's	extend	the	first	version	to	support	mulDple	lists	by	using	a	string-
indexed,	mulD-level	collecDon.	A	list	of	lists....	
string_tracker1.*
string_tracker2.*
string_tracker3*.*
List	1:	1-10000	 List	2:	10001-20000	 List	2:	20001-30000	
The	hard	way:	segmenDng	one	big	collecDon
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	64	
Emulate	mul>dimensional	arrays	
• CollecDons	are	always	single	dimensioned.	
• But	a	collecDon	of	collecDons	is	"kinda	like"	a	two-dimensional	array.	
– You	can	extrapolate	from	there.	
CREATE OR REPLACE PACKAGE multdim
IS
TYPE dim1_t IS TABLE OF VARCHAR2 (32767)
INDEX BY PLS_INTEGER;
TYPE dim2_t IS TABLE OF dim1_t
INDEX BY PLS_INTEGER;
TYPE dim3_t IS TABLE OF dim2_t
INDEX BY PLS_INTEGER;
multdim*.*
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	65	
Complex	example:	four-levels	of	nes>ng	
• The	most	complicated	structure	I	ever	built	was	a	four-level	nested	
collecDon	structure.	
• I	used	it	to	build	a	uDlity	to	analyze	packages	for	potenDally	ambiguous	
overloading.	
• The	next	several	slides	explore	the	implementaDon.	
– It	is	too	complex	to	fully	explain	in	this	lesson.
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	66	
Mul>level	collec>ons	as	a	kind	of	
normalized	database	design	
• I	have	found	that	coming	up	with	the	right	model	of	mulDlevel	collecDons	
is	very	similar	to	normalizing	data	in	relaDonal	tables.	
– Avoid	redundancy	
– Accurately	reflect	relaDonships	
– Simply	resulDng	applicaDon	code	
• Let's	take	a	look	at	an	example	of	such	a	process.
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	67	
The	problem	of	ambiguous	overloading	
• Oddly	and	sadly,	it	is	possible	to	compile	overloadings	which	
are	not	usable.	
– You	see	an	obvious	example	below,	but	there	are	many	more	subtle	
circumstances,	usually	involving	defaulted	parameters.	
• So	I	will	build	a	uDlity	to	idenDfy	such	ambiguous	overloadings.	
But	how	can	I	do	this?	
BEGIN
salespkg.calc_total ('ABC');
END;
PACKAGE salespkg
IS
PROCEDURE calc_total (
dept_in IN VARCHAR2);
PROCEDURE calc_total (
dept_in IN CHAR);
END salespkg;
?
ambig_overloading.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	68	
ALL_ARGUMENTS	to	the	rescue!	
• Parsing	is	too	complicated	for	me,	but	the	ALL_ARGUMENTS	
data	dicDonary	view	contains	informaDon	about	all	the	
arguments	of	all	the	procedures	and	funcDons	to	which	I	have	
access.		
– That	sounds	preLy	good!	
• As	usual,	Oracle	offers	us	a	whole	lot	of	pleasure,	mixed	with	a	
liLle	bit	of	pain.	
– The	organizaDon	of	data	in	ALL_ARGUMENTS	is	a	bit	bizarre,	plus	it	is	
incomplete,	necessitaDng	the	use	also	of	
DBMS_DESCRIBE.DESCRIBE_COLUMNS.	 all_arguments.tst
all_arguments.sql
allargs.*
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	69	
First	Inclina>on:	Same	Old,	Same	Old	
• All	right	then,	I	will	grab	all	the	informaDon	from	
ALL_ARGUMENTS	and	dump	it	into	a	collecDon	based	on	that	
view!	Very	easy...	
CREATE OR REPLACE PROCEDURE get_all_arguments (
package_in IN VARCHAR2)
IS
TYPE all_arguments_tt IS TABLE OF all_arguments%ROWTYPE
INDEX BY BINARY_INTEGER;
l_arguments all_arguments_tt;
BEGIN
FOR rec IN (
SELECT * FROM all_arguments
WHERE owner = USER AND package_name = package_in)
LOOP
l_arguments (SQL%ROWCOUNT) := rec;
END LOOP;
END;
Load it up!
Emulate the
view.
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	70	
Then	what?	Write	lots	of	code	to	interpret	
the	contents...	
• Which	programs	are	overloaded?	Where	does	one	overloading	end	and	
another	start?	
l_last_program all_arguments.object_name%TYPE;
l_is_new_program BOOLEAN := FALSE;
l_last_overload PLS_INTEGER := -1;
BEGIN
FOR indx IN l_arguments.FIRST ..
l_arguments.LAST
LOOP
IF l_arguments (indx).object_name !=
l_last_program
OR l_last_program IS NULL
THEN
l_last_program :=
l_arguments (indx).object_name;
l_is_new_program := TRUE;
do_new_program_stuff;
END IF;
...
IF l_arguments (indx).overload
!= l_last_overload
OR l_last_overload = -1
THEN
IF l_is_new_program
THEN
do_first_overloading_stuff;
ELSE
do_new_overloading_stuff;
END IF;
END IF;
END LOOP;
END;
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	71	
Discovery:	there	is	a	hierarchy	within	the	
ALL_ARGUMENTS	data!		
•  Each	program	has	zero	or	more	
overloadings,	each	overloading	has	
N	arguments,	and	each	argument	
can	have	mulDple	"breakouts"	(my	
term	-	applies	to	non-scalar	
parameters,	such	as	records	or	
object	types).	
RUN_TEST
SHOW_RESULTS
RESET_FLAGS
Program name
Overloading 1
Overloading 2
Overloading
Argument 1
Argument 2
Argument 3
Argument 4
Argument 5
Argument Breakout 1
Breakout 1
Breakout 2
Breakout 3
Breakout
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	72	
What	if	I	reflect	this	hierarchy	in		
a	mul>level	collec>on?	
• Have	to	build	from	the	boLom	up:	
TYPE breakouts_t IS TABLE OF all_arguments%ROWTYPE
INDEX BY PLS_INTEGER;
TYPE arguments_t IS TABLE OF breakouts_t
INDEX BY PLS_INTEGER;
TYPE overloadings_t IS TABLE OF arguments_t
INDEX BY PLS_INTEGER;
TYPE programs_t IS TABLE OF overloadings_t
INDEX BY all_arguments.object_name%type;
1. Set of rows from
ALL_ARGUMENTS
String-based index
2. All the "breakout" info
for a single argument
3. All the argument info
for a single overloading
4. All the overloadings for
a distinct program name
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	73	
Then	I	can	populate	it	very	easily	
• Assigning	a	single	record	to	the	"lowest"	level	also	defines	each	of	
the	upper	levels.	
• NoDce	the	automaDc	"SELECT	DISTINCT"	on	name	that	results!	
FOR rec IN (SELECT * FROM all_arguments)
LOOP
l_arguments (NVL (l_arguments.LAST, 0) + 1)
:= rec;
 
l_programs
(rec.object_name)
(NVL (rec.overload, 0))
(rec.position)
(rec.data_level) := rec;
END LOOP;
I can still do the
typical sequential
load.
But I will now also
add the multi-level
load in single
assignment
show_all_arguments.sp
show_all_arguments.tst
cc_smartargs.pkb/load_arguments
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	74	
And	then	I	can	"query"	the	contents	
with	a	minimum	of	code	
l_programs ('TOP_SALES') (2).EXISTS (0)
Is the TOP_SALES
program overloaded?
l_programs ('TOP_SALES') (2)(0)(0).datatype
l_programs ('TOP_SALES').COUNT > 1
Is the 2nd overloading
of TOP_SALES a
function?
What is the datatype
of the RETURN
clause of the 2nd
overloading of
TOP_SALES? And, of course, I know the beginning and end points of
each program, overloading, and argument. I just use the
FIRST and LAST methods on those collections!
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	75	
Conclusions	–	Nested	Collec>ons	
• The	nested	collecDon	is	a	powerful,	but	potenDally	very	
complicated,	feature	of	PL/SQL.	
• Used	correctly,	it	can	hide	complexity	in	the	underlying	data	
structure,	and	greatly	simplify	your	algorithms.	
• If	you	find	yourself	saying	"It	shouldn't	be	this	hard,"	take	a	look	
at	how	you	are	using	your	collecDons	(or	SQL).		
– Perhaps	mulDlevel	collecDons	can	come	to	the	rescue!
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	76	
Manipula>ng	Nested	Tables	as	Mul>sets	
• Nested	tables	are,	from	a	theoreDcal	standpoint,	"mulDsets."	
– There	is	no	inherent	order	to	the	elements.	
– Duplicates	are	allowed	and	are	significant.	
– RelaDonal	tables	are	mulDsets	as	well.	
• If	a	set	has	no	order,	then	it	has	no	index,	so	it	must	be	manipulated	as	a	
set.	
• In	Oracle	Database	10g,	Oracle	added	MULTISET	set	operators	to	
manipulate	the	contents	of	nested	tables	(only).	
– Use	in	both	PL/SQL	blocks	and	SQL	statements.
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	77	
Set-Oriented	Features	for	Nested	Tables	
• Determine	if...	
– two	nested	tables	are	equal/unequal		
– a	nested	table	has	duplicates,	and	remove	duplicates	
– one	nested	table	contains	another	
– an	element	is	a	member	of	a	nested	table	
• Perform	set	operaDons.	
– Join	contents	of	two	nested	tables:	MULTISET	UNION.	
– Return	common	elements	of	two	nested	tables	with	MULTISET	INTERSECT.	
– Take	away	the	elements	of	one	nested	table	from	another	with	MULTISET	EXCEPT	
(oddly,	not	MINUS).
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	78	
Check	for	equality	and	inequality	
• You	can	use	=	and	<>	to	compare	the	contents	of	two	nested	
tables.	
– But	watch	out!	NULLs	have	the	usual	disrupDve	impact.	
• This	is	an	enormous	advantage	over	wriDng	a	program	to	compare	
the	contents	of	two	collecDons.	
DECLARE
TYPE clientele IS TABLE OF VARCHAR2 (64);
group1 clientele := clientele ('Customer 1', 'Customer 2');
group2 clientele := clientele ('Customer 1', 'Customer 3');
group3 clientele := clientele ('Customer 3', 'Customer 1');
BEGIN
IF group1 = group2 THEN
DBMS_OUTPUT.put_line ('Group 1 = Group 2');
ELSE
DBMS_OUTPUT.put_line ('Group 1 != Group 2');
END IF;
END;
10g_compare.sql
10g_compare_nulls.sql
10g_compare_old.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	79	Copyright	2000-2008			Steven	Feuerstein	-	Page	79	
Nested	table	duplicates	–	detec>on	and	removal	
• Use	the	SET	operator	to	work	with	disDnct	values,	and	determine	
if	you	have	a	set	of	disDnct	values.	
DECLARE
keep_it_simple strings_nt := strings_nt ();
BEGIN
keep_it_simple := SET (favorites_pkg.my_favorites);
favorites_pkg.show_favorites ('FULL SET', favorites_pkg.my_favorites);
p.l (favorites_pkg.my_favorites IS A SET, 'My favorites distinct?');
p.l (favorites_pkg.my_favorites IS NOT A SET,
'My favorites NOT distinct?');
favorites_pkg.show_favorites (
'DISTINCT SET', keep_it_simple);
p.l (keep_it_simple IS A SET, 'Keep_it_simple distinct?');
p.l (keep_it_simple IS NOT A SET, 'Keep_it_simple NOT distinct?');
END;
authors.pkg
10g_set.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	80	
Determine	if	value	is	in	nested	table	
• Use	the	MEMBER	OF	syntax	to	determine	if	a	value	is	in	the	
nested	table.	
– Much	simpler	than	scanning	the	contents	of	a	collecDon.	
– Performs	an	equality	check	for	the	enDre	element;	you	cannot	compare	
individual	fields	of	records,	and	so	on.	
• The	implementaDon	in	SQL	itself	is	quite	slow.	
• Performance	in	PL/SQL	is	fast.	
in_clause.*
10g_member_of.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	81	
Does	one	nested	table	contains	another?	
• The	SUBMULTISET	OF	operator	determines	if	all	the	elements	of	one	
nested	table	are	in	another.	
DECLARE
TYPE nested_typ IS TABLE OF NUMBER;
nt1 nested_typ := nested_typ (1, 2);
nt2 nested_typ := nested_typ (3, 2, 1);
BEGIN
IF nt1 SUBMULTISET OF nt2
THEN
...
END IF;
END;
authors.pkg
10g_submultiset.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	82	
UNION	two	nested	tables	together	
• Use	UNION	to	join	together	the	contents	of	two	nested	tables.	
• Duplicates	are	preserved	unless	you	include	the	DISTINCT	
modifier.	
– This	is	the	opposite	of	SQL	UNION	and	UNION	ALL.	
• The	resulDng	collecDon	is	either	empty	or	sequenDally	filled	from	
index	value	1.	
– You	do	not	need	to	iniDalize	or	extend	first.	
authors.pkg
10g_union.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	83	
Intersect	two	nested	tables	together	
• Use	INTERSECT	to	find	the	common	elements	of	two	nested	tables.	
• Duplicates	are	preserved	unless	you	include	the	DISTINCT	modifier.	
– And	the	ALL	modifier	is	the	default.	
• The	resulDng	collecDon	is	either	empty	or	sequenDally	filled	from	index	
value	1.	
– You	do	not	need	to	iniDalize	or	extend	first.	
10g_intersect.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	84	
Take	away	the	elements	of	one	nested	table	
from	another	
• Use	EXCEPT	(not	MINUS!)	to	take	all	elements	in	one	nested	table	out	of	
another.	
• Duplicates	are	preserved	unless	you	include	the	DISTINCT	modifier.	
– And	the	ALL	modifier	is	the	default.	
• The	resulDng	collecDon	is	either	empty	or	sequenDally	filled	from	index	
value	1.	
– You	do	not	need	to	iniDalize	or	extend	first.	
10g_except.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	85	
Conclusions	–	MULTISET	operators		
• When	you	need	to	manipulate	the	contents	of	a	collecDon	as	a	
set,	use	a	nested	table.	
• The	MULTISET	operators	offer	a	powerful,	simple	way	to	avoid	
wriDng	lots	of	code.	
• The	SET,	SUBMULTISET	and	MEMBER	operators	also	can	come	in	
very	handy.	
• Watch	out	for	results	when	your	nested	table	may	contain	NULL	
elements.
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	86	
Collec>on	Best	Prac>ces	
• Watch	the	PGA	memory.	
• Hide	the	implementaDon	details.	
• Use	subtypes	to	self-document	element	and	index	by	types.	
• Choosing	the	best	type	of	collecDon
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	87	
Watch	PGA	memory	consump>on	
• Memory	for	collecDons	is	allocated	from	the	PGA	(Process	Global	
Area).	
– There	is	a	PGA	for	each	session	connected	to	the	instance.	
• Large	collecDons	constructed	by	programs	run	by	many	
simultaneously-connected	users	can	cause	memory	errors.	
• Use	the	plsq_memory	package	to	analyze	the	amount	of	memory	
used.	
– Or	at	least	make	sure	your	DBA	knows	you	are	making	extensive	use	of	
collecDons.	
plsql_memory*.*
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	88	
Hide	the	implementa>on	details.	
• CollecDons,	especially	mulD-level	collecDons,	are	very	complex	
structures.	
• Hide	the	way	you	to	set	and	get	elements	in	a	collecDon	behind	
an	API.	
– Procedure	to	set,	funcDon	to	get.	
– When	you	have	change	the	implement,	you	change	in	one	place	(single	point	
of	definiDon).	
multdim.sql
cc_smartargs.sql
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	89	
Use	subtypes	to	self-document	datatypes	
• You	should	avoid	using	base	datatypes	in	both	the	TABLE	OF	and	INDEX	BY	
clauses.	
– Especially	when	working	with	string-indexed	associaDve	arrays.	
• Use	SUBTYPEs	to	provide	applicaDon-specific	names	that	self-document	
both	contents	and	intenDon.	
– Constants	can	also	come	in	handy.	
string_tracker3.*
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	90	
Choosing	the	best	type	of	collec>on	
• Use	associaDve	arrays	when	you	need	to...	
– Work	within	PL/SQL	code	only	
– Sparsely	fill	and	manipulate	the	collecDon	
– Take	advantage	of	negaDve	index	values	or	string	indexing	
• Use	nested	tables	when	you	need	to...	
– Access	the	collecDon	inside	SQL	
– Want	or	need	to	perform	high	level	set	operaDons	(MULTISET)	
• Use	varrays	when	you	need	to...	
– If	you	need	to	specify	a	maximum	size	to	your	collecDon	
– OpDmize	performance	of	storing	collecDon	as	column
Copyright	©	2015	Oracle	and/or	its	affiliates.	All	rights	reserved.		|	 Page	91	
Collec>ons:	Don't	start	coding	without	them.	
• It	is	impossible	to	write	efficient,	high	quality	PL/SQL	code,	
taking	full	advantage	of	new	features,	unless	you	use	collecDons.	
– From	array	processing	to	table	funcDons,	collecDons	are	required.	
• Learn	collecDons	thoroughly	and	apply	them	throughout	your	
backend	code.	
– Your	code	will	get	faster	and	in	many	cases	much	simpler	than	it	might	have	
been	(though	not	always!).
92

Contenu connexe

Tendances

pl/sql Procedure
pl/sql Procedurepl/sql Procedure
pl/sql ProcedurePooja Dixit
 
05 Creating Stored Procedures
05 Creating Stored Procedures05 Creating Stored Procedures
05 Creating Stored Proceduresrehaniltifat
 
09 Managing Dependencies
09 Managing Dependencies09 Managing Dependencies
09 Managing Dependenciesrehaniltifat
 
pl/sql online Training|sql online Training | iTeknowledge
pl/sql online Training|sql online Training | iTeknowledgepl/sql online Training|sql online Training | iTeknowledge
pl/sql online Training|sql online Training | iTeknowledgeMasood Khan
 
PL/SQL Introduction and Concepts
PL/SQL Introduction and Concepts PL/SQL Introduction and Concepts
PL/SQL Introduction and Concepts Bharat Kalia
 
PL/SQL Fundamentals I
PL/SQL Fundamentals IPL/SQL Fundamentals I
PL/SQL Fundamentals INick Buytaert
 
Aggregate functions
Aggregate functionsAggregate functions
Aggregate functionssinhacp
 
Oracle pl/sql control statments
Oracle pl/sql control statmentsOracle pl/sql control statments
Oracle pl/sql control statmentsTayba Bashir
 
PL/SQL - CURSORS
PL/SQL - CURSORSPL/SQL - CURSORS
PL/SQL - CURSORSIshaRana14
 
Oracle sql high performance tuning
Oracle sql high performance tuningOracle sql high performance tuning
Oracle sql high performance tuningGuy Harrison
 
The Amazing and Elegant PL/SQL Function Result Cache
The Amazing and Elegant PL/SQL Function Result CacheThe Amazing and Elegant PL/SQL Function Result Cache
The Amazing and Elegant PL/SQL Function Result CacheSteven Feuerstein
 
Turbocharge SQL Performance in PL/SQL with Bulk Processing
Turbocharge SQL Performance in PL/SQL with Bulk ProcessingTurbocharge SQL Performance in PL/SQL with Bulk Processing
Turbocharge SQL Performance in PL/SQL with Bulk ProcessingSteven Feuerstein
 
Python SQite3 database Tutorial | SQlite Database
Python SQite3 database Tutorial | SQlite DatabasePython SQite3 database Tutorial | SQlite Database
Python SQite3 database Tutorial | SQlite DatabaseElangovanTechNotesET
 
Advanced PLSQL Optimizing for Better Performance
Advanced PLSQL Optimizing for Better PerformanceAdvanced PLSQL Optimizing for Better Performance
Advanced PLSQL Optimizing for Better PerformanceZohar Elkayam
 
Aggregating Data Using Group Functions
Aggregating Data Using Group FunctionsAggregating Data Using Group Functions
Aggregating Data Using Group FunctionsSalman Memon
 

Tendances (20)

pl/sql Procedure
pl/sql Procedurepl/sql Procedure
pl/sql Procedure
 
05 Creating Stored Procedures
05 Creating Stored Procedures05 Creating Stored Procedures
05 Creating Stored Procedures
 
09 Managing Dependencies
09 Managing Dependencies09 Managing Dependencies
09 Managing Dependencies
 
SQL JOINS
SQL JOINSSQL JOINS
SQL JOINS
 
pl/sql online Training|sql online Training | iTeknowledge
pl/sql online Training|sql online Training | iTeknowledgepl/sql online Training|sql online Training | iTeknowledge
pl/sql online Training|sql online Training | iTeknowledge
 
Packages - PL/SQL
Packages - PL/SQLPackages - PL/SQL
Packages - PL/SQL
 
PL/SQL Introduction and Concepts
PL/SQL Introduction and Concepts PL/SQL Introduction and Concepts
PL/SQL Introduction and Concepts
 
PL/SQL Fundamentals I
PL/SQL Fundamentals IPL/SQL Fundamentals I
PL/SQL Fundamentals I
 
Aggregate functions
Aggregate functionsAggregate functions
Aggregate functions
 
Oracle pl/sql control statments
Oracle pl/sql control statmentsOracle pl/sql control statments
Oracle pl/sql control statments
 
PL/SQL - CURSORS
PL/SQL - CURSORSPL/SQL - CURSORS
PL/SQL - CURSORS
 
Oracle sql high performance tuning
Oracle sql high performance tuningOracle sql high performance tuning
Oracle sql high performance tuning
 
Joins in SQL
Joins in SQLJoins in SQL
Joins in SQL
 
The Amazing and Elegant PL/SQL Function Result Cache
The Amazing and Elegant PL/SQL Function Result CacheThe Amazing and Elegant PL/SQL Function Result Cache
The Amazing and Elegant PL/SQL Function Result Cache
 
Turbocharge SQL Performance in PL/SQL with Bulk Processing
Turbocharge SQL Performance in PL/SQL with Bulk ProcessingTurbocharge SQL Performance in PL/SQL with Bulk Processing
Turbocharge SQL Performance in PL/SQL with Bulk Processing
 
Python SQite3 database Tutorial | SQlite Database
Python SQite3 database Tutorial | SQlite DatabasePython SQite3 database Tutorial | SQlite Database
Python SQite3 database Tutorial | SQlite Database
 
View & index in SQL
View & index in SQLView & index in SQL
View & index in SQL
 
Advanced PLSQL Optimizing for Better Performance
Advanced PLSQL Optimizing for Better PerformanceAdvanced PLSQL Optimizing for Better Performance
Advanced PLSQL Optimizing for Better Performance
 
Aggregating Data Using Group Functions
Aggregating Data Using Group FunctionsAggregating Data Using Group Functions
Aggregating Data Using Group Functions
 
Sql server T-sql basics ppt-3
Sql server T-sql basics  ppt-3Sql server T-sql basics  ppt-3
Sql server T-sql basics ppt-3
 

Similaire à All About PL/SQL Collections

Impact Analysis with PL/Scope
Impact Analysis with PL/ScopeImpact Analysis with PL/Scope
Impact Analysis with PL/ScopeSteven Feuerstein
 
JSON and PL/SQL: A Match Made in Database
JSON and PL/SQL: A Match Made in DatabaseJSON and PL/SQL: A Match Made in Database
JSON and PL/SQL: A Match Made in DatabaseSteven Feuerstein
 
Unit Testing Oracle PL/SQL Code: utPLSQL, Excel and More
Unit Testing Oracle PL/SQL Code: utPLSQL, Excel and MoreUnit Testing Oracle PL/SQL Code: utPLSQL, Excel and More
Unit Testing Oracle PL/SQL Code: utPLSQL, Excel and MoreSteven Feuerstein
 
Oracle Application Express and PL/SQL: a world-class combo
Oracle Application Express and PL/SQL: a world-class comboOracle Application Express and PL/SQL: a world-class combo
Oracle Application Express and PL/SQL: a world-class comboSteven Feuerstein
 
Database Developers: the most important developers on earth?
Database Developers: the most important developers on earth?Database Developers: the most important developers on earth?
Database Developers: the most important developers on earth?Steven Feuerstein
 
Appendix f education
Appendix f educationAppendix f education
Appendix f educationImran Ali
 
Free Oracle Training
Free Oracle TrainingFree Oracle Training
Free Oracle Trainingsdturton
 
Oracle PL/SQL 12c and 18c New Features + RADstack + Community Sites
Oracle PL/SQL 12c and 18c New Features + RADstack + Community SitesOracle PL/SQL 12c and 18c New Features + RADstack + Community Sites
Oracle PL/SQL 12c and 18c New Features + RADstack + Community SitesSteven Feuerstein
 
Using Edition-Based Redefinition for Zero Downtime PL/SQL Changes
Using Edition-Based Redefinition for Zero Downtime PL/SQL ChangesUsing Edition-Based Redefinition for Zero Downtime PL/SQL Changes
Using Edition-Based Redefinition for Zero Downtime PL/SQL ChangesChris Saxon
 
Speakers at Nov 2019 PL/SQL Office Hours session
Speakers at Nov 2019 PL/SQL Office Hours sessionSpeakers at Nov 2019 PL/SQL Office Hours session
Speakers at Nov 2019 PL/SQL Office Hours sessionSteven Feuerstein
 
How to Build a High Performance Application with PHP and Swoole?
How to Build a High Performance Application with PHP and Swoole?How to Build a High Performance Application with PHP and Swoole?
How to Build a High Performance Application with PHP and Swoole?Albert Chen
 
Java Community and Overview Track - July 2015
Java Community and Overview Track - July 2015 Java Community and Overview Track - July 2015
Java Community and Overview Track - July 2015 Yolande Poirier
 
Java Community News - September 2015
Java Community News - September 2015Java Community News - September 2015
Java Community News - September 2015Yolande Poirier
 

Similaire à All About PL/SQL Collections (20)

Impact Analysis with PL/Scope
Impact Analysis with PL/ScopeImpact Analysis with PL/Scope
Impact Analysis with PL/Scope
 
JSON and PL/SQL: A Match Made in Database
JSON and PL/SQL: A Match Made in DatabaseJSON and PL/SQL: A Match Made in Database
JSON and PL/SQL: A Match Made in Database
 
Unit Testing Oracle PL/SQL Code: utPLSQL, Excel and More
Unit Testing Oracle PL/SQL Code: utPLSQL, Excel and MoreUnit Testing Oracle PL/SQL Code: utPLSQL, Excel and More
Unit Testing Oracle PL/SQL Code: utPLSQL, Excel and More
 
Oracle Application Express and PL/SQL: a world-class combo
Oracle Application Express and PL/SQL: a world-class comboOracle Application Express and PL/SQL: a world-class combo
Oracle Application Express and PL/SQL: a world-class combo
 
Database Developers: the most important developers on earth?
Database Developers: the most important developers on earth?Database Developers: the most important developers on earth?
Database Developers: the most important developers on earth?
 
OLD APEX and PL/SQL
OLD APEX and PL/SQLOLD APEX and PL/SQL
OLD APEX and PL/SQL
 
Appendix f education
Appendix f educationAppendix f education
Appendix f education
 
PL/SQL Guilty Pleasures
PL/SQL Guilty PleasuresPL/SQL Guilty Pleasures
PL/SQL Guilty Pleasures
 
Free Oracle Training
Free Oracle TrainingFree Oracle Training
Free Oracle Training
 
Bryn llewellyn why_use_plsql at amis25
Bryn llewellyn why_use_plsql at amis25Bryn llewellyn why_use_plsql at amis25
Bryn llewellyn why_use_plsql at amis25
 
Oracle PL/SQL 12c and 18c New Features + RADstack + Community Sites
Oracle PL/SQL 12c and 18c New Features + RADstack + Community SitesOracle PL/SQL 12c and 18c New Features + RADstack + Community Sites
Oracle PL/SQL 12c and 18c New Features + RADstack + Community Sites
 
D34010.pdf
D34010.pdfD34010.pdf
D34010.pdf
 
Quarterly leader-call-dec-2014
Quarterly leader-call-dec-2014Quarterly leader-call-dec-2014
Quarterly leader-call-dec-2014
 
Dd 1 1
Dd 1 1Dd 1 1
Dd 1 1
 
Using Edition-Based Redefinition for Zero Downtime PL/SQL Changes
Using Edition-Based Redefinition for Zero Downtime PL/SQL ChangesUsing Edition-Based Redefinition for Zero Downtime PL/SQL Changes
Using Edition-Based Redefinition for Zero Downtime PL/SQL Changes
 
Speakers at Nov 2019 PL/SQL Office Hours session
Speakers at Nov 2019 PL/SQL Office Hours sessionSpeakers at Nov 2019 PL/SQL Office Hours session
Speakers at Nov 2019 PL/SQL Office Hours session
 
How to Build a High Performance Application with PHP and Swoole?
How to Build a High Performance Application with PHP and Swoole?How to Build a High Performance Application with PHP and Swoole?
How to Build a High Performance Application with PHP and Swoole?
 
Java Community and Overview Track - July 2015
Java Community and Overview Track - July 2015 Java Community and Overview Track - July 2015
Java Community and Overview Track - July 2015
 
Les01
Les01Les01
Les01
 
Java Community News - September 2015
Java Community News - September 2015Java Community News - September 2015
Java Community News - September 2015
 

Plus de Steven Feuerstein

Six simple steps to unit testing happiness
Six simple steps to unit testing happinessSix simple steps to unit testing happiness
Six simple steps to unit testing happinessSteven Feuerstein
 
New Stuff in the Oracle PL/SQL Language
New Stuff in the Oracle PL/SQL LanguageNew Stuff in the Oracle PL/SQL Language
New Stuff in the Oracle PL/SQL LanguageSteven Feuerstein
 
AskTOM Office Hours on Database Triggers
AskTOM Office Hours on Database TriggersAskTOM Office Hours on Database Triggers
AskTOM Office Hours on Database TriggersSteven Feuerstein
 
AskTOM Office Hours - Dynamic SQL in PL/SQL
AskTOM Office Hours - Dynamic SQL in PL/SQLAskTOM Office Hours - Dynamic SQL in PL/SQL
AskTOM Office Hours - Dynamic SQL in PL/SQLSteven Feuerstein
 
Take Full Advantage of the Oracle PL/SQL Compiler
Take Full Advantage of the Oracle PL/SQL CompilerTake Full Advantage of the Oracle PL/SQL Compiler
Take Full Advantage of the Oracle PL/SQL CompilerSteven Feuerstein
 
utPLSQL: Unit Testing for Oracle PL/SQL
utPLSQL: Unit Testing for Oracle PL/SQLutPLSQL: Unit Testing for Oracle PL/SQL
utPLSQL: Unit Testing for Oracle PL/SQLSteven Feuerstein
 

Plus de Steven Feuerstein (8)

New(er) Stuff in PL/SQL
New(er) Stuff in PL/SQLNew(er) Stuff in PL/SQL
New(er) Stuff in PL/SQL
 
Six simple steps to unit testing happiness
Six simple steps to unit testing happinessSix simple steps to unit testing happiness
Six simple steps to unit testing happiness
 
New Stuff in the Oracle PL/SQL Language
New Stuff in the Oracle PL/SQL LanguageNew Stuff in the Oracle PL/SQL Language
New Stuff in the Oracle PL/SQL Language
 
AskTOM Office Hours on Database Triggers
AskTOM Office Hours on Database TriggersAskTOM Office Hours on Database Triggers
AskTOM Office Hours on Database Triggers
 
High Performance PL/SQL
High Performance PL/SQLHigh Performance PL/SQL
High Performance PL/SQL
 
AskTOM Office Hours - Dynamic SQL in PL/SQL
AskTOM Office Hours - Dynamic SQL in PL/SQLAskTOM Office Hours - Dynamic SQL in PL/SQL
AskTOM Office Hours - Dynamic SQL in PL/SQL
 
Take Full Advantage of the Oracle PL/SQL Compiler
Take Full Advantage of the Oracle PL/SQL CompilerTake Full Advantage of the Oracle PL/SQL Compiler
Take Full Advantage of the Oracle PL/SQL Compiler
 
utPLSQL: Unit Testing for Oracle PL/SQL
utPLSQL: Unit Testing for Oracle PL/SQLutPLSQL: Unit Testing for Oracle PL/SQL
utPLSQL: Unit Testing for Oracle PL/SQL
 

Dernier

Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 

Dernier (20)

Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 

All About PL/SQL Collections