Sunteți pe pagina 1din 161

12/18/2015

Note: Small fonts in this presentation

Can you read this ?

SQL> select sample_font


2 from dual ;

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 2

1
12/18/2015

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 4

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 5

2
12/18/2015

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 6

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 7

3
12/18/2015

bio

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 8

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

4
12/18/2015

make you more successful with Oracle

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

SQL-lectric !!!

Connor McDonald
Developer Advocate for SQL
2015

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | Oracle Confidential – Internal/Restricted/Highly Restricted

5
12/18/2015

why talk about SQL


(part 1)

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 13

SQL is sortta important …

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 14

6
12/18/2015

“….the complexity of dealing with a “[Facebook] started in the Hadoop


non-ACID data store in every part of world. We are now bringing in
our business logic would be too relational to enhance that. ... [we]
great, and there was simply no way realized that using the wrong
our business could function without technology for certain kinds of
SQL queries.” problems can be difficult.”
Google, VLDB 2013 Ken Rudin, Facebook, TDWI 2013

https://www.linkedin.com/groups/Find-out-why-Google-decided-4434815.S.273792742 http://tdwi.org/articles/2013/05/06/facebooks-relational-platform.aspx

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 15

7
12/18/2015

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

why talk about SQL


(part 2)

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 18

8
12/18/2015

we suck at set theory....

....technically

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 19

not our fault

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 20

9
12/18/2015

Codd & Date

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 21

"data is represented as mathematical n-ary relations, an n-ary


relation being a subset of the Cartesian product of n domains."

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 22

10
12/18/2015

wha ?

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 23

we excel at set theory....

....in the real world

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 24

11
12/18/2015

shopping

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 25

in the real world

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 26

12
12/18/2015

drive to shop;

pick up items;

pay for items;

drive home;

maybe fill up with petrol;

maybe pick up a newspaper;

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 27

efficient
drive to shop;

pick up items;

pay for items;

drive home;

maybe fill up with petrol;

maybe pick up a newspaper;

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 27

13
12/18/2015

efficient
drive to shop;

pick up items;

pay for items;

drive home;

maybe fill up with petrol;

maybe pick up a newspaper;

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 27

efficient
drive to shop;

pick up items;

pay for items;

drive home;

maybe fill up with petrol;

maybe pick up a newspaper;

value add
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 27

14
12/18/2015

in the technical world

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 28

Shopping v1.0

subroutine PURCHASE_ITEM(item_id)
- drive to shop
- obtain item
- pay for item
- drive home

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 29

15
12/18/2015

Shopping v1.0

subroutine PURCHASE_ITEM(item_id)
- drive to shop
- obtain item
- pay for item
- drive home Shopping v2.0
for each_item in LIST_OF_ITEMS
do
purchase_item;
end loop;

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 29

Shopping v1.0

subroutine PURCHASE_ITEM(item_id)
- drive to shop
- obtain item
- pay for item
- drive home Shopping v2.0
for each_item in LIST_OF_ITEMS
do
purchase_item;
Shopping v2.1
end loop;

ORA-20000: No petrol found at supermarket

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 29

16
12/18/2015

business analysts...

procedural analysis

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 30

technical analysts...

procedural specifications

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 31

17
12/18/2015

programmers

procedural programs

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 32

its all about the SQL

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 33

18
12/18/2015

this session

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 34

my favourites

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 35

19
12/18/2015

Favourite:

subquery factoring

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 36

WITH clause

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 37

20
12/18/2015

SQL> WITH last_hire AS


2 ( select deptno, max(hiredate)
3 from emp
4 group by deptno
5 )
6 select * from last_hire;

DEPTNO MAX(HIRED
---------- ---------
30 03-DEC-81
20 12-JAN-83
10 23-JAN-82

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 38

"gee.......wow"

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 39

21
12/18/2015

why is it cool ?

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 40

good solution metaphor

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 41

22
12/18/2015

recall: "We suck at set theory"

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 42

"First, get the total salary paid by department...

SQL> WITH dept_salaries AS (


2 SELECT dname, SUM(sal) dept_sal
3 FROM emp e, dept d
4 WHERE e.deptno = d.deptno
5 GROUP BY dname),

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 43

23
12/18/2015

"...then get the average of these totals...

6 avg_sal AS ( SELECT AVG(dept_sal) avsal


7 FROM dept_salaries)

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 44

"...then list those departments above average."

8 SELECT * FROM dept_salaries d, avg_sal a


9 WHERE d.dept_sal > a.avsal
10 ORDER BY d.dname;

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 45

24
12/18/2015

SQL> WITH dept_salaries AS (


2 SELECT dname, SUM(sal) dept_sal
3 FROM emp e, dept d
4 WHERE e.deptno = d.deptno
5 GROUP BY dname),

6 avg_sal AS ( SELECT AVG(dept_sal) avsal


7 FROM dept_salaries)

8 SELECT * FROM dept_salaries d, avg_sal a


9 WHERE d.dept_sal > a.avsal
10 ORDER BY d.dname;

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 46

procedural approach....

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 47

25
12/18/2015

...set based solution

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 48

things to note...

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 49

26
12/18/2015

execution plan

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 50

two possibilities

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 51

27
12/18/2015

temporary storage

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 52

----------------------------------------------------------------------
| Id | Operation | Name |
----------------------------------------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | TEMP TABLE TRANSFORMATION | |
| 2 | LOAD AS SELECT | |
| 3 | HASH GROUP BY | |
| 4 | MERGE JOIN | |
| 5 | TABLE ACCESS BY INDEX ROWID| DEPT |
| 6 | INDEX FULL SCAN | PK_DEPT |
| 7 | SORT JOIN | |
| 8 | TABLE ACCESS FULL | EMP |
| 9 | SORT ORDER BY | |
| 10 | NESTED LOOPS | |
| 11 | VIEW | |
| 12 | SORT AGGREGATE | |
| 13 | VIEW | |
| 14 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6624_AF422F5 |
| 15 | VIEW | |
| 16 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6624_AF422F5 |
----------------------------------------------------------------------

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 53

28
12/18/2015

SQL> alter session set sql_trace = true;

Session altered.

SQL> WITH dept_salaries AS (


2 SELECT dname, SUM(sal) dept_sal
3 FROM emp e, dept d
4 WHERE e.deptno = d.deptno
5 GROUP BY dname),
6 avg_sal AS ( SELECT AVG(dept_sal) asal
7 FROM dept_salaries)
8 SELECT * FROM dept_salaries d, avg_sal a
9 WHERE d.dept_sal > a.asal
10 ORDER BY d.dname;

DNAME DEPT_SAL ASAL


-------------- ---------- ----------
RESEARCH 21750 19350

SQL> alter session set sql_trace = false;

Session altered.

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 54

PARSING IN CURSOR #12 len=179 dep=1 uid=0 oct=1...

CREATE GLOBAL TEMPORARY


TABLE "SYS"."SYS_TEMP_0FD9D6625_AF422F5"
("C0" VARCHAR2(14),"C1" NUMBER )
IN_MEMORY_METADATA CURSOR_SPECIFIC_SEGMENT
STORAGE (OBJNO 4254950949 ) NOPARALLEL

END OF STMT

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 55

29
12/18/2015

no temporary storage

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 56

------------------------------------------------------
| Id | Operation | Name |
------------------------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | SORT ORDER BY | |
| 2 | NESTED LOOPS | |
| 3 | VIEW | |
| 4 | SORT AGGREGATE | |
| 5 | VIEW | |
| 6 | HASH GROUP BY | |
| 7 | MERGE JOIN | |
| 8 | TABLE ACCESS BY INDEX ROWID| DEPT |
| 9 | INDEX FULL SCAN | PK_DEPT |
| 10 | SORT JOIN | |
| 11 | TABLE ACCESS FULL | EMP |
| 12 | VIEW | |
| 13 | SORT GROUP BY | |
| 14 | MERGE JOIN | |
| 15 | TABLE ACCESS BY INDEX ROWID | DEPT |
| 16 | INDEX FULL SCAN | PK_DEPT |
| 17 | SORT JOIN | |
| 18 | TABLE ACCESS FULL | EMP |
------------------------------------------------------

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 57

30
12/18/2015

explicit control

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 58

SQL> WITH dept_salaries AS (


2 SELECT /*+ INLINE */ dname, SUM(sal) dept_sal
3 FROM emp e, dept d
4 WHERE e.deptno = d.deptno
5 GROUP BY dname),
6 avg_sal AS ( SELECT AVG(dept_sal) asal
7 FROM dept_salaries)
8 SELECT * FROM dept_salaries d, avg_sal a
9 WHERE d.dept_sal > a.asal
10 ORDER BY d.dname;

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 59

31
12/18/2015

SQL> WITH dept_salaries AS (


2 SELECT /*+ MATERIALIZE*/ dname, SUM(sal) dept_sal
3 FROM emp e, dept d
4 WHERE e.deptno = d.deptno
5 GROUP BY dname),
6 avg_sal AS ( SELECT AVG(dept_sal) asal
7 FROM dept_salaries)
8 SELECT * FROM dept_salaries d, avg_sal a
9 WHERE d.dept_sal > a.asal
10 ORDER BY d.dname;

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 60

undocumented .... sort of

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 61

32
12/18/2015

useful control over optimizer

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 62

useful control over database links

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 63

33
12/18/2015

... more on WITH later

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 64

Favourite:

temporal validity

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

34
12/18/2015

Huh ?

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

very common

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 67

35
12/18/2015

when is a row "valid"

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 68

SQL> CREATE TABLE emp_temporal (


2 empno NUMBER,
3 name VARCHAR2(30),
4 sal NUMBER,
5 deptno NUMBER,
6 start_dt DATE,
7 end_dt DATE,
8
9 );

Table created.

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 69

36
12/18/2015

12c - part of the definition

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 70

SQL> CREATE TABLE emp_temporal (


2 empno NUMBER,
3 name VARCHAR2(30),
4 sal NUMBER,
5 deptno NUMBER,
6 start_dt DATE,
7 end_dt DATE,
8 PERIOD FOR valid_range (start_dt, end_dt)
9 );

Table created.

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 71

37
12/18/2015

examples

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 72

SQL> select * from emp_temporal


2 order by empno, start_dt;

EMPNO NAME SAL DEPTNO START_DT END_DT


---------- ------------ ---------- ---------- --------- ---------
7369 SMITH 806 20 01-JAN-14 01-MAR-14
7369 SMITHX 8060 21 02-MAR-14 01-OCT-14
7499 ALLEN 1606 30 01-JAN-14 01-MAR-14
7499 ALLENX 16060 31 02-MAR-14 01-OCT-14
7521 WARD 1256 30 01-JAN-14 01-MAR-14
7521 WARDX 12560 31 02-MAR-14 01-OCT-14
7566 JONES 2981 20 01-JAN-14 01-MAR-14
7566 JONESX 29810 21 02-MAR-14 01-OCT-14
7654 MARTIN 1256 30 01-JAN-14 01-MAR-14
7654 MARTINX 12560 31 02-MAR-14 01-OCT-14
7698 BLAKE 2856 30 01-JAN-14 01-MAR-14

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 73

38
12/18/2015

SQL> select * from emp_temporal


2 as of period for valid_range '01-FEB-14';

EMPNO NAME SAL DEPTNO START_DT END_DT


---------- ------------ ---------- ---------- --------- ---------
7369 SMITH 806 20 01-JAN-14 01-MAR-14
7499 ALLEN 1606 30 01-JAN-14 01-MAR-14
7521 WARD 1256 30 01-JAN-14 01-MAR-14
7566 JONES 2981 20 01-JAN-14 01-MAR-14
7654 MARTIN 1256 30 01-JAN-14 01-MAR-14

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 74

so what's happening ?

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 75

39
12/18/2015

a slight digression

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 76

Favourite:

query expansion

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 77

40
12/18/2015

SQL> set autotrace traceonly stat

SQL> select * from MY_STUFF


2 where CREATED > sysdate

Statistics
------------------------------------------
651 recursive calls
0 db block gets
2243 consistent gets
24 physical reads

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 78

SQL> variable c clob

SQL> begin
2 dbms_utility.expand_sql_text
3 ( 'select * from MY_STUFF'||
4 'where created > sysdate',:c);
5 end;
6 /

PL/SQL procedure successfully completed.

SQL> print c

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 79

41
12/18/2015

SQL> create or replace


2 view MY_STUFF as
3 select
4 o.owner,
5 o.created,
6 s.bytes,
7 s.tablespace_name
8 from
9 dba_segments s,
10 all_objects o
11 where o.owner = s.owner
12 and o.object_name = s.segment_name;

View created.

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 80

SELECT "A1"."OWNER" "OWNER",


"A1"."NAME" "NAME",
"A1"."CREATED" "CREATED",
"A1"."BYTES" "BYTES",
"A1"."TABLESPACE_NAME" "TABLESPACE_NAME"
FROM (SELECT "A2"."OWNER" "OWNER",
"A2"."OBJECT_NAME" "NAME",
"A2"."CREATED" "CREATED",
"A3"."BYTES" "BYTES",
"A3"."TABLESPACE_NAME" "TABLESPACE_NAME" FROM (SELECT "A4"
."OWNER" "OWNER",
"A4"."SEGMENT_NAME" "SEGMENT_NAME",
"A4"."PARTITION_NAME" "PARTITION_NAME",
"A4"."SEGMENT_TYPE" "SEGMENT_TYPE",
"A4"."SEGMENT_SUBTYPE" "SEGMENT_SUBTYPE",
"A4"."TABLESPACE_NAME" "TABLESPACE_NAME",
"A4"."HEADER_FILE" "HEADER_FILE",
"A4"."HEADER_BLOCK" "HEADER_BLOCK",
DECODE(BITAND("A4"."SEGMENT_FLAGS",131072),131072,
"A4"."BLOCKS",DECODE(BITAND("A4"."SEGMENT_FLAGS",1),1,
"SYS"."DBMS_SPACE_ADMIN"."SEGMENT_NUMBER_BLOCKS"("A4"."TABLESPACE_ID",
"A4"."RELATIVE_FNO",
"A4"."HEADER_BLOCK",
"A4"."SEGMENT_TYPE_ID",
"A4"."BUFFER_POOL_ID",
"A4"."SEGMENT_FLAGS",
"A4"."SEGMENT_OBJD",
"A4"."BLOCKS"),
"A4"."BLOCKS"))*"A4"."BLOCKSIZE" "BYTES",
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 81
DECODE(BITAND("A4"."SEGMENT_FLAGS",131072),131072,
"A4"."BLOCKS",DECODE(BITAND("A4"."SEGMENT_FLAGS",1),1,

42
12/18/2015

"A4"."HEADER_BLOCK",
"A4"."SEGMENT_TYPE_ID",
"A4"."BUFFER_POOL_ID",
"A4"."SEGMENT_FLAGS",
"A4"."SEGMENT_OBJD",
"A4"."BLOCKS"),
"A4"."BLOCKS")) "BLOCKS",DECODE(BITAND("A4"."SEGMENT_FLAGS",131072),131072,
"A4"."EXTENTS",DECODE(BITAND("A4"."SEGMENT_FLAGS",1),1,
"SYS"."DBMS_SPACE_ADMIN"."SEGMENT_NUMBER_EXTENTS"("A4"."TABLESPACE_ID",
"A4"."RELATIVE_FNO",
"A4"."HEADER_BLOCK",
"A4"."SEGMENT_TYPE_ID",
"A4"."BUFFER_POOL_ID",
"A4"."SEGMENT_FLAGS",
"A4"."SEGMENT_OBJD",
"A4"."EXTENTS"),
"A4"."EXTENTS")) "EXTENTS",
"A4"."INITIAL_EXTENT" "INITIAL_EXTENT",
"A4"."NEXT_EXTENT" "NEXT_EXTENT",
"A4"."MIN_EXTENTS" "MIN_EXTENTS",
"A4"."MAX_EXTENTS" "MAX_EXTENTS",
"A4"."MAX_SIZE" "MAX_SIZE",
"A4"."RETENTION" "RETENTION",
"A4"."MINRETENTION" "MINRETENTION",
"A4"."PCT_INCREASE" "PCT_INCREASE",
"A4"."FREELISTS" "FREELISTS",
"A4"."FREELIST_GROUPS" "FREELIST_GROUPS",
"A4"."RELATIVE_FNO" "RELATIVE_FNO",Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 82

DECODE("A4"."BUFFER_POOL_ID",1,'KEEP',2,'RECYCLE','DEFAULT') "BUFFER_POOL",

"A198"."SUBNAME" "PARTITION_NAME",
"A196"."OBJECT_TYPE" "SEGMENT_TYPE",
"A195"."TYPE#" "SEGMENT_TYPE_ID",DECODE(BIT
AND("A195"."SPARE1",2097408),2097152,'SECUREFILE',256,'ASSM','MSSM')
"SEGMENT_SUBTYPE",
"A197"."TS#" "TABLESPACE_ID",
"A197"."NAME" "TABLESPACE_NAME",
"A197"."BLOCKSIZE" "BLOCKSIZE",
"A194"."FILE#" "HEADER_FILE",
"A195"."BLOCK#" "HEADER_BLOCK",
"A195"."BLOCKS"*"A197"."BLOCKSIZE" "BYTES",
"A195"."BLOCKS" "BLOCKS",
"A195"."EXTENTS" "EXTENTS",
"A195"."INIEXTS"*"A197"."BLOCKSIZE" "INITIAL_EXTENT",
"A195"."EXTSIZE"*"A197"."BLOCKSIZE" "NEXT_EXTENT",
"A195"."MINEXTS" "MIN_EXTENTS",
"A195"."MAXEXTS"
"MAX_EXTENTS",DECODE(BITAND("A195"."SPARE1",4194304),4194304,
"A195"."BITMAPRANGES",NULL) "MAX_SIZE",TO_CHAR(DECODE(
BITAND("A195"."SPARE1",2097152),2097152,
DECODE("A195"."LISTS",0,'NONE',1,'AUTO',2,'MIN',3,'MAX',4,'DEFAULT','INVALID'
),NULL))
"RETENTION",DECODE(BITAND("A195"."SPARE1",2097152),2097152,
"A195"."GROUPS",NULL)
"MINRETENTION",DECODE(BITAND("A197"."FLAGS",3),1,TO_NUMBER(NULL),
"A195"."EXTPCT") "PCT_INCREASE",DECODE(BITAND("A197"."FLAGS",32),32,
TO_NUMBER(NULL),DECODE("A195"."LISTS",0,1,
"A195"."LISTS"))
"FREELISTS",DECODE(BITAND("A197"."FLAGS",32),32,TO_NUMBER(NULL),DECODE("A195"
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 83
."GROUPS",0,1,
"A195"."GROUPS")) "FREELIST_GROUPS",

43
12/18/2015

DECODE(BITAND("A209"."PROPERTY",8192),8192,'NESTED TABLE','TABLE')
"OBJECT_TYPE",
2 "OBJECT_TYPE_ID",5 "SEGMENT_TYPE_ID",
"A209"."OBJ#" "OBJECT_ID",
"A209"."FILE#" "HEADER_FILE",
"A209"."BLOCK#" "HEADER_BLOCK",
"A209"."TS#" "TS_NUMBER" FROM "SYS"."TAB$" "A209" WHERE
BITAND("A209"."PROPERTY",1024)=0) UNI
ON ALL (SELECT 'TABLE PARTITION' "OBJECT_TYPE",19 "OBJECT_TYPE_ID",5
"SEGMENT_TYPE_ID",
"A208"."OBJ#" "OBJECT_ID",
"A208"."FILE#" "HEADER_FILE",
"A208"."BLOCK#" "HEADER_BLOCK",
"A208"."TS#" "TS_NUMBER" FROM "SYS"."TABPART$" "A208") UNION ALL
(SELECT 'CLUSTER' "OBJECT_TYPE",3 "OBJECT_TYPE_ID",5 "SEGMENT_TYPE_ID",
"A207"."OBJ#" "OBJECT_ID",
"A207"."FILE#" "HEADER_FILE",
"A207"."BLOCK#" "HEADER_BLOCK",
"A207"."TS#" "TS_NUMBER" FROM "SYS"."CLU$" "A207") UNION ALL
(SELECT DECODE("A206"."TYPE#",8,'LOBINDEX','INDEX') "OBJECT_TYPE",1
"OBJECT_TYPE_ID",6 "SEGMENT_TYPE_ID",
"A206"."OBJ#" "OBJECT_ID",
"A206"."FILE#" "HEADER_FILE",
"A206"."BLOCK#" "HEADER_BLOCK",
"A206"."TS#" "TS_NUMBER" FROM "SYS"."IND$" "A206" WHERE "A206"."TYPE#"=1 OR
"A206"."TYPE#"=2 OR
"A206"."TYPE#"=3 OR
"A206"."TYPE#"=4 OR
"A206"."TYPE#"=6 OR Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 84
"A206"."TYPE#"=7 OR

"A205"."TS#" "TS_NUMBER" FROM "SYS"."INDPART$" "A205") UNION ALL


(SELECT 'LOBSEGMENT' "OBJECT_TYPE",21 "OBJECT_TYPE_ID",8 "SEGMENT_TYPE_ID",
"A204"."LOBJ#" "OBJECT_ID",
"A204"."FILE#" "HEADER_FILE",
"A204"."BLOCK#" "HEADER_BLOCK",
"A204"."TS#" "TS_NUMBER" FROM "SYS"."LOB$" "A204" WHERE
BITAND("A204"."PROPERTY",64)=0 OR
BITAND("A204"."PROPERTY",128)=128) UNION ALL
(SELECT 'TABLE SUBPARTITION' "OBJECT_TYPE",34 "OBJECT_TYPE_ID",5
"SEGMENT_TYPE_ID",
"A203"."OBJ#" "OBJECT_ID",
"A203"."FILE#" "HEADER_FILE",
"A203"."BLOCK#" "HEADER_BLOCK",
"A203"."TS#" "TS_NUMBER" FROM "SYS"."TABSUBPART$" "A203") UNION ALL
(SELECT 'INDEX SUBPARTITION' "OBJECT_TYPE",35 "OBJECT_TYPE_ID",6
"SEGMENT_TYPE_ID",
"A202"."OBJ#" "OBJECT_ID",
"A202"."FILE#" "HEADER_FILE",
"A202"."BLOCK#" "HEADER_BLOCK",
"A202"."TS#" "TS_NUMBER" FROM "SYS"."INDSUBPART$" "A202") UNION ALL
(SELECT DECODE("A201"."FRAGTYPE$",'P','LOB PARTITION','LOB SUBPARTITION')
"OBJECT_TYPE",DECODE("A201"."FRAGTYPE$",'P',40,41) "OBJECT_TYPE_ID",8
"SEGMENT_TYPE_ID",
"A201"."FRAGOBJ#" "OBJECT_ID",
"A201"."FILE#" "HEADER_FILE",
"A201"."BLOCK#" "HEADER_BLOCK",
"A201"."TS#" "TS_NUMBER" FROM "SYS"."LOBFRAG$" "A201")) "A196",
"SYS"."SEG$" "A195", Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 85

"SYS"."FILE$" "A194" WHERE "A195"."FILE#"="A196"."HEADER_FILE" AND

44
12/18/2015

"A195"."FILE#"="A194"."RELFILE#") UNION ALL


(SELECT NVL("A193"."NAME",'SYS') "OWNER",
"A191"."NAME" "SEGMENT_NAME",NULL "PARTITION_NAME",
DECODE("A190"."TYPE#",1,'ROLLBACK',10,'TYPE2 UNDO') "SEGMENT_TYPE",
"A190"."TYPE#" "SEGMENT_TYPE_ID",NULL "SEGMENT_SUBTYPE",
"A192"."TS#" "TABLESPACE_ID",
"A192"."NAME" "TABLESPACE_NAME",
"A192"."BLOCKSIZE" "BLOCKSIZE",
"A189"."FILE#" "HEADER_FILE",
"A190"."BLOCK#" "HEADER_BLOCK",
"A190"."BLOCKS"*"A192"."BLOCKSIZE" "BYTES",
"A190"."BLOCKS" "BLOCKS",
"A190"."EXTENTS" "EXTENTS",
"A190"."INIEXTS"*"A192"."BLOCKSIZE" "INITIAL_EXTENT",
"A190"."EXTSIZE"*"A192"."BLOCKSIZE" "NEXT_EXTENT",
"A190"."MINEXTS" "MIN_EXTENTS",
"A190"."MAXEXTS"
"MAX_EXTENTS",DECODE(BITAND("A190"."SPARE1",4194304),4194304,
"A190"."BITMAPRANGES",NULL) "MAX_SIZE",NULL "RETENTION",NULL "MINRETENTION",
"A190"."EXTPCT"
"PCT_INCREASE",DECODE(BITAND("A192"."FLAGS",32),32,TO_NUMBER(NULL),DECODE("A1
90"."LISTS",0,1,
"A190"."LISTS"))
"FREELISTS",DECODE(BITAND("A192"."FLAGS",32),32,TO_NUMBER(NULL),
DECODE("A190"."GROUPS",0,1,"A190"."GROUPS")) "FREELIST_GROUPS",
"A190"."FILE#" "RELATIVE_FNO",BITAND("A190"."CACHEHINT",3)
"BUFFER_POOL_ID",BITAND("A190"."CACHEHINT",12)/4 "FLASH_CACHE",
BITAND("A190"."CACHEHINT",48)/16 "CELL_FLASH_CACHE",NVL("A190"."SPARE1",0)
"SEGMENT_FLAGS", Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 86

"A191"."US#" "SEGMENT_OBJD" FROM "SYS"."USER$" "A193","SYS"."TS$" "A192",

"A191"."TS#"="A189"."TS#" AND
"A191"."FILE#"="A189"."RELFILE#") UNION ALL
(SELECT NVL("A188"."NAME",'SYS') "OWNER",
TO_CHAR("A185"."FILE#")||'.'||TO_CHAR("A186"."BLOCK#") "SEGMENT_NAME",NULL
"PARTITION_NAME",
DECODE("A186"."TYPE#",2,'DEFERRED ROLLBACK',3,
'TEMPORARY',4,'CACHE',9,'SPACE HEADER','UNDEFINED') "SEGMENT_TYPE",
"A186"."TYPE#" "SEGMENT_TYPE_ID",NULL "SEGMENT_SUBTYPE",
"A187"."TS#" "TABLESPACE_ID",
"A187"."NAME" "TABLESPACE_NAME",
"A187"."BLOCKSIZE" "BLOCKSIZE",
"A185"."FILE#" "HEADER_FILE",
"A186"."BLOCK#" "HEADER_BLOCK",
"A186"."BLOCKS"*"A187"."BLOCKSIZE" "BYTES",
"A186"."BLOCKS" "BLOCKS",
"A186"."EXTENTS" "EXTENTS",
"A186"."INIEXTS"*"A187"."BLOCKSIZE" "INITIAL_EXTENT",
"A186"."EXTSIZE"*"A187"."BLOCKSIZE" "NEXT_EXTENT",
"A186"."MINEXTS" "MIN_EXTENTS",
"A186"."MAXEXTS"
"MAX_EXTENTS",DECODE(BITAND("A186"."SPARE1",4194304),4194304,
"A186"."BITMAPRANGES",NULL) "MAX_SIZE",NULL
"RETENTION",NULL
"MINRETENTION",DECODE(BITAND("A187"."FLAGS",3),1,TO_NUMBER(NULL),
"A186"."EXTPCT")
"PCT_INCREASE",DECODE(BITAND("A187"."FLAGS",32),32,TO_NUMBER(NULL),DECODE("A1
86"."LISTS",0,1,
"A186"."LISTS"))
"FREELISTS",DECODE(BITAND("A187"."FLAGS",32),32,TO_NUMBER(NULL),DECODE("A186"
."GROUPS",0,1, Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 87

"A186"."GROUPS")) "FREELIST_GROUPS",

45
12/18/2015

"A186"."TYPE#"<>6 AND
"A186"."TYPE#"<>8 AND
"A186"."TYPE#"<>10 AND
"A186"."TYPE#"<>11 AND
"A186"."TS#"="A185"."TS#"
AND
"A186"."FILE#"="A185"."RELFILE#") UNION ALL
(SELECT NVL("A184"."NAME",'SYS') "OWNER",'HEATMAP' "SEGMENT_NAME",
NULL "PARTITION_NAME",'SYSTEM STATISTICS' "SEGMENT_TYPE",
"A182"."TYPE#" "SEGMENT_TYPE_ID",NULL "SEGMENT_SUBTYPE",
"A183"."TS#" "TABLESPACE_ID",
"A183"."NAME" "TABLESPACE_NAME",
"A183"."BLO
CKSIZE" "BLOCKSIZE",
"A181"."FILE#" "HEADER_FILE",
"A182"."BLOCK#" "HEADER_BLOCK",
"A182"."BLOCKS"*"A183"."BLOCKSIZE" "BYTES",
"A182"."BLOCKS" "BLOCKS",
"A182"."EXTENTS" "EXTENTS",
"A182"."INIEXTS"*"A183"."BLOCKSIZE" "INITIAL_EXTENT",
"A182"."EXTSIZE"*"A183"."BLOCKSIZE" "NEXT_EXTENT",
"A182"."MINEXTS" "MIN_EXTENTS",
"A182"."MAXEXTS"
"MAX_EXTENTS",DECODE(BITAND("A182"."SPARE1",4194304),4194304,
"A182"."BITMAPRANGES",NULL) "MAX_SIZE",NULL "RETENTION",NULL
"MINRETENTION",DECODE(BITAND("A183"."FLAGS",3),1,TO_NUMBER(NULL),
"A182"."EXTPCT")
"PCT_INCREASE",DECODE(BITAND("A183"."FLAGS",32),32,TO_NUMBER(NULL),DEC
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 88

ODE("A182"."LISTS",0,1,

"SYS"."TS$" "A183",
"SYS"."SEG$" "A182",
"SYS"."FILE$" "A181" WHERE "A182"."TS#"="A183"."TS#" AND
"A182"."USER#"="A184"."USER#"(+) AND
"A182"."TYPE#"=11 AND
"A182"."TS#"="A181"."TS#" AND
"A182"."FILE#"="A181"."RELFILE#")) "A4") "A3", (SELECT "A5"."NAME" "OWNER",
"A6"."NAME" "OBJECT_NAME",
"A6"."SUBNAME" "SUBOBJECT_NAME",
"A6"."OBJ#" "OBJECT_ID",
"A6"."DATAOBJ#" "DATA_OBJECT_ID",DECODE("A6"."TYPE#",0,'NEXT OBJECT',1,'INDEX',
2,'TABLE',3,'CLUSTER',4,'VIEW',5,'SYNONYM
',6,'SEQUENCE',7,'PROCEDURE',8,'FUNCTION',9,'PACKAGE',11,'PACKAGE BODY',12,
'TRIGGER',13,'TYPE',14,'TYPE BODY',19,'TABLE PARTITION',20,'INDEX PARTITION',
21,'LOB',22,'LIBRARY',23,'DIRECTORY',24,'QUEUE',28,'JAVA SOURCE',29,'JAVA CLASS',30,
'JAVA RESOURCE',32,'INDEXTYPE',33,'OPERATOR',34,
'TABLE SUBPARTITION',35,'INDEX SUBPARTITION',40,'LOB PARTITION',41,'LOB SUBPARTITION',42
,NVL( (SELECT 'REWRITE EQUIVALENCE' "'REWRITEEQUIVALENCE'" FROM SYS."SUM$" "A52" WHERE
"A52"."OBJ#"="A6"."OBJ#" AND
BITAND("A52"."XPFLAGS",8388608)=8388608),'MATERIALIZED VIEW'),43,'DIMENSION',
44,'CONTEXT',46,'RULE SET',47,'RESOURCE PLAN',48,'CONSUMER GROUP',55,'XML SCHEMA',56,'JAVA
DATA',57,'EDITION',59,'RULE',
60,'CAPTURE',61,'APPLY',62,'EVALUATION CONTEXT',66,'JOB',67,'PROGRAM',68,'JOB CLASS',69,
'WINDOW',72,'SCHEDULER GROUP',74,'SCHEDULE',79,'CHAIN',81,'FILE GROUP',82,'MINING
MODEL',87,'ASSEMBLY',90,'CREDENTIAL',92,'CUBE
DIMENSION',93,'CUBE',94,'MEASURE FOLDER',95,'CUBE BUILD PROCESS',100,'FILE WATCHER',
101,'DESTINATION',114,'SQL TRANSLATION PROFILE',115,'UNIFIED AUDIT POLICY','UNDEFINED')
"OBJECT_TYPE",
"A6"."CTIME" "CREATED", Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 89

"A6"."MTIME" "LAST_DDL_TIME",TO_CHAR("A6"."STIME",'YYYY-MM-DD:HH24:MI:SS') "TIMESTAMP",DEC

46
12/18/2015

16 ...

more

pages

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 90

back to temporal validity

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 91

47
12/18/2015

SQL> variable c clob

SQL> begin
2 dbms_utility.expand_sql_text(
3 q'{select * from emp_temporal
4 as of period for valid_range '01-FEB-14'}',:c);
6 end;
7 /

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

SQL> print c

C
------------------------------------------------
SELECT
"A1"."EMPNO"
...
FROM (
SELECT "A2"."EMPNO" "EMPNO",
"A2"."NAME"
FROM "SCOTT"."EMP_TEMPORAL" "A2"
WHERE ("A2"."START_DT" IS NULL
OR "A2"."START_DT"<='01-FEB-14')
AND ("A2"."END_DT" IS NULL
OR "A2"."END_DT">'01-FEB-14')
) "A1"

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 93

48
12/18/2015

existing tables

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 94

SQL> desc EMPLOYEE

Name Null? Type


------------------------- -------- ---------------
EMPNO NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(12,2)
DEPTNO NUMBER(2)

SQL> alter table EMPLOYEE add period for TIME_RANGE;

Table altered.

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 95

49
12/18/2015

SQL> desc EMPLOYEE

Name Null? Type


------------------------- -------- ---------------
EMPNO NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(12,2)
DEPTNO NUMBER(2)

still looks the same ?


Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 96

SQL> select column_name , hidden_column


2 from USER_TAB_COLS
3 where table_name = 'EMPLOYEE'
4 order by column_id;

COLUMN_NAME HIDDEN_COLUMN
------------------------------ -------------
EMPNO NO
ENAME NO
JOB NO
MGR NO
HIREDATE NO
SAL NO
COMM NO
DEPTNO NO
TIME_RANGE_START YES
TIME_RANGE_END YES
TIME_RANGE YES

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 97

50
12/18/2015

multi temporal validity

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 98

SQL> alter table EMP_TEMPORAL add period for CAL_RANGE;

Table altered.

SQL> alter table EMP_TEMPORAL add period for FINYR_RANGE;

Table altered.

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 99

51
12/18/2015

room to grow

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 100

no temporal constraints

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 101

52
12/18/2015

SQL> alter table EMP_TEMPORAL add primary key (empno);

Table altered.

SQL> insert into EMP_TEMPORAL


2 (empno, name, start_dt, end_dt )
3 values (20,'BROWN', '01-FEB-14','01-MAR-14');

1 row created.

SQL> insert into EMP_TEMPORAL


2 (empno, name, start_dt, end_dt )
3 values (20,'BROWN', '01-MAY-14','01-SEP-14');

insert into EMP_TEMPORAL


*
ERROR at line 1:
ORA-00001: unique constraint (SYS_C009892) violated

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 102

add START_DT to primary key ?

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

53
12/18/2015

no temporal validation

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 104

SQL> insert into EMP_TEMPORAL


2 (empno, name, start_dt, end_dt )
3 values (10,'JONES', '01-JAN-14','01-MAY-14');

1 row created.

SQL> insert into EMP_TEMPORAL


2 (empno, name, start_dt, end_dt )
3 values (10,'JONES', '01-FEB-14','01-MAR-14');

1 row created.

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

54
12/18/2015

no (native) temporal DML

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 106

SQL> update EMP_TEMPORAL


2 as of period for valid_range '01-FEB-14'
3 set sal = 10
4 where empno = 20;

as of period for valid_range '01-FEB-14'


*
ERROR at line 2:
ORA-08187: snapshot expression not allowed here

107

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

55
12/18/2015

SQL> update
2 ( select * from EMP_TEMPORAL
3 as of period for valid_range '01-FEB-14'
4 )
5 set sal = 10
6 where empno = 20;

1 row updated.

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 108

take note ..

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

56
12/18/2015

"Temporal validity is not supported


with a multitenant container
database"
12.1.0.1
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 110

bringing it all together

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

57
12/18/2015

the past the future

flashback temporal
data archive validity

112

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

SQL> begin
2 DBMS_FLASHBACK_ARCHIVE.ENABLE_AT_VALID_TIME (
3 level=>'ASOF',
4 query_time=>systimestamp+10);
5 end;
6 /

PL/SQL procedure successfully completed.

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 113

58
12/18/2015

the past the future

flashback temporal
data archive validity

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

the past the future

flashback
data archive
temporal
validity

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

59
12/18/2015

SQL> select * from emp_temporal


2 as of timestamp sysdate-10
3 as of period for valid_range '01-FEB-14';

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 115

Favourite:

top-n simplifications

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 116

60
12/18/2015

"5 most recently hired employees"

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 117

SQL> select empno, ename, hiredate


2 from emp
3 where rownum <= 5
4 order by hiredate desc;

EMPNO ENAME HIREDATE


---------- ---------- -------------------
7654 MARTIN 28/09/1981 00:00:00
7566 JONES 02/04/1981 00:00:00
7521 WARD 22/02/1981 00:00:00
7499 ALLEN 20/02/1981 00:00:00
7369 SMITH 17/12/1980 00:00:00

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 118

61
12/18/2015

SQL> select empno, ename, hiredate


2 from emp
3 where rownum <= 5
4 order by hiredate desc;

EMPNO ENAME HIREDATE


---------- ---------- -------------------
7654 MARTIN 28/09/1981 00:00:00
7566 JONES 02/04/1981 00:00:00
7521 WARD 22/02/1981 00:00:00
7499 ALLEN 20/02/1981 00:00:00
7369 SMITH 17/12/1980 00:00:00

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 118

inline view

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 119

62
12/18/2015

SQL> select *
2 from (
3 select empno, ename, hiredate
4 from emp
5 order by hiredate desc
6 )
7 where rownum <= 5;

EMPNO ENAME HIREDATE


---------- ---------- ---------
7876 ADAMS 23-MAY-87
7788 SCOTT 19-APR-87
...

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 120

------------------------------------------------
| Id | Operation | Name | Rows |
------------------------------------------------
| 0 | SELECT STATEMENT | | 5 |
|* 1 | COUNT STOPKEY | | |
| 2 | VIEW | | 14 |
|* 3 | SORT ORDER BY STOPKEY| | 14 |
| 4 | TABLE ACCESS FULL | EMP | 14 |
------------------------------------------------

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 121

63
12/18/2015

SQL> select *
2 from (
3 select
4 empno, ename, hiredate,
5 row_number() over ( order by hiredate desc) rn
6 from emp
7 )
8 where rn <= 5;

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 122

-------------------------------------------------
| Id | Operation | Name | Rows |
-------------------------------------------------
| 0 | SELECT STATEMENT | | 14 |
|* 1 | VIEW | | 14 |
|* 2 | WINDOW SORT PUSHED RANK| | 14 |
| 3 | TABLE ACCESS FULL | EMP | 14 |
-------------------------------------------------

Predicate Information (identified by operation id):


---------------------------------------------------

1 - filter("RN"<=5)
2 - filter(ROW_NUMBER() OVER
( ORDER BY HIREDATE") DESC )<=5)

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 123

64
12/18/2015

12c .... easier

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 124

SQL> select empno, ename, hiredate


2 from emp
3 order by hiredate desc
4 fetch first 5 rows only;

EMPNO ENAME HIREDATE


---------- ---------- ---------
7876 ADAMS 23-MAY-87
7788 SCOTT 19-APR-87
...

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 125

65
12/18/2015

behind the scenes

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 126

-------------------------------------------------
| Id | Operation | Name | Rows |
-------------------------------------------------
| 0 | SELECT STATEMENT | | 14 |
|* 1 | VIEW | | 14 |
|* 2 | WINDOW SORT PUSHED RANK| | 14 |
| 3 | TABLE ACCESS FULL | EMP | 14 |
-------------------------------------------------

Predicate Information (identified by operation id):


---------------------------------------------------

1 - filter("from$_subquery$_002".
"rowlimit_$$_rownumber"<=5)

2 - filter(ROW_NUMBER() OVER
( ORDER BY HIREDATE") DESC )<=5)

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 127

66
12/18/2015

variations

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 128

SQL> select empno, ename, hiredate


2 from emp
3 order by hiredate desc
4 fetch first 1 row only;

EMPNO ENAME HIREDATE


---------- ---------- ---------
7876 ADAMS 23-MAY-87

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 129

67
12/18/2015

SQL> select empno, ename, hiredate


2 from emp
3 order by hiredate desc
4 fetch first 5 row only;

EMPNO ENAME HIREDATE


---------- ---------- ---------
7876 ADAMS 23-MAY-87
7788 SCOTT 19-APR-87
7934 MILLER 23-JAN-82
7900 JAMES 03-DEC-81
7902 FORD 03-DEC-81

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 130

SQL> select empno, ename, hiredate


2 from emp
3 order by hiredate desc
4 fetch first 10 percent rows only;

EMPNO ENAME HIREDATE


---------- ---------- ---------
7876 ADAMS 23-MAY-87
7788 SCOTT 19-APR-87

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 131

68
12/18/2015

pagination

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 132

SQL> select empno, ename, hiredate


2 from emp
3 order by hiredate desc
4 offset 5 rows fetch next 3 rows only;

EMPNO ENAME HIREDATE


---------- ---------- ---------
7839 KING 17-NOV-81
7654 MARTIN 28-SEP-81
7844 TURNER 08-SEP-81

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 133

69
12/18/2015

can mimic rownum

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 134

SQL> select empno, ename, hiredate


2 from emp

4 fetch first 3 rows only;

EMPNO ENAME HIREDATE


---------- ---------- ---------
7369 SMITH 17-DEC-80
7499 ALLEN 20-FEB-81
7521 WARD 22-FEB-81

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 135

70
12/18/2015

-----------------------------------------------
| Id | Operation | Name | Rows |
-----------------------------------------------
| 0 | SELECT STATEMENT | | 14 |
|* 1 | VIEW | | 14 |
|* 2 | WINDOW NOSORT STOPKEY| | 14 |
| 3 | TABLE ACCESS FULL | EMP | 14 |
-----------------------------------------------

1 - filter("from$_subquery$_002"."rowlimit_$
2 - filter(ROW_NUMBER() OVER ( ORDER BY NULL ) <= 3

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 136

things to note

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 137

71
12/18/2015

SQL> select empno, ename, hiredate


2 from emp
3 order by hiredate desc
4 fetch LAST 5 rows only;

fetch LAST 5 rows only


*
ERROR at line 4:
ORA-00905: missing keyword

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 138

SQL> select *
2 from (
3 select empno, ename, hiredate
4 from emp
5 order by hiredate asc
6 fetch first 5 rows only
7 )
8 order by hiredate desc;

EMPNO ENAME HIREDATE


---------- ---------- ---------
7698 BLAKE 01-MAY-81
7566 JONES 02-APR-81
7521 WARD 22-FEB-81
7499 ALLEN 20-FEB-81
7369 SMITH 17-DEC-80

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 139

72
12/18/2015

or ...

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 140

SQL> select empno, ename, hiredate


2 from emp
3 order by hiredate desc
4 offset ( select count(*)-5 from emp) rows
5 fetch first 5 rows only;

EMPNO ENAME HIREDATE


---------- ---------- ---------
7698 BLAKE 01-MAY-81
7566 JONES 02-APR-81
7521 WARD 22-FEB-81
7499 ALLEN 20-FEB-81
7369 SMITH 17-DEC-80

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 141

73
12/18/2015

----------------------------------------------
| Id | Operation | Name | Rows |
----------------------------------------------
| 0 | SELECT STATEMENT | | 14 |
|* 1 | VIEW | | 14 |
| 2 | WINDOW SORT | | 14 |
| 3 | TABLE ACCESS FULL| EMP | 14 |
| 4 | SORT AGGREGATE | | 1 |
| 5 | INDEX FULL SCAN | PK_EMP | 14 |
----------------------------------------------

ugh
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 142

no percent pagination

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 143

74
12/18/2015

SQL> select empno, ename, hiredate


2 from emp
3 order by hiredate desc
4 offset 20 percent fetch
5 next 10 percent rows only;

offset 20 percent fetch next 10 percent rows only


*
ERROR at line 4:
ORA-00905: missing keyword

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 144

SQL> select empno, ename, hiredate


2 from emp
3 order by hiredate desc
4 offset
5 ( select 20/100*count(*) from emp) rows
6 fetch next 10 percent rows only;

EMPNO ENAME HIREDATE


---------- ---------- ---------
7934 MILLER 23-JAN-82
7902 FORD 03-DEC-81

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 145

75
12/18/2015

PL/SQL quirk

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 146

"Note that in real life,


you would use bind variables
instead of hard-coded literals"
- Tom Kyte,
Oracle Magazine
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 147

76
12/18/2015

SQL> variable x number


SQL> exec :x := 5

PL/SQL procedure successfully completed.

SQL> select empno, ename, hiredate


2 from emp
3 order by hiredate desc
4 fetch first :x rows only;

EMPNO ENAME HIREDATE


---------- ---------- ---------
7876 ADAMS 23-MAY-87
7788 SCOTT 19-APR-87
7934 MILLER 23-JAN-82
7900 JAMES 03-DEC-81
7902 FORD 03-DEC-81

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 148

SQL> declare
2 l_num number := 5;
3 begin
4 for i in (
5 select empno, ename, hiredate
6 from emp
7 order by hiredate desc
8 fetch first l_num rows only
9 )
10 loop
11 null;
12 end loop;
13 end;
14 /

ERROR at line 1:
ORA-03113: end-of-file on communication channel
Process ID: 26618
Session ID: 25 Serial number: 53023

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 149

77
12/18/2015

SQL> declare
2 l_num number := 5;
3 begin
4 for i in (
5 select empno, ename, hiredate
6 from emp
7 order by hiredate desc
8 fetch first cast(l_num as number) rows only
9 )
10 loop
11 null;
12 end loop;
13 end;
14 /

PL/SQL procedure successfully completed.

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 150

Favourite:

pattern matching

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 151

78
12/18/2015

median

top n

analytics ... since 8.1.6


moving average

etc

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 152

"analysis"

often

"patterns"

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 153

79
12/18/2015

real example

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 154

AML

anti-money laundering

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 156

80
12/18/2015

"Find 10 consecutive deposits in a


24 hour period, then
a withdrawal within three days of
the last deposit, at a different outlet"

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 157

ACCT TSTAMP WTHD_TSTAMP T AMT


---------- ------------------ ------------------ - ----------
54261 25/01/13 17:20:55 D 100
54261 25/01/13 17:56:58 D 165
54261 26/01/13 11:24:14 D 30
54261 26/01/13 11:47:53 D 45
54261 26/01/13 12:59:38 D 100
54261 26/01/13 13:26:04 D 80
54261 26/01/13 14:41:09 D 50
54261 26/01/13 14:53:12 D 50
54261 26/01/13 15:15:05 D 50
54261 26/01/13 15:51:17 D 50
54261 26/01/13 16:15:02 D 120
54261 26/01/13 16:36:51 D 100
54261 26/01/13 16:55:09 D 100
54261 26/01/13 18:07:17 26/01/13 18:07:17 W -500

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 158

81
12/18/2015

hard...

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 159

pattern matching

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 160

82
12/18/2015

SQL> select acct, tstamp, wthd_tstamp, txn_type, amt


2 from account_txns
3 MATCH_RECOGNIZE
4 (
5 partition by acct
6 order by tstamp
7 measures
8 dep.tstamp dep_tstamp,
9 wthd.tstamp wthd_tstamp
10
11 all rows per match
12 pattern ( dep{10,} wthd )
13 define
14 dep as
15 txn_type = 'D',
16 wthd as
17 txn_type = 'W'
18 and last(dep.tstamp)-first(dep.tstamp) < interval '1' day
19 and wthd.tstamp - last(dep.tstamp) < interval '3' day
20 and wthd.location != last(dep.location)
21 )

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 161

"What is the longest losing


streak for customers since
the start of the month"

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 162

83
12/18/2015

SQL> select acct, started_losing, finished_losing


2 from account_txns
3 MATCH_RECOGNIZE
4 (
5 partition by acct
6 order by tstamp
7 measures
8 tstamp as tstamp, outcome as outcome,
9 first(still_losing.tstamp) started_losing,
10 got_lucky.tstamp finished_losing
11 one row per match
12 pattern ( still_losing* got_lucky )
13 define
14 still_losing as outcome = 'L'
15 and still_losing.outcome =
16 first(still_losing.outcome),
17 got_lucky as outcome = 'W'
18 );

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 163

ACCT STARTED_LOSING FINISHED_LOSING


---------- ------------------- -------------------
66 01/02/2014 10:49:41 01/02/2014 16:30:01
66 01/02/2014 16:30:56 01/02/2014 17:23:06
66 01/02/2014 17:24:03 01/02/2014 18:11:32
66 01/02/2014 18:11:44 01/02/2014 19:13:04
66 01/02/2014 19:13:19 01/02/2014 19:44:04
66 01/02/2014 19:44:21 01/02/2014 20:15:33
184 02/02/2014 11:50:46 02/02/2014 12:23:49
184 02/02/2014 12:26:29 02/02/2014 12:56:57
184 02/02/2014 12:57:00 02/02/2014 13:19:51
184 02/02/2014 13:23:35 08/02/2014 14:24:35
280 01/02/2014 12:37:05 01/02/2014 14:36:18
280 01/02/2014 14:36:27 01/02/2014 14:49:43
280 01/02/2014 14:49:50 01/02/2014 15:47:21
280 01/02/2014 15:47:48 01/02/2014 23:30:12
280 02/02/2014 12:16:43 02/02/2014 13:15:52

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 164

84
12/18/2015

SQL> select acct, ceil(max(finished_losing-started_losing))


2 from account_txns
3 MATCH_RECOGNIZE
4 (
5 partition by acct
6 order by tstamp
7 measures
8 tstamp as tstamp, outcome as outcome,
9 first(still_losing.tstamp) started_losing,
10 got_lucky.tstamp finished_losing
11 one row per match
12 pattern ( still_losing* got_lucky )
13 define
14 still_losing as outcome = 'L'
15 and still_losing.outcome =
16 first(still_losing.outcome),
17 got_lucky as outcome = 'W'
18 )
19 group by acct
20 order by 1,2;
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 165

ACCT CEIL(MAX(FINISHED_LOSING-STARTED_LOSING))
---------- -----------------------------------------
66 3
184 7
280 2
416 1
814 3
908 5
1083 2
1142 3
1256 1
1260 1
1282 15
1676 2
1794 1
2085 12
2133 4
...

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 166

85
12/18/2015

Favourite:

join enhancements

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

11.2

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 168

86
12/18/2015

SQL> create table emp2 as


2 select * from emp;

Table created.

SQL> select *
2 from emp e,
3 emp2 e2,
4 dept d
5 where e.deptno = d.deptno(+)
6 and e2.deptno = d.deptno(+)
7 and e.empno = e2.empno
8 /

where e.deptno = d.deptno(+)


*
ERROR at line 5:
ORA-01417: a table may be outer joined to at most one other table

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 169

but ANSI syntax works …

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 170

87
12/18/2015

12c

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 171

SQL> select *
2 from emp e,
3 emp2 e2,
4 dept d
5 where e.deptno = d.deptno(+)
6 and e2.deptno = d.deptno(+)
7 and e.empno = e2.empno
8 /

EMPNO ENAME JOB MGR


---------- ---------- --------- ----------
7934 MILLER CLERK 7782
...

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 172

88
12/18/2015

correlated inline views

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 173

SQL> create table DEPT_BENEFITS as


2 select d.*, 10 benefits from dept d;

Table created.

SQL> insert into DEPT_BENEFITS


2 select d.*, 20 benefits from dept d;

4 rows created.

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 174

89
12/18/2015

SQL> select e.empno, e.deptno, d.benefits


2 from emp e,
3 DEPT_BENEFITS d
4 where e.deptno = d.deptno
5 order by 1,3;

EMPNO DEPTNO BENEFITS


---------- ---------- ----------
7369 20 10
7369 20 20
7499 30 10
7499 30 20
7521 30 10
7521 30 20
...
...

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 175

"benefits for each employee"

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 176

90
12/18/2015

SQL> select e.empno, d.deptno, b.benefits


2 from emp e,
3 ( select benefits
4 from DEPT_BENEFITS d
5 where d.deptno = e.deptno
6 ) b
7 order by 1,3;

where d.deptno = e.deptno


*
ERROR at line 5:
ORA-00904: "E"."DEPTNO": invalid identifier

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 177

CROSS APPLY

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 178

91
12/18/2015

SQL> select e.empno, e.deptno, b.benefits


2 from emp e
3 CROSS APPLY
4 ( select benefits
5 from DEPT_BENEFITS d
6 where d.deptno = e.deptno
7 ) b
8 order by 1,3;

EMPNO DEPTNO BENEFITS


---------- ---------- ----------
7369 20 10
7369 20 20
7499 30 10
...
...

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

"big deal"

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 180

92
12/18/2015

SQL> select e.empno, d.deptno, b.benefits


2 from emp e,
3 ( select benefits
4 from DEPT_BENEFITS d
5 where d.deptno = e.deptno
6 ) b
7
8 order by 1,3;

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 181

SQL> select e.empno, d.deptno, b.benefits


2 from emp e,
3 ( select benefits
4 from DEPT_BENEFITS d
5
6 ) b
7 where d.deptno = e.deptno
8 order by 1,3;

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 181

93
12/18/2015

"best benefit for each employee"

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 182

SQL> select e.empno, e.deptno, b.benefits


2 from emp e
3 CROSS APPLY
4 ( select benefits
5 from DEPT_BENEFITS d
6 where d.deptno = e.deptno
7 order by benefits desc
8 fetch first 1 rows only
9 ) b
10 order by 1,3;

EMPNO DEPTNO BENEFITS


---------- ---------- ----------
7369 20 20
7499 30 20
7521 30 20
7566 20 20
7654 30 20
...
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 183

94
12/18/2015

Favourite:

DML error logging

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 184

SQL> insert /*+ APPEND */ into MY_TABLE


2 select *
3 from MY_WHOPPING_GREAT_FAT_TABLE;

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 185

95
12/18/2015

SQL> insert /*+ APPEND */ into MY_TABLE


2 select *
3 from MY_WHOPPING_GREAT_FAT_TABLE;
MY_WHOPPING_GREAT_FAT_TABLE;

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 185

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 186

96
12/18/2015

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 187

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 188

97
12/18/2015

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 189

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 190

98
12/18/2015

SQL> insert /*+ APPEND */ into MY_TABLE


2 select *
3 from MY_WHOPPING_GREAT_FAT_TABLE;

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 191

SQL> insert /*+ APPEND */ into MY_TABLE


2 select *
3 from MY_WHOPPING_GREAT_FAT_TABLE;

Elapsed: 06:12:34.00

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 191

99
12/18/2015

SQL> insert /*+ APPEND */ into MY_TABLE


2 select *
3 from MY_WHOPPING_GREAT_FAT_TABLE;

Elapsed: 06:12:34.00

ERROR at line 1:
ORA-00001: unique constraint (DEMO.WHOPPER_PK) violated

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 192

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 192

100
12/18/2015

SQL> select count(*) from MY_TABLE;

COUNT(*)
----------
0

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 193

what we want

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 194

101
12/18/2015

keep successful rows

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 195

skip / bypass bad rows

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 196

102
12/18/2015

SQL> insert /*+ APPEND */ into MY_TABLE


2 select *
3 from MY_WHOPPING_GREAT_FAT_TABLE

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 197

SQL> insert /*+ APPEND */ into MY_TABLE


2 select *
3 from MY_WHOPPING_GREAT_FAT_TABLE
4 where "not a duplicate"
5 and "datatypes are ok"
6 and "foreign keys are ok"
7 and "check constraints are ok"

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 197

103
12/18/2015

SQL> exec DBMS_ERRLOG.CREATE_ERROR_LOG('EMP')

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 198

ERR$_EMP

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 199

104
12/18/2015

DBMS_ERRLOG.CREATE_ERROR_LOG (
dml_table_name IN VARCHAR2,
err_log_table_name IN VARCHAR2 := NULL,
err_log_table_owner IN VARCHAR2 := NULL,
...

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 200

SQL> desc ERR$_EMP


Name Null? Type
----------------------------- -------- ----------------
ORA_ERR_NUMBER$ NUMBER
ORA_ERR_MESG$ VARCHAR2(2000)
ORA_ERR_ROWID$ ROWID
ORA_ERR_OPTYP$ VARCHAR2(2)
ORA_ERR_TAG$ VARCHAR2(2000)
EMPNO VARCHAR2(4000)
ENAME VARCHAR2(4000)
JOB VARCHAR2(4000)
MGR VARCHAR2(4000)
HIREDATE VARCHAR2(4000)
SAL VARCHAR2(4000)
COMM VARCHAR2(4000)
DEPTNO VARCHAR2(4000)

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 201

105
12/18/2015

SQL> desc ERR$_EMP


Name Null? Type
----------------------------- -------- ----------------
ORA_ERR_NUMBER$ NUMBER
ORA_ERR_MESG$ VARCHAR2(2000)
ORA_ERR_ROWID$ ROWID
ORA_ERR_OPTYP$ VARCHAR2(2)
ORA_ERR_TAG$ VARCHAR2(2000)
EMPNO VARCHAR2(4000)
ENAME VARCHAR2(4000)
JOB VARCHAR2(4000)
MGR VARCHAR2(4000)
HIREDATE VARCHAR2(4000)
SAL VARCHAR2(4000)
COMM VARCHAR2(4000)
DEPTNO VARCHAR2(4000)

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 201

SQL> desc ERR$_EMP


Name Null? Type
----------------------------- -------- ----------------
ORA_ERR_NUMBER$ NUMBER
ORA_ERR_MESG$ VARCHAR2(2000)
ORA_ERR_ROWID$ ROWID
ORA_ERR_OPTYP$ VARCHAR2(2)
ORA_ERR_TAG$ VARCHAR2(2000)
EMPNO VARCHAR2(4000)
ENAME VARCHAR2(4000)
JOB VARCHAR2(4000)
MGR VARCHAR2(4000)
HIREDATE VARCHAR2(4000)
SAL VARCHAR2(4000)
COMM VARCHAR2(4000)
DEPTNO VARCHAR2(4000)

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 201

106
12/18/2015

SQL> desc ERR$_EMP


Name Null? Type
----------------------------- -------- ----------------
ORA_ERR_NUMBER$ NUMBER
ORA_ERR_MESG$ VARCHAR2(2000)
ORA_ERR_ROWID$ ROWID
ORA_ERR_OPTYP$ VARCHAR2(2)
ORA_ERR_TAG$ VARCHAR2(2000)
EMPNO VARCHAR2(4000)
ENAME VARCHAR2(4000)
JOB VARCHAR2(4000)
MGR VARCHAR2(4000)
HIREDATE VARCHAR2(4000)
SAL VARCHAR2(4000)
COMM VARCHAR2(4000)
DEPTNO VARCHAR2(4000)

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 201

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 202

107
12/18/2015

demo

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 203

SQL> select * from NEW_DATA;

EMPNO SAL DEPTNO


---------- ---------- ----------
1000 5000 20
100X 3550 10
2000 2500 50
7934 4000 20

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 204

108
12/18/2015

non-numeric
SQL> select * from NEW_DATA;

EMPNO SAL DEPTNO


---------- ---------- ----------
1000 5000 20
100X 3550 10
2000 2500 50
7934 4000 20

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 204

non-numeric
SQL> select * from NEW_DATA;

EMPNO SAL DEPTNO


---------- ---------- ----------
1000 5000 20
100X 3550 10
2000 2500 50
7934 4000 20

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 204

109
12/18/2015

no dept 50
non-numeric
SQL> select * from NEW_DATA;

EMPNO SAL DEPTNO


---------- ---------- ----------
1000 5000 20
100X 3550 10
2000 2500 50
7934 4000 20

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 204

no dept 50
non-numeric
SQL> select * from NEW_DATA;

EMPNO SAL DEPTNO


---------- ---------- ----------
1000 5000 20
100X 3550 10
2000 2500 50
7934 4000 20

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 204

110
12/18/2015

no dept 50
non-numeric
SQL> select * from NEW_DATA;

EMPNO SAL DEPTNO


---------- ---------- ----------
1000 5000 20
100X 3550 10
2000 2500 50
7934 4000 20

duplicate

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 204

SQL> insert into EMP (empno,sal,deptno)


2 select empno,sal,deptno
3 from NEW_DATA

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 205

111
12/18/2015

SQL> exec dbms_errlog.create_error_log( 'EMP' );

PL/SQL procedure successfully completed.

SQL> insert into EMP (empno,sal,deptno)


2 select empno,sal,deptno
3 from NEW_DATA

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 205

SQL> exec dbms_errlog.create_error_log( 'EMP' );

PL/SQL procedure successfully completed.

SQL> insert into EMP (empno,sal,deptno)


2 select empno,sal,deptno
3 from NEW_DATA
4 LOG ERRORS REJECT LIMIT UNLIMITED;

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 205

112
12/18/2015

SQL> exec dbms_errlog.create_error_log( 'EMP' );

PL/SQL procedure successfully completed.

SQL> insert into EMP (empno,sal,deptno)


2 select empno,sal,deptno
3 from NEW_DATA
4 LOG ERRORS REJECT LIMIT 50
UNLIMITED;

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 205

SQL> exec dbms_errlog.create_error_log( 'EMP' );

PL/SQL procedure successfully completed.

SQL> insert into EMP (empno,sal,deptno)


2 select empno,sal,deptno
3 from NEW_DATA
4 LOG ERRORS REJECT LIMIT 50
UNLIMITED;

1 row created.

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 205

113
12/18/2015

SQL> select ORA_ERR_OPTYP$ op, ORA_ERR_MESG$, EMPNO


2 from ERR$_EMP

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 206

SQL> select ORA_ERR_OPTYP$ op, ORA_ERR_MESG$, EMPNO


2 from ERR$_EMP

OP ORA_ERR_MESG$ EMPNO
-- ------------------------------------------------------------ -----
I ORA-01722: invalid number 100X
I ORA-02291: integrity constraint (SCOTT.FK_DEPTNO) violated 2000
I ORA-00001: unique constraint (SCOTT.PK_EMP) violated 7934

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 206

114
12/18/2015

favourite:

query blocks

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 207

C# application

208 Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

115
12/18/2015

209 Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

C#, C++

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 210

116
12/18/2015

C#, C++

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 210

C#, C++

PL/SQL

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 211

117
12/18/2015

No comments

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 212

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 213

118
12/18/2015

"C# is self-documenting"

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 214

good code in any language ...

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 215

119
12/18/2015

... should self document

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 216

SQL is no different

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 217

120
12/18/2015

select emp.*
from emp,
( select trunc(hiredate,'YYYY'), max(empno) empno
from emp
where empno > 0
group by trunc(hiredate,'YYYY') ) x,
( select deptno, avg(sal)
from emp
group by deptno ) y
where x.empno = emp.empno
and y.deptno = emp.deptno

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

Explain plan

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

121
12/18/2015

Id | Operation | Name |
----------------------------------------------|
0 | SELECT STATEMENT | |
1 | HASH JOIN | |
2 | TABLE ACCESS BY INDEX ROWID | EMP |
3 | NESTED LOOPS | |
4 | VIEW | |
5 | SORT GROUP BY | |
6 | TABLE ACCESS BY INDEX ROWID| EMP |
7 | INDEX FULL SCAN | E2 |
8 | INDEX RANGE SCAN | E1 |
9 | VIEW | |
10 | SORT GROUP BY | |
11 | TABLE ACCESS BY INDEX ROWID | EMP |
12 | INDEX RANGE SCAN | E2 |

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

?
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

122
12/18/2015

explain plan for


select emp.*
from emp,
( select /*+ QB_NAME(lastemp) */
trunc(hiredate,'YYYY'), max(empno) empno
from emp
where empno > 0
group by trunc(hiredate,'YYYY') ) x,
( select /*+ QB_NAME(avgsal) */
deptno, avg(sal)
from emp
group by deptno ) y
where x.empno = emp.empno
and y.deptno = emp.deptno

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

explain plan for


select emp.*
from emp,
( select /*+ QB_NAME(lastemp) */
trunc(hiredate,'YYYY'), max(empno) empno
from emp
where empno > 0
group by trunc(hiredate,'YYYY') ) x,
( select /*+ QB_NAME(avgsal) */
deptno, avg(sal)
from emp
group by deptno ) y
where x.empno = emp.empno
and y.deptno = emp.deptno

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

123
12/18/2015

explain plan for


select emp.*
from emp,
( select /*+ QB_NAME(lastemp) */
trunc(hiredate,'YYYY'), max(empno) empno
from emp
where empno > 0
group by trunc(hiredate,'YYYY') ) x,
( select /*+ QB_NAME(avgsal) */
deptno, avg(sal)
from emp
group by deptno ) y
where x.empno = emp.empno
and y.deptno = emp.deptno

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

Id | Operation | Name |
----------------------------------------------|
0 | SELECT STATEMENT | |
1 | HASH JOIN | |
2 | TABLE ACCESS BY INDEX ROWID | EMP |
3 | NESTED LOOPS | |
4 | VIEW | |
5 | SORT GROUP BY | |
6 | TABLE ACCESS BY INDEX ROWID| EMP |
7 | INDEX FULL SCAN | E2 |
8 | INDEX RANGE SCAN | E1 |
9 | VIEW | |
10 | SORT GROUP BY | |
11 | TABLE ACCESS BY INDEX ROWID | EMP |
12 | INDEX RANGE SCAN | E2 |

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

124
12/18/2015

Id | Operation | Name |
----------------------------------------------|
0 | SELECT STATEMENT | |
1 | HASH JOIN | |
2 | TABLE ACCESS BY INDEX ROWID | EMP |
3 | Query
NESTED LOOPS
Block | by operation
Name / Alias (identified | id):
4 | ---------------------------------------------------------
VIEW | |
5 | 1 SORT
- SEL$1
GROUP BY | |
6 | 3 -TABLE
AVGSAL
ACCESS/ Y@SEL$1
BY INDEX ROWID| EMP |
7 | 4 - INDEX
AVGSALFULL SCAN | E2 |
8 | 5 - AVGSAL
INDEX RANGE SCAN/ EMP@AVGSAL | E1 |
6 - SEL$1 / EMP@SEL$1
9 | VIEW | |
7 - LASTEMP / X@SEL$1
10 | SORT GROUP BY
8 - LASTEMP
| |
11 | TABLE ACCESS
9 - LASTEMP BY INDEX ROWID
/ EMP@LASTEMP | EMP |
12 | INDEX RANGE SCAN | E2 |

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

query PLAN_TABLE

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

125
12/18/2015

Id | Operation | Name | Query Block


----------------------------------------------|--------------
0 | SELECT STATEMENT | |
1 | HASH JOIN | | SEL$4ADCCA61
2 | TABLE ACCESS BY INDEX ROWID | EMP | SEL$4ADCCA61
3 | NESTED LOOPS | |
4 | VIEW | | AVGSAL
5 | SORT GROUP BY | | AVGSAL
6 | TABLE ACCESS BY INDEX ROWID| EMP | AVGSAL
7 | INDEX FULL SCAN | E2 | AVGSAL
8 | INDEX RANGE SCAN | E1 | SEL$4ADCCA61
9 | VIEW | | LASTEMP
10 | SORT GROUP BY | | LASTEMP
11 | TABLE ACCESS BY INDEX ROWID | EMP | LASTEMP
12 | INDEX RANGE SCAN | E2 | LASTEMP

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

Runtime statistics as well

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

126
12/18/2015

SQL> select /*+ gather_plan_statistics */


2 emp.*
3 from emp,
4 ( select /*+ QB_NAME(lastemp) */
5 trunc(hiredate,'YYYY'), max(empno) empno
6 from emp
7 where empno > 0
8 group by trunc(hiredate,'YYYY') ) x,
9 ( select /*+ QB_NAME(avgsal) */
10 deptno, avg(sal)
11 from emp
12 group by deptno ) y
13 where x.empno = emp.empno
14 and y.deptno = emp.deptno
15 /
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

SQL> select * from


2 table(dbms_xplan.display_cursor(null,null,'IOSTATS LAST +ALIAS'));

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

127
12/18/2015

SQL> select * from


2 table(dbms_xplan.display_cursor(null,null,'IOSTATS LAST +ALIAS'));

-----------------------------------------------------------------------------------
|Id | Operation | Name |Starts | E-Rows | A-Rows |A-Time | Buffers |
-----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 4 |00:00.01 | 21 |
| 1 | HASH JOIN | | 1 | 13 | 4 |00:00.01 | 21 |
| 2 | HASH JOIN | | 1 | 14 | 14 |00:00.01 | 14 |
| 3 | VIEW | | 1 | 3 | 3 |00:00.01 | 7 |
| 4 | HASH GROUP BY | | 1 | 3 | 3 |00:00.01 | 7 |
| 5 | TABLE ACCESS FULL| EMP | 1 | 14 | 14 |00:00.01 | 7 |
| 6 | TABLE ACCESS FULL | EMP | 1 | 14 | 14 |00:00.01 | 7 |
| 7 | VIEW | | 1 | 13 | 4 |00:00.01 | 7 |
| 8 | HASH GROUP BY | | 1 | 13 | 4 |00:00.01 | 7 |
| 9 | TABLE ACCESS FULL | EMP | 1 | 14 | 14 |00:00.01 | 7 |
-----------------------------------------------------------------------------------

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

SQL> select * from


2 table(dbms_xplan.display_cursor(null,null,'IOSTATS LAST +ALIAS'));

-----------------------------------------------------------------------------------
|Id | Operation | Name |Starts | E-Rows | A-Rows |A-Time | Buffers |
-----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 4 |00:00.01 | 21 |
| 1 | HASH JOIN | | 1 | 13 | 4 |00:00.01 | 21 |
| 2 | HASH JOINBlock Name |/ Object
Query | 1 | (identified
Alias 14 | 14
by |00:00.01
operation| id): 14 |
| 3 | VIEW | | 1 | 3 | 3 |00:00.01 | 7 |
-------------------------------------------------------------
| 4 | HASH GROUP BY | | 1 | 3 | 3 |00:00.01 | 7 |
| 5 |
1 - SEL$1
TABLE ACCESS FULL| EMP | 1 | 14 | 14 |00:00.01 | 7 |
| 6 | 3 ACCESS
TABLE - AVGSALFULL |/ EMP
Y@SEL$1
| 1 | 14 | 14 |00:00.01 | 7 |
| 7 | VIEW 4 - AVGSAL | | 1 | 13 | 4 |00:00.01 | 7 |
| 8 | HASH5GROUP
- AVGSAL
BY |/ EMP@AVGSAL
| 1 | 13 | 4 |00:00.01 | 7 |
| 9 | 6 -ACCESS
TABLE SEL$1FULL |/ EMP
EMP@SEL$1
| 1 | 14 | 14 |00:00.01 | 7 |
-----------------------------------------------------------------------------------
7 - LASTEMP / X@SEL$1
8 - LASTEMP
9 - LASTEMP / EMP@LASTEMP

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

128
12/18/2015

SQL> alter session set


2 events = '10053 trace name context forever, level 1';

Session altered.

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 230

**************************
Query transformations (QT)
**************************
CBQT: Validity checks passed for 7jpzpr2475cqw.
CSE: Sub-expression elimination in query block SEL$1 (#0)

*************************
Common Subexpression elimination (CSE)
*************************
CSE: CSE not performed on query block LAST_EMP(#0).
CSE: Sub-expression elimination in query block AVG_SAL (#0)
CSE: CSE not performed on query block AV_SAL (#0).
CSE: CSE not performed on query block SEL$1 (#0).

***************************
Order-by elimination (OBYE)
***************************
OBYE: Considering Order-by Elimination from view SEL$1 (#0)

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 231

129
12/18/2015

assist with hints

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 232

select
/*+ QB_NAME(top)
INDEX(@yr_hire emp (empno))
FULL(@av_sal emp)
*/
emp.*
from emp,
( select /*+ QB_NAME(YR_HIRE) */
trunc(hiredate,'YYYY'), max(empno) empno
from emp
where empno > 0
group by trunc(hiredate,'YYYY') ) x,
( select /*+ QB_NAME(AV_SAL) */
deptno, avg(sal)
from emp
group by deptno ) y
where x.empno = emp.empno
and y.deptno = emp.deptno

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 233

130
12/18/2015

Help the next person

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

It’s probably you

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

131
12/18/2015

Favourite:

subquery factoring

part 2
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 236

first principles

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 237

132
12/18/2015

SQL> select rpad(' ',level)||ename,


2 from emp
3 start with mgr is null
4 connect by prior empno = mgr

ENAME
---------------------------
KING
BLAKE
JAMES
ALLEN
WARD
CLARK
MILLER

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 238

SQL> select empno, ename, mgr


2 from emp
3 where mgr is null;

EMPNO ENAME MGR


---------- -------------------- ----------
7839 KING

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 239

133
12/18/2015

SQL> select e2.empno, e2.ename, e2.mgr


2 from emp e2,
3 ( select empno, mgr
4 from emp
5 where mgr is null ) inner
6 where e2.mgr = inner.empno;

EMPNO ENAME MGR


---------- -------------------- ----------
7566 JONES 7839
7698 BLAKE 7839
7782 CLARK 7839

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 240

SQL> select e3.empno, e3.ename, e3.mgr


2 from emp e3,
3 ( select e2.empno, e2.ename, e2.mgr
4 from emp e2,
5 ( select empno, mgr
6 from emp
7 where mgr is null ) inner
8 where e2.mgr = inner.empno ) inner
9 where e3.mgr = inner.empno;

EMPNO ENAME MGR


---------- -------------------- ----------
7902 FORD 7566
7788 SCOTT 7566
7900 JAMES 7698
7844 TURNER 7698
7654 MARTIN 7698
7521 WARD 7698
7934 MILLER 7782
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 241

134
12/18/2015

SQL> select e4.empno, e4.ename, e4.mgr


2 from emp e4,
3 ( select e3.empno, e3.ename, e3.mgr
4 from emp e3,
5 ( select e2.empno, e2.ename, e2.mgr
6 from emp e2,
7 ( select empno, mgr
8 from emp
9 where mgr is null ) inner
10 where e2.mgr = inner.empno ) inner
11 where e3.mgr = inner.empno ) inner
12 where e4.mgr = inner.empno;

EMPNO ENAME MGR


---------- -------------------- ----------
7876 ADAMS 7788

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 242

SQL> select e4.empno, e4.ename, e4.mgr


2 from emp e4,
3 ( select e3.empno, e3.ename, e3.mgr
4 from emp e3,
5 ( select e2.empno, e2.ename, e2.mgr
6 from emp e2,
7 ( select empno, mgr
8 from emp
9 where mgr is null ) inner
10 where e2.mgr = inner.empno ) inner
11 where e3.mgr = inner.empno ) inner
12 where e4.mgr = inner.empno;

EMPNO ENAME MGR


---------- -------------------- ----------
7876 ADAMS 7788

recursive...
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 242

135
12/18/2015

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 243

WITH can be recursive

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 244

136
12/18/2015

SQL> with EACH_LEVEL (empno, name, mgr) as

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 245

SQL> with EACH_LEVEL (empno, name, mgr) as


2 ( --
3 -- start with
4 --
5 select empno, ename, mgr
6 from emp
7 where mgr is null

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 245

137
12/18/2015

SQL> with EACH_LEVEL (empno, name, mgr) as


2 ( --
3 -- start with
4 --
5 select empno, ename, mgr
6 from emp
7 where mgr is null
8 --
9 -- connect by
10 --
11 union all
12 select emp.empno, emp.ename, emp.mgr
13 from emp, EACH_LEVEL
14 where emp.mgr = each_level.empno

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 245

SQL> with EACH_LEVEL (empno, name, mgr) as


2 ( --
3 -- start with
4 --
5 select empno, ename, mgr
6 from emp
7 where mgr is null
8 --
9 -- connect by
10 --
11 union all
12 select emp.empno, emp.ename, emp.mgr
13 from emp, EACH_LEVEL
14 where emp.mgr = each_level.empno
15 )
16 select *
17 from each_level;

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 245

138
12/18/2015

EMPNO NAME MGR


---------- --------------- ----------
7839 KING
7566 JONES 7839
7698 BLAKE 7839
7782 CLARK 7839
7499 ALLEN 7698
7521 WARD 7698
7654 MARTIN 7698
7788 SCOTT 7566
7844 TURNER 7698
7900 JAMES 7698
7902 FORD 7566
7934 MILLER 7782
7369 SMITH 7902
7876 ADAMS 7788

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 246

two part structure

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 247

139
12/18/2015

with RECURSIVE_WITH (c1,c2,c3) as


(
<starting/entry point>

union all

<recursive relationship>

)
select ...
from RECURSIVE_WITH

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 248

you control pseudo-functions

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 249

140
12/18/2015

SQL> with each_level (empno, name, mgr, rlevel) as


2 ( select empno, ename, mgr, 1 rlevel
3 from emp
4 where mgr is null
5 union all
6 select emp.empno, emp.ename, emp.mgr, rlevel+1
7 from emp, each_level
8 where emp.mgr = each_level.empno
9 )
10 select * from each_level;

EMPNO NAME MGR RLEVEL


---------- --------------- ---------- ----------
7839 KING 1
7566 JONES 7839 2
7698 BLAKE 7839 2
7782 CLARK 7839 2
7499 ALLEN 7698 3
<etc>
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 250

SQL> with each_level (empno, name, mgr, level) as


2 ( select empno, ename, mgr, 1 level
3 from emp
4 where mgr is null
5 union all
6 select emp.empno, emp.ename, emp.mgr, level+1
7 from emp, each_level
8 where emp.mgr = each_level.empno
9 )
10 select empno, name, mgr, level from each_level;

with each_level (empno, name, mgr, level) as


*
ERROR at line 1:
ORA-00904: : invalid identifier

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 251

141
12/18/2015

SQL> with each_level (empno, name, mgr, rlevel) as


2 ( select empno, ename, mgr, 1 rlevel
3 from emp
4 where mgr is null
5 union all
6 select emp.empno, emp.ename, emp.mgr, rlevel+1
7 from emp, each_level
8 where emp.mgr = each_level.empno
9 )
10 select empno, name, mgr, rlevel as "LEVEL"
11 from each_level;

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 252

SQL> with each_level (empno, name, mgr, padding) as


2 ( select empno, ename, mgr, '' padding
3 from emp
4 where mgr is null
5 union all
6 select e.empno, e.ename, e.mgr, padding || ' '
7 from emp e, each_level
8 where e.mgr = each_level.empno
9 )

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 253

142
12/18/2015

SQL> with each_level (empno, name, mgr, padding) as


2 ( select empno, ename, mgr, '' padding
3 from emp
4 where mgr is null
5 union all
6 select e.empno, e.ename, e.mgr, padding || ' '
7 from emp e, each_level
8 where e.mgr = each_level.empno
9 )
10 select empno, padding||name name
11 from each_level;

ERROR:
ORA-01489: result of string concatenation is too long

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 253

SQL> with each_level (empno, name, mgr, padding) as


2 ( select empno, ename, mgr,
3 cast('' as varchar2(100)) padding
4 from emp
5 where mgr is null
6 union all
7 select e.empno, e.ename, e.mgr, padding || ' '
8 from emp e, each_level
9 where e.mgr = each_level.empno
10 )
11 select empno, padding||name name
12 from each_level;

EMPNO NAME
---------- --------------------------------
7839 KING
7566 JONES
...
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 254

143
12/18/2015

SQL> with each_level (empno, name) as


2 ( select empno, ename from emp
3 where mgr is null
4 union all
5 select e.empno,
6 each_level.name||'-'||e.ename
7 from emp e, each_level
8 where e.mgr = each_level.empno
9 )
10 select empno, name from each_level;

EMPNO NAME
---------- --------------------------------
7839 KING
7566 KING-JONES
7698 KING-BLAKE
7782 KING-CLARK
7499 KING-BLAKE-ALLEN
7521 KING-BLAKE-WARD
<etc>
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 255

some nice touches...

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 256

144
12/18/2015

SQL> with each_level (empno, name, hiredate, mgr) as


2 ( ... )
9 SEARCH BREADTH FIRST BY HIREDATE SET IDX
10 select name, hiredate, idx from each_level;

NAME HIREDATE IDX


-------------------------------- --------- ----------
KING 17-NOV-81 1
KING-JONES 02-APR-81 2
KING-BLAKE 01-MAY-81 3
KING-CLARK 09-JUN-81 4
KING-BLAKE-ALLEN 20-FEB-81 5
KING-BLAKE-WARD 22-FEB-81 6
[snip]
KING-JONES-FORD-SMITH 17-DEC-80 13
KING-JONES-SCOTT-ADAMS 23-MAY-87 14

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 257

SQL> with each_level (empno, name, hiredate, mgr) as


2 ( ... )
9 SEARCH DEPTH FIRST BY HIREDATE SET IDX
10 select name, hiredate, idx from each_level;

NAME HIREDATE IDX


-------------------------------- --------- ----------
KING 17-NOV-81 1
KING-JONES 02-APR-81 2
KING-JONES-FORD 03-DEC-81 3
KING-JONES-FORD-SMITH 17-DEC-80 4
KING-JONES-SCOTT 19-APR-87 5
KING-JONES-SCOTT-ADAMS 23-MAY-87 6
KING-BLAKE 01-MAY-81 7
KING-BLAKE-ALLEN 20-FEB-81 8
etc

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 258

145
12/18/2015

get used to it .....

ANSI

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 259

Favourite:

sql transposition

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 260

146
12/18/2015

rows to columns, colums to rows

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 261

"I need sales by product


for each quarter....now"

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 262

147
12/18/2015

SQL> select product,


2 trunc(txn_date,'Q') mth, sum(quantity) total
3 from SALES
4 group by product,trunc(txn_date,'Q')
5 order by 1,2;

PRODUCT MTH TOTAL


-------------------- --- ----------
CHAINSAW JAN 251473
CHAINSAW APR 254830
CHAINSAW JUL 251994
CHAINSAW OCT 243748
HAMMER JAN 249889
HAMMER APR 256566
HAMMER JUL 252992
HAMMER OCT 249104
SCREW DRIVER JAN 245988
SCREW DRIVER APR 249219
SCREW DRIVER JUL 252128

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 263

"That’s junk...surely you know


I wanted it ACROSS the page"

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 264

148
12/18/2015

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 265

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 266

149
12/18/2015

PIVOT clause

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 267

SQL> select *
2 from (select product,
3 trunc(txn_date,'Q') mth,
4 quantity
5 from sales )
6 pivot( sum(quantity) for mth in
7 ( 'JAN','APR','JUL','OCT' ) )
11 order by 1
12 /

PRODUCT 'JAN' 'APR' 'JUL' 'OCT'


-------------------- ---------- ---------- ---------- ----------
CHAINSAW 251473 254830 251994 243748
HAMMER 249889 256566 252992 249104
SCREW DRIVER 245988 249219 252128 244721
SPADE 242434 254090 259613 248428
WHEEL BARROW 243899 249327 252296 254137

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 268

150
12/18/2015

"nah...make it go DOWN the page

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 269

SQL> create table PIVOTED_SALES as select *


2 from (select product,
3 trunc(txn_date,'Q') mth,
4 quantity
5 from sales )
6 pivot( sum(quantity) for mth in
7 ( 'JAN',
8 'APR',
9 'JUL',
10 'OCT') )
11 order by 1
12 /

Table created.

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 270

151
12/18/2015

UNPIVOT clause

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 271

SQL> desc PIVOTED_SALES

Name Null? Type


----------------------------- -------- -------------
PRODUCT VARCHAR2(20)
Q1 NUMBER
Q2 NUMBER
Q3 NUMBER
Q4 NUMBER

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 272

152
12/18/2015

SQL> select *
2 from PIVOTED_SALES
3 UNPIVOT
4 ( quantity for quarter in (Q1,Q2,Q3,Q4) )
5 /

PRODUCT QUARTER QUANTITY


-------------------- ------- ----------
CHAINSAW Q1 251473
CHAINSAW Q2 254830
CHAINSAW Q3 251994
CHAINSAW Q4 243748
HAMMER Q1 249889
HAMMER Q2 256566
HAMMER Q3 252992
HAMMER Q4 249104
SCREW DRIVER Q1 245988
SCREW DRIVER Q2 249219
SCREW DRIVER Q3 252128
...

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 273

SQL> select * column values


2 from PIVOTED_SALES become "quantity"
3 UNPIVOT
4 ( quantity for quarter in (Q1,Q2,Q3,Q4) )
5 /

PRODUCT QUARTER QUANTITY


-------------------- ------- ----------
CHAINSAW Q1 251473
CHAINSAW Q2 254830
CHAINSAW Q3 251994
CHAINSAW Q4 243748
HAMMER Q1 249889
HAMMER Q2 256566
HAMMER Q3 252992
HAMMER Q4 249104
SCREW DRIVER Q1 245988
SCREW DRIVER Q2 249219
SCREW DRIVER Q3 252128
...

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 273

153
12/18/2015

SQL> select * column values


2 from PIVOTED_SALES become "quantity"
3 UNPIVOT
4 ( quantity for quarter in (Q1,Q2,Q3,Q4) )
5 /

PRODUCT QUARTER QUANTITY


-------------------- ------- ----------
CHAINSAW Q1 251473
CHAINSAW Q2 254830
CHAINSAW Q3 251994
CHAINSAW Q4 243748
HAMMER Q1 249889
HAMMER Q2 256566
HAMMER Q3 252992
HAMMER Q4 249104
SCREW DRIVER Q1 245988
SCREW DRIVER Q2 249219
SCREW DRIVER Q3 252128
...

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 273

SQL> select * column values


2 from PIVOTED_SALES become "quantity"
3 UNPIVOT
4 ( quantity for quarter in (Q1,Q2,Q3,Q4) )
5 /

PRODUCT QUARTER QUANTITY column names


-------------------- ------- ----------
CHAINSAW Q1 251473 become "quarter"
CHAINSAW Q2 254830
CHAINSAW Q3 251994
CHAINSAW Q4 243748
HAMMER Q1 249889
HAMMER Q2 256566
HAMMER Q3 252992
HAMMER Q4 249104
SCREW DRIVER Q1 245988
SCREW DRIVER Q2 249219
SCREW DRIVER Q3 252128
...

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 273

154
12/18/2015

elements must be known in advance

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 274

Wrap up

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 275

155
12/18/2015

lots not covered today

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 276

why talk about SQL


(part 3)

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 277

156
12/18/2015

Life is too short

(look away now if you are squeamish)

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 278

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 279

157
12/18/2015

import java.sql.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.accessibility.*;
import com.sun.java.accessibility.util.*;

public AssistiveExample extends JPanel


implements MouseMotionListener, ActionListener,
GUIInitializedListener {

Timer timer;
static JFrame frame;

JLabel nameLabel = new JLabel();


JLabel descriptionLabel = new JLabel();
JLabel tableLabel = new JLabel();

JCheckBox selectionCheckBox = new JCheckBox("Selection",


false);
JCheckBox textCheckBox = new JCheckBox("Text", false);
JCheckBox valueCheckBox = new JCheckBox("Value", false);
JCheckBox componentCheckBox = new JCheckBox("Component",
false);
JCheckBox actionCheckBox = new JCheckBox("Action", false);
JCheckBox hypertextCheckBox = new JCheckBox("Hypertext",
false);
JCheckBox iconCheckBox = new JCheckBox("Icon", false);
JCheckBox tableCheckBox = new JCheckBox("Table", false);
JCheckBox editableTextCheckBox = new JCheckBox("EditableText",
false);
JLabel classLabel = new JLabel();
JLabel parentLabel = new JLabel();
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 280
JLabel relationLabel = new JLabel();
JButton performAction = new JButton("Perform Action");

try{
if(stmt!=null)
stmt.close();
}catch(SQLException se2){
}// nothing we can do
try{
if(conn!=null)
conn.close();
}catch(SQLException se){
se.printStackTrace();
}//end finally try
}//end try
System.out.println("Goodbye!");
}
}

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 280

158
12/18/2015

SQL is faster

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 281

SQL is easier

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 282

159
12/18/2015

SQL is more exciting

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 283

Connor McDonald

286 Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

160
12/18/2015

ORA-03113

286 Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

Creative Commons Image Resources

https://commons.wikimedia.org/wiki/File:Horse_Race_Finish_Line_(11888565543).jpg
https://pixabay.com/en/iphone-iphone-6-apple-flat-762044/
https://pixabay.com/en/curve-return-pass-road-384406/
https://pixabay.com/en/high-five-figure-man-blue-150911/
https://pixabay.com/en/joker-jester-card-playing-card-164030/
https://commons.wikimedia.org/wiki/File:2008-08-19_Flat_tire.jpg
https://upload.wikimedia.org/wikipedia/commons/4/4d/3DCrystal_ball.png

Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |

161

S-ar putea să vă placă și