SlideShare una empresa de Scribd logo
1 de 374
NOTE
itty bitty fonts in this
presentation

SQL> exec sample_font

Can you read this ?
1
Connor McDonald
OracleDBA
co.uk
2
3
bio slide

4
Connor McDonald
Connor McDonald
Connor McDonald
Connor McDonald
6
"why bother?"

7
2013

12c

2014

12.1.2

2015

2016

2017

2018

2019

2020

2021

12.2
12c
desupported

management
visibility

"maybe"
9
"why bother?"
(part 2)

10
don’t reinvent
there's a lot in 12c !

13
but not widely advertised

14
multi- tenant

15
multi- tenant

16
some cool things....

17
some not so cool things....

18
first impressions

19
tough for "home" exploring

20
SQL> create user DEV_TESTING
2
identified by MYPASS;
create user DEV_TESTING identified by MYPASS
*
ERROR at line 1:
ORA-65096: invalid common user or role name

?
21
be patient

22
23
or let someone else do it

24
http://www.oracle.com/technetwork/community/developer-vm/index.html

25
26
"Feature:"
total recall

27
"hold on !"

28
11g feature !

29
why talk about it ?

31
we've all done it...

32
site to site to site...

33
auditing row changes

34
SQL> desc T

Name
----------------------------OWNER
OBJECT_NAME

Null?
-------NOT NULL
NOT NULL

Type
------------VARCHAR2(30)
VARCHAR2(30)

SQL> desc T_AUDIT
Name
----------------------------AUDIT_DATE
AUDIT_ACTION
OWNER
OBJECT_NAME

Null?
Type
-------- -------------DATE
CHAR(1)
NOT NULL VARCHAR2(30)
NOT NULL VARCHAR2(30)

35
SQL>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

create or replace
trigger AUDIT_TRG
after insert or update or delete on T
for each row
declare
v_action varchar2(1) := case when updating then 'U'
when deleting then 'D' else 'I' end;
begin
if updating or inserting then
insert into T_AUDIT
values (sysdate
,v_action
,:new.owner
,:new.object_name);
else
insert into T_AUDIT
values (sysdate
,v_action
,:old.owner
,:old.object_name);
end if;
end;
/

Trigger created.
36
works but slow...

37
SQL>
2
3
4

insert
select
from
where

into T
owner, object_name
all_objects
rownum <= 10000;

10000 rows created.

38
SQL> insert
2 select
3 from
insert where
4 into T

into T
owner, object_name
all_objects
rownum <= 10000;

select owner, object_name
from
all_objects
10000 rownum <= 10000
rows created.
where
call
count
------- -----Parse
1
Execute
1
Fetch
0
------- -----total
2

cpu
elapsed
disk
query
current
------- ---------- -------- --------- ---------0.01
0.00
0
0
0
3.10
3.05
88
123
10642
0.00
0.00
0
0
0
------- ---------- -------- --------- ---------3.12
3.06
88
123
10642

rows
---------0
10000
0
---------10000

INSERT INTO T_AUDIT
VALUES (SYSDATE ,:B3 ,:B1 ,:B2 )

call
count
------- -----Parse
1
Execute 10000
Fetch
0
------- -----total
10001

cpu
elapsed
disk
query
current
------- ---------- -------- --------- ---------0.00
0.00
0
0
0
0.79
0.97
2
109
10845
0.00
0.00
0
0
0
------- ---------- -------- --------- ---------0.79
0.97
2
109
10845

rows
---------0
10000
0
---------10000
38
if you were dilligent

39
bulk binding
see later

40
11g

41
compound triggers

42
a better, faster, robust version ...

49
... total recall
11g

50
SQL> create tablespace SPACE_FOR_ARCHIVE
2 datafile 'C:ORACLEDB11ARCH_SPACE.DBF'
3 size 100M;
Tablespace created.

51
SQL> CREATE FLASHBACK ARCHIVE longterm
2 TABLESPACE space_for_archive
3 RETENTION 1 YEAR;
Flashback archive created.

52
SQL> ALTER TABLE EMP FLASHBACK ARCHIVE LONGTERM;
Table altered.
[lots of DML]

53
SQL> select * from EMP;
-------------------------------------------------| Id | Operation
| Name | Rows | Bytes |
-------------------------------------------------|
0 | SELECT STATEMENT |
|
14 |
518 |
|
1 | TABLE ACCESS FULL| EMP |
14 |
518 |
--------------------------------------------------

54
SQL> select * from EMP
2
AS OF TIMESTAMP SYSDATE-3;
-------------------------------------------------| Id | Operation
| Name | Rows | Bytes |
-------------------------------------------------|
0 | SELECT STATEMENT |
|
14 |
518 |
|
1 | TABLE ACCESS FULL| EMP |
14 |
518 |
--------------------------------------------------

55
[after DML and time passing]

SQL> select * from EMP
2
AS OF TIMESTAMP SYSDATE-3;
----------------------------------------------------------------| Id | Operation
| Name
| Rows |
----------------------------------------------------------------|
0 | SELECT STATEMENT
|
|
446 |
|
1 | VIEW
|
|
446 |
|
2 |
UNION-ALL
|
|
|
|* 3 |
FILTER
|
|
|
|
4 |
PARTITION RANGE ITERATOR|
|
445 |
|* 5 |
TABLE ACCESS FULL
| SYS_FBA_HIST_69539 |
445 |
|* 6 |
FILTER
|
|
|
|* 7 |
HASH JOIN OUTER
|
|
1 |
|* 8 |
TABLE ACCESS FULL
| EMP
|
1 |
|* 9 |
TABLE ACCESS FULL
| SYS_FBA_TCRV_69539 |
14 |
------------------------------------------------------------------

56
SQL> select table_name
2 from
user_tables
3 /
TABLE_NAME
--------------------------SYS_FBA_HIST_71036
SYS_FBA_TCRV_71036
SYS_FBA_DDL_COLMAP_71036
EMP

57
but can also be your audit !

58
SQL> alter table EMP add
2
LAST_MOD timestamp default systimestamp;
SQL> update EMP
2 set
sal = sal*10
3 where empno = 7369;

SQL> delete from EMP
2 where empno = 7934;
SQL> update EMP
2 set
job = 'SALES'
3 where ename = 'SMITH';
SQL> update EMP
2 set
comm = 1000
3 where empno = 7369;
SQL> commit;
59
SQL>
2
3
4
5
6
7
8

select empno, ename, job, sal, comm,
nvl(VERSIONS_STARTTIME,LAST_MOD) TS
,nvl(VERSIONS_OPERATION,'I') op
from EMP
versions between timestamp
timestamp '2014-02-11 20:12:00' and
systimestamp
order by empno;

EMPNO
---------7369
7369
7499
7521
7566
...
7900
7902
7934
7934

ENAME
---------SMITH
SMITH
ALLEN
WARD
JONES

JOB
SAL
COMM TS
--------- ---------- ---------- -----------CLERK
806
08.10.51 PM
SALES
8060
1000 08.12.10 PM
SALESMAN
1606 300000000 08.10.51 PM
SALESMAN
1256 500000000 08.10.51 PM
MANAGER
2981
08.10.51 PM

O
I
U
I
I
I

JAMES
FORD
MILLER
MILLER

CLERK
ANALYST
CLERK
CLERK

I
I
I
D

956
3006
1306
1306

08.10.51
08.10.51
08.10.51
08.12.10

PM
PM
PM
PM

60
so why didn't we ?

61
reason 1

62
"yeah...but who ? where ? how ?"

63
SQL> alter table EMP add UPDATED_BY varchar2(10);
Table altered.
SQL> alter table EMP add UPDATED_PGM varchar2(10);
Table altered.
[etc]
[etc]

64
reason 2

65
separately licensed :-(

67
can 12c help ?

68
1) context extension

69
SQL> begin
2
dbms_flashback_archive.set_context_level(
3
level=> 'ALL');
4 end;
PL/SQL procedure successfully completed.

70
SQL> update EMP
2 set
sal = sal*10
3 where empno = 7499;
1 row updated.

SQL> commit;

71
SQL> select XID from SYS_FBA_HIST_510592;
XID
---------------09000B00C7080000

72
SQL> set serverout on
SQL> begin
2
dbms_output.put_line(
3
dbms_flashback_archive.get_sys_context (
4
'09000B00C7080000', 'USERENV', 'SESSION_USER'));
5
6
dbms_output.put_line(
7
dbms_flashback_archive.get_sys_context (
8
'09000B00C7080000', 'USERENV', 'HOST'));
9
10
dbms_output.put_line(
11
dbms_flashback_archive.get_sys_context (
12
'09000B00C7080000', 'USERENV', 'MODULE'));
13 end;
14 /
SCOTT
WORKGROUPXPS
SQL*Plus

73
74
SQL> desc SYS.SYS_FBA_CONTEXT_AUD
Name
Null?
------------------------- -------XID
ACTION
AUTHENTICATED_IDENTITY
CLIENT_IDENTIFIER
CLIENT_INFO
CURRENT_EDITION_NAME
CURRENT_SCHEMA
CURRENT_USER
DATABASE_ROLE
DB_NAME
GLOBAL_UID
HOST
IDENTIFICATION_TYPE
INSTANCE_NAME
IP_ADDRESS
MODULE
OS_USER
SERVER_HOST
SERVICE_NAME

Type
-----------------RAW(8)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)

75
AUTHENTICATED_IDENTITY
CLIENT_IDENTIFIER
CLIENT_INFO
CURRENT_EDITION_NAME
CURRENT_SCHEMA
CURRENT_USER
DATABASE_ROLE
DB_NAME
GLOBAL_UID
HOST
IDENTIFICATION_TYPE
INSTANCE_NAME
IP_ADDRESS
MODULE
OS_USER
SERVER_HOST
SERVICE_NAME
SESSION_EDITION_NAME
SESSION_USER
SESSION_USERID
SESSIONID
TERMINAL
SPARE

VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
VARCHAR2(256)
76
SQL> @pt "select * from SYS.SYS_FBA_CONTEXT_AUD
where xid = '09000B00C7080000'"
XID
AUTHENTICATED_IDENTITY
CLIENT_IDENTIFIER
CLIENT_INFO
CURRENT_EDITION_NAME
CURRENT_SCHEMA
CURRENT_USER
DATABASE_ROLE
DB_NAME
HOST
IDENTIFICATION_TYPE
INSTANCE_NAME
MODULE
OS_USER
SERVER_HOST
SERVICE_NAME
SESSION_EDITION_NAME
SESSION_USER
SESSION_USERID
SESSIONID
TERMINAL

:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:

09000B00C7080000
scott

ORA$BASE
SYS
SYS
PRIMARY
np12
WORKGROUPXPS
LOCAL
np12
SQL*Plus
xpshamcdc
xps
SYS$USERS
ORA$BASE
SCOTT
103
230698
XPS
77
SQL>
2
3
4
5
6
7

select empno, ename, job, sal, comm,
VERSIONS_XID
from EMP
versions between timestamp
timestamp '2014-02-11 20:12:00' and
systimestamp
order by empno;

EMPNO
---------7369
7369
7499
7499
7499
7521

ENAME
---------SMITH
SMITH
ALLEN
ALLEN
ALLEN
WARD

JOB
SAL
COMM VERSIONS_XID
--------- ---------- ---------- ---------------CLERK
806
SALES
8060
1000 09001C00E04A0000
CLERK
16060 300000000 0A000A0024080000
SALESMAN
16060 300000000 09000B00C7080000
SALESMAN
1606 300000000
SALESMAN
1256 500000000

78
SQL>
2
3
4
5
6
7
8
9
10
11

select ...
from
( select
empno, ename, job,
sal, comm, VERSIONS_XID
from EMP
versions between timestamp
timestamp '2014-02-11 20:12:00' and
systimestamp
) e, SYS.SYS_FBA_CONTEXT_AUD a
where e.VERSIONS_XID = a.XID;

79
keep an eye on space

SYSTEM tablespace
80
2)

81
total recall is now …

75
free !

76
let

me
repeat
77
oracle feature that is free !

78
basis versus advanced

79
compression

choose your cost

partitioning
87
so think about total recall

81
secure

read only

89
efficient
fdba

90
all your history...

84
all your audit...

85
be careful...
silent errors

93
SQL> ALTER TABLE EMP FLASHBACK ARCHIVE LONGTERM;
Table altered.
Flashback Archive:
Error ORA-1950 in SQL create table "SCOTT".SYS_FBA_DDL_COLMAP_91938
(STARTSCN NUMBER, ENDSCN NUMBER...
Flashback Archive:
Error ORA-942 in SQL insert into "SCOTT".SYS_FBA_DDL_COLMAP_91938
(ENDSCN, COLUMN_NAME, TYPE, ...
Flashback Archive:
Error ORA-942 in SQL "select count(*) from "SCOTT".SYS_FBA_DDL_COLMAP_91938"

94
Feature:
better truncate

88
SQL> create table PARENT ( p int primary key );

Table created.
SQL> create table CHILD
2
( c int primary key,
3
p int references PARENT ( p )
4
);
Table created.
SQL> insert into PARENT values (1);
1 row created.
SQL> insert into CHILD

values (1,1);

1 row created.
89
SQL> truncate table PARENT;

truncate table PARENT
*
ERROR at line 1:
ORA-02266: unique/primary keys in table
referenced by enabled foreign keys

90
SQL> create table CHILD
2
( c int primary key,
3
p int references PARENT ( p )
4
on delete cascade);

Table created.
SQL> insert into PARENT values (1);
1 row created.
SQL> insert into CHILD

values (1,1);

1 row created.
SQL> truncate table PARENT;
truncate table PARENT
*
ERROR at line 1:
ORA-02266: unique/primary keys in table referenced by
enabled foreign keys
91
12c

92
SQL> truncate table PARENT cascade;
Table truncated.

93
must be on delete cascade

94
SQL> alter table child modify
2
constraint CHILD_FK on delete cascade;
ERROR at line 1:
ORA-00933: SQL command not properly ended

SQL> alter table child add
2
constraint NEW_FK foreign key ( p )
3
references parent ( p ) on delete cascade;
ERROR at line 1:
ORA-02275: such a referential constraint already
exists in the table

95
full cascade

96
referential partitions

97
Feature
session level sequence

98
SQL> create sequence SESS_SEQ session;
Sequence created.

99
SQL> select sess_seq.nextval from dual;
NEXTVAL
---------1
SQL> conn scott/tiger
Connected.
SQL> select sess_seq.nextval from dual;
NEXTVAL
---------1

100
"big deal"

101
"bad" reason

102
SQL> select X
2 from
GTT;

SQL> select X
2 from
GTT;

X
---------1
2
3
4
5
6
7
8
9
...

X
---------1
2
3
4
5
6
7
8
9
...
103
better reason

104
contention

105
SQL> create sequence NORMAL cache 1000;

Sequence created.
SQL> alter session set sql_trace = true;
Session altered.
SQL>
2
3
4

insert into GTT
select SESS_SEQ.NEXTVAL
from dual
connect by level < 50000;

49999 rows created.
SQL>
2
3
4

insert into GTT
select NORMAL.NEXTVAL
from dual
connect by level < 50000;

49999 rows created.
106
insert into GTT
select NORMAL.NEXTVAL
from dual
connect by level < 50000
call
count
------- -----Parse
1
Execute
1
Fetch
0
------- -----total
2

cpu
elapsed
disk
query
current
-------- ---------- ---------- ---------- ---------0.00
0.00
0
0
0
0.35
0.35
0
147
642
0.00
0.00
0
0
0
-------- ---------- ---------- ---------- ---------0.35
0.35
0
147
642

rows
---------0
49999
0
---------49999

107
insert into GTT
select SESS_SEQ.NEXTVAL
from dual
connect by level < 50000
call
count
------- -----Parse
1
Execute
1
Fetch
0
------- -----total
2

cpu
elapsed
disk
query
current
-------- ---------- ---------- ---------- ---------0.00
0.00
0
0
0
0.25
0.25
0
145
592
0.00
0.00
0
0
0
-------- ---------- ---------- ---------- ---------0.25
0.25
0
145
592

rows
---------0
49999
0
---------49999

108
update SEQ$
set increment$=:2,minvalue=:3,maxvalue=:4,
cycle#=:5,order$=:6,
cache=:7,highwater=:8,audit$=:9,
flags=:10,partcount=:11
where
obj#=:1
call
count
------- -----Parse
1
Execute
50
Fetch
0
------- -----total
51

cpu
elapsed
disk
query
current
-------- ---------- ---------- ---------- ---------0.00
0.00
0
0
0
0.00
0.00
0
50
103
0.00
0.00
0
0
0
-------- ---------- ---------- ---------- ---------0.00
0.00
0
50
103

rows
---------0
50
0
---------50

109
Feature
defaults

110
the most common ...

111
and the absolute worst ...

112
usage of triggers

113
SQL> create sequence seq;

Sequence created.
SQL> create table T ( pk number

, c1 int);

Table created.
SQL>
2
3
4
5
6
7
8

create or replace
trigger FILL_IN_PK
before insert on T
for each row
begin
select seq.nextval into :new.pk from dual;
end;
/

Trigger created.

114
SQL> insert into T values (10,20);

1 row created.
SQL> select * from T;
PK
C1
---------- ---------1
20

115
we got smarter

116
SQL>
2
3
4
5
6
7
8
9

create or replace
trigger FILL_IN_PK
before insert on T
for each row
when ( new.pk is null )
begin
select seq.nextval into :new.pk from dual;
end;
/

Trigger created.
SQL> insert into T values (20,20);
1 row created.
SQL> select * from T;
PK
C1
---------- ---------1
20
20
20
117
triggers
over rated ...

for that stuff
insert /* with trigger */ into T
select rownum, rownum
from dual connect by level <= 50000
call
count
------- -----Parse
1
Execute
1
Fetch
0
------- -----total
2

cpu
elapsed
disk
query
current
-------- ---------- ---------- ---------- ---------0.00
0.00
0
0
0
5.64
5.64
0
466
1608
0.00
0.00
0
0
0
-------- ---------- ---------- ---------- ---------5.64
5.65
0
466
1608

rows
---------0
50000
0
---------50000
insert /* without trigger */ into T
select rownum, rownum
from dual connect by level <= 50000
call
count
------- -----Parse
1
Execute
1
Fetch
0
------- -----total
2

cpu
elapsed
disk
query
current
-------- ---------- ---------- ---------- ---------0.00
0.00
0
0
0
0.09
0.15
0
466
1620
0.00
0.00
0
0
0
-------- ---------- ---------- ---------- ---------0.09
0.15
0
466
1620

rows
---------0
50000
0
---------50000
12c ... finally !
SQL> create table T ( pk number default seq.nextval ,
2
c1 int);
Table created.
SQL> insert into T ( c1 ) values ( 0);
SQL> select * from T;
PK
C1
---------- ---------2
0

SQL> insert into T ( pk, c1 ) values (default, 1) ;
SQL> select * from T;
PK
C1
---------- ---------2
0
3
1
123
insert /* with default */ into T
select rownum, rownum
from dual connect by level <= 50000
call
count
------- -----Parse
1
Execute
1
Fetch
0
------- -----total
2

cpu
elapsed
disk
query
current
-------- ---------- ---------- ---------- ---------0.00
0.00
0
0
0
0.06
0.07
0
467
1608
0.00
0.00
0
0
0
-------- ---------- ---------- ---------- ---------0.06
0.08
0
467
1608

rows
---------0
50000
0
---------50000
other default improvements
"identity"
SQL> drop table t purge;
Table dropped.
SQL> create table T
2
( pk number generated as identity ,
3
c1 int);
Table created.
SQL> select object_id, object_name,
2
object_type from user_objects;
OBJECT_ID
---------414914
414915

OBJECT_NAME
-----------------T
ISEQ$$_414914

OBJECT_TYPE
-----------TABLE
SEQUENCE

127
SQL> @pr "select * from user_sequences"
SEQUENCE_NAME
MIN_VALUE
MAX_VALUE
INCREMENT_BY
CYCLE_FLAG
ORDER_FLAG
CACHE_SIZE
LAST_NUMBER
PARTITION_COUNT
SESSION_FLAG
KEEP_VALUE

:
:
:
:
:
:
:
:
:
:
:

ISEQ$$_414914
1
9999999999999999999999
1
N
N
20
1
N
N

128
SQL> create table T
2
( pk number
3
generated as identity (cache 1000)
4
, c1 int);
Table created.
SQL> insert into T values (1,2);
insert into T values (1,2)
*
ERROR at line 1:
ORA-32795: cannot insert into a generated always
identity column

can choose
129
more null control
before 12c
SQL> create table T (
2
pk int,
3
status varchar2(1) default 'N' );
Table created.
SQL> insert into T (pk) values (1);
1 row created.
SQL> insert into T (pk, status) values (2,default);

1 row created.
SQL> insert into T (pk, status) values (3,null);
1 row created.

132
SQL> select * from T;
PK STATUS
---------- -----1
N
2
N
3

133
workarounds ugly

134
SQL>
2
3
4
5
6
7
8
9
10
11
12

create or replace
procedure ins(p_pk int, p_status varchar2) is
begin
if p_status is null then
insert into T (pk, status)
values (p_pk, default );
else
insert into T (pk, status)
values (p_pk, p_status );
end if;
end;
/

Procedure created.

135
12c "on null"
SQL> create table T (
2
pk
int,
3
status
varchar2(1)
4
start_date date
5
6
commission int
7
job_level
int
8
);

default on null 'N' ,
default on null
trunc(sysdate,'MM'),
default on null 1000,
default on null 1

Table created.
SQL> insert into T values (1,null,null,null,null);
1 row created.
SQL> select * from T;

PK S START_DAT COMMISSION JOB_LEVEL
---------- - --------- ---------- ---------1 N 01-JAN-14
1000
1
137
Feature
temporal validity
wtf
very common

140
"when" is a row valid

141
SQL> CREATE TABLE
2
empno
3
name
4
sal
5
deptno
6
start_dt
7
end_dt
8
9 );

emp_temporal (
NUMBER,
VARCHAR2(30),
NUMBER,
NUMBER,
DATE,
DATE,

Table created.

142
12c part of the definition

143
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.

144
examples

145
SQL> select * from emp_temporal
2 order by empno, start_dt;
EMPNO
---------7369
7369
7499
7499
7521
7521
7566
7566
7654
7654
7698

NAME
SAL
DEPTNO START_DT END_DT
------------ ---------- ---------- --------- --------SMITH
806
20 01-JAN-14 01-MAR-14
SMITHX
8060
21 02-MAR-14 01-OCT-14
ALLEN
1606
30 01-JAN-14 01-MAR-14
ALLENX
16060
31 02-MAR-14 01-OCT-14
WARD
1256
30 01-JAN-14 01-MAR-14
WARDX
12560
31 02-MAR-14 01-OCT-14
JONES
2981
20 01-JAN-14 01-MAR-14
JONESX
29810
21 02-MAR-14 01-OCT-14
MARTIN
1256
30 01-JAN-14 01-MAR-14
MARTINX
12560
31 02-MAR-14 01-OCT-14
BLAKE
2856
30 01-JAN-14 01-MAR-14

146
SQL> select * from emp_temporal
2 as of period for valid_range '01-FEB-14';
EMPNO
---------7369
7499
7521
7566
7654

NAME
SAL
DEPTNO START_DT END_DT
------------ ---------- ---------- --------- --------SMITH
806
20 01-JAN-14 01-MAR-14
ALLEN
1606
30 01-JAN-14 01-MAR-14
WARD
1256
30 01-JAN-14 01-MAR-14
JONES
2981
20 01-JAN-14 01-MAR-14
MARTIN
1256
30 01-JAN-14 01-MAR-14

147
so what's happening ?

148
another new feature

149
Feature
query expansion

150
SQL> set autotrace traceonly stat
SQL> select * from MY_VIEW
2 where CREATED > sysdate

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

151
SQL> variable c clob
SQL> begin
2
dbms_utility.expand_sql_text
3
( 'select * from MY_VIEW'||
4
'where created > sysdate',:c);
5 end;
6 /
PL/SQL procedure successfully completed.

SQL> print c

152
SQL>
2
3
4
5
6
7
8
9
10
11
12

create or replace
view MY_VIEW as
select
o.owner,
o.created,
s.bytes,
s.tablespace_name
from
dba_segments s,
all_objects o
where o.owner = s.owner
and
o.object_name = s.segment_name;

View created.

153
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",
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",

154
"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",
DECODE("A4"."BUFFER_POOL_ID",1,'KEEP',2,'RECYCLE','DEFAULT') "BUFFER_POOL",
DECODE("A4"."FLASH_CACHE",1,'KEEP',2,
'NONE','DEFAULT')
"FLASH_CACHE",DECODE("A4"."CELL_FLASH_CACHE",1,'KEEP',2,'NONE','DEFAULT')
"CELL_FLASH_CACHE"
FROM ( (SELECT NVL("A199"."NAME",'SYS') "OWNER",
"A198"."NAME" "SEGMENT_NAME",

155
"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'),N
ULL))
"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"."G
ROUPS",0,1,
"A195"."GROUPS")) "FREELIST_GROUPS",
"A195"."FILE#" "RELATIVE_FNO",BITAND("A195"."CACHEHINT",3) "BUFFER_POOL_ID",
BITAND("A195"."CACHEHINT",12)/4 "FLASH_CACHE",BITAND("A195"."CACHEHINT",48)/16
"CELL_FLASH_CACHE",
NVL("A195"."SPARE1",0)
"SEGMENT_FLAGS",DECODE(BITAND("A195"."SPARE1",1),1,
"A195"."HWMINCR",
"A198"."DATAOBJ#") "SEGMENT_OBJD" FROM "SYS"."USER$" "A199",
"SYS"."OBJ$" "A198",
"SYS"."TS$" "A197", ( (SELECT

156
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
"A206"."TYPE#"=7 OR
"A206"."TYPE#"=8 OR
"A206"."TYPE#"=9) UNION ALL
(SELECT 'INDEX PARTITION'
"OBJECT_TYPE",20 "OBJECT_TYPE_ID",6 "SEGMENT_TYPE_ID",
"A205"."OBJ#" "OBJECT_ID",
"A205"."FILE#" "HEADER_FILE",
"A205"."BLOCK#" "HEADER_BLOCK",

157
"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",
"SYS"."FILE$" "A194" WHERE "A195"."FILE#"="A196"."HEADER_FILE" AND
"A195"."BLOCK#"="A196"."HEADER_BLOCK" AND
"A195"."TS#"="A196"."TS_NUMBER" AND
"A195"."TS#"="A197"."TS#" AND
"A198"."OBJ#"="A196"."OBJECT_ID" AND
"A198"."OWNER#"="A199"."USER#"(+) AND
"A195"."TYPE#"="A196"."SEGMENT_TYPE_ID" AND
"A198"."TYPE#"="A196"."OBJECT_TYPE_ID" AND
"A195"."TS#"="A194"."TS#" AND

158
"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("A190"
."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",
"A191"."US#" "SEGMENT_OBJD" FROM "SYS"."USER$" "A193","SYS"."TS$" "A192",
"SYS"."UNDO$" "A191",
"SYS"."SEG$" "A190",
"SYS"."FILE$" "A189" WHERE "A190"."FILE#"="A191"."FILE#" AND
"A190"."BLOCK#"="A191"."BLOCK#" AND
"A190"."TS#"="A191"."TS#" AND
"A190"."TS#"="A192"."TS#" AND
"A190"."USER#"="A193"."USER#"(+) AND
("A190"."TYPE#"=1 OR
"A190"."TYPE#"=10) AND
"A191"."STATUS$"<>1 AND

159
"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("A186"
."LISTS",0,1,
"A186"."LISTS"))
"FREELISTS",DECODE(BITAND("A187"."FLAGS",32),32,TO_NUMBER(NULL),DECODE("A186"."G
ROUPS",0,1,
"A186"."GROUPS")) "FREELIST_GROUPS",
"A186"."FILE#" "RELATIVE_FNO",BITAND("A186"."CACHEHINT",3)
"BUFFER_POOL_ID",BITAND("A186"."CACHEHINT",12)/4
"FLASH_CACHE",BITAND("A186"."CACHEHINT",48)/16
"CELL_FLASH_CACHE",NVL("A186"."SPARE1",0) "SEGMENT_FLAGS",
"A186"."HWMINCR" "SEGMENT_OBJD" FROM "SYS"."USER$"
"A188",
"SYS"."TS$" "A187",
"SYS"."SEG$" "A186",
"SYS"."FILE$" "A185" WHERE "A186"."TS#"="A187"."TS#" AND
"A186"."USER#"="A188"."USER#"(+) AND
"A186"."TYPE#"<>1 AND
"A186"."TYPE#"<>5 AND

160
"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
ODE("A182"."LISTS",0,1,
"A182"."LISTS"))
"FREELISTS",DECODE(BITAND("A183"."FLAGS",32),32,TO_NUMBER(NULL),DECODE("A182"."G
ROUPS",0,1,
"A182"."GROUPS")) "FREELIST_GROUPS",
"A182"."FILE#" "RELATIVE_FNO",BITAND("A182"."CACHEHINT",3) "BUFFER_POOL_ID",
BITAND("A182"."CACHEHINT",12)/4 "FLASH_CACHE",BITAND("A18
2"."CACHEHINT",48)/16 "CELL_FLASH_CACHE",NVL("A182"."SPARE1",0) "SEGMENT_FLAGS",
"A182"."HWMINCR" "SEGMENT_OBJD" FROM "SYS"."USER$" "A184",

161
"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",
"A6"."MTIME" "LAST_DDL_TIME",TO_CHAR("A6"."STIME",'YYYY-MM-DD:HH24:MI:SS') "TIMESTAMP",DEC
ODE("A6"."STATUS",0,'N/A',1,'VALID','INVALID')
"STATUS",DECODE(BITAND("A6"."FLAGS",2),0,'N',2,'Y','N')
"TEMPORARY",DECODE(BITAND("A6"."FLAGS",4),0,'N',4,'Y','N')
"GENERATED",DECODE(BITAND("A6"."FLAGS",16),0,'N',16,'Y','N') "SECONDARY",
"A6"."NAMESPACE" "NAMESPACE",
"A6"."DEFINING_EDITION" "EDITION_NAM
E",DECODE(BITAND("A6"."FLAGS",196608),65536,'METADATA LINK',131072,'OBJECT LINK','NONE')
"SHARING",
CASE WHEN ("A6"."TYPE#"=4 OR
"A6"."TYPE#"=5 OR

162
16 ...
more
pages

163
back to temporal validity

164
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 /
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"

166
existing tables

167
SQL> desc EMPLOYEE

Name
Null?
------------------------- -------EMPNO
ENAME
JOB
MGR
HIREDATE
SAL
COMM
DEPTNO

Type
--------------NUMBER(4)
VARCHAR2(10)
VARCHAR2(9)
NUMBER(4)
DATE
NUMBER(7,2)
NUMBER(12,2)
NUMBER(2)

SQL> alter table EMPLOYEE add period for TIME_RANGE;
Table altered.

168
SQL> desc EMPLOYEE

Name
Null?
------------------------- -------EMPNO
ENAME
JOB
MGR
HIREDATE
SAL
COMM
DEPTNO

Type
--------------NUMBER(4)
VARCHAR2(10)
VARCHAR2(9)
NUMBER(4)
DATE
NUMBER(7,2)
NUMBER(12,2)
NUMBER(2)

still looks the same ?
169
SQL>
2
3
4

select column_name , hidden_column
from user_tab_cols
where table_name = 'EMPLOYEE'
order by column_id;

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

HIDDEN_COLUMN
------------NO
NO
NO
NO
NO
NO
NO
NO
YES
YES
YES
170
multi temporal validity

171
SQL> alter table EMP_TEMPORAL add period for CAL_RANGE;
Table altered.
SQL> alter table EMP_TEMPORAL add period for FINYR_RANGE;
Table altered.

172
maybe a 12.x feature ?

173
no temporal constraints

174
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
175
add START_DT to primary key ?
no temporal validation

177
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.
no (native) temporal DML

179
SQL>
2
3
4

update EMP_TEMPORAL
as of period for valid_range '01-FEB-14'
set sal = 10
where empno = 20;

as of period for valid_range '01-FEB-14'
*
ERROR at line 2:
ORA-08187: snapshot expression not allowed here
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.

181
and one more issue…
"Temporal validity is not supported
with a multitenant container
database"

183
Feature
PL/SQL debugging
it all starts off easy

185
SQL>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

create or replace procedure P is
x int;
y int;
begin
x := 10;
select
into
from
where

count(*)
y
all_objects
object_name = 'NUFFIN';

x := x / y;

select rownum
into
x
from
dual;
end;
/

Procedure created.
186
SQL> exec P;
BEGIN P; END;
*
ERROR at line 1:
ORA-01476: divisor is equal to zero
ORA-06512: at "SCOTT.P", line 13
ORA-06512: at line 1

187
SQL>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

create or replace procedure P is
x int;
y int;
begin
x := 10;
select
into
from
where

count(*)
y
all_objects
object_name = 'NUFFIN';

x := x / y;

select rownum
into
x
from
dual;
end;
/

Procedure created.
188
... and downhill from there
SQL>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

create or replace procedure P is
x int;
y int;
begin
x := 10;
select
into
from
where

count(*)
y
all_objects
object_name = 'NUFFIN';

x := x / y;
select rownum
into
x
from
dual;
exception
when others then
log_error;
raise;
end;
/

190
SQL> exec P;
BEGIN P; END;
*
ERROR at line 1:
ORA-01476: divisor is equal to zero
ORA-06512: at "SCOTT.P", line 22
SQL>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

create or replace procedure P is
x int;
y int;
begin
x := 10;
select
into
from
where

count(*)
y
all_objects
object_name = 'NUFFIN';

?

x := x / y;
select rownum
into
x
from
dual;
exception
when others then
log_error;
raise;
end;
/

192
SQL>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

create or replace procedure P is
x int;
y int;
begin
x := 10;
select
into
from
where

count(*)
y
all_objects
object_name = 'NUFFIN';

x := x / y;
select rownum
into
x
from
dual;
exception
when others then
dbms_output.put_line(
dbms_utility.format_call_stack);
raise;
end;
/
SQL> exec P;
----- PL/SQL Call Stack ----object
line object
handle
number name
0x14b1e3900
21 procedure SCOTT.P
0x12521b8d8
1 anonymous block
BEGIN P; END;
*
ERROR at line 1:
ORA-01476: divisor is equal to zero
ORA-06512: at "SCOTT.P", line 23
ORA-06512: at line 1

194
SQL>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

create or replace procedure P is
x int;
y int;
l_debug varchar2(4000);
begin
l_debug := dbms_utility.format_call_stack;
x := 10;
l_debug := dbms_utility.format_call_stack;
select count(*)
into
y
from
all_objects
where object_name = 'NUFFIN';
l_debug := dbms_utility.format_call_stack;
x := x / y;
l_debug := dbms_utility.format_call_stack;
select rownum
into
x
from
dual;
exception
when others then
dbms_output.put_line(l_debug);
raise;
end;
SQL> exec P;
----- PL/SQL Call Stack ----object
line object
handle
number name
0x14b1e3900
16 procedure SCOTT.P
0x12521b8d8
1 anonymous block
BEGIN P; END;
*
ERROR at line 1:
ORA-01476: divisor is equal to zero
ORA-06512: at "SCOTT.P", line 27
ORA-06512: at line 1

196
SQL> create or replace procedure P is
2
x int;
3
y int;
4
l_debug varchar2(4000);
5 begin
6
l_debug := dbms_utility.format_call_stack;
7
...
24
25
26
27
28
29
30
31

exception
when others then
l_debug := substr(l_debug,instr(l_debug,chr(10),1,3));
l_debug := regexp_replace(l_debug,chr(10)||'.*$');
dbms_output.put_line(l_debug);
raise;
end;
/
SQL> exec P;
0x14b1e3900
BEGIN P; END;

16

procedure SCOTT.P

*
ERROR at line 1:
ORA-01476: divisor is equal to zero
ORA-06512: at "SCOTT.P", line 29
ORA-06512: at line 1

198
10g got better
DBMS_UTILITY.FORMAT_ERROR_BACKTRACE

200
SQL> create or replace procedure P is
2
x int;
3
y int;
4
l_debug varchar2(4000);
5 begin
6
l_debug := dbms_utility.format_call_stack;
7
8
x := 10;
9
...
23
24 exception
25
when others then
26
dbms_output.put_line(
27
DBMS_UTILITY.FORMAT_ERROR_BACKTRACE );
28
raise;
29 end;
SQL> exec P;
ORA-06512: at "SCOTT.P", line 17
BEGIN P; END;

*
ERROR at line 1:
ORA-01476: divisor is equal to zero
ORA-06512: at "SCOTT.P", line 27
ORA-06512: at line 1

202
still parsing strings
12c .... finally

204
UTL_CALL_STACK
SQL> create or replace procedure P is
2
x int;
3
y int;
4 begin
5
x := 10;
6
...
17
18 exception
19
when others then
20
for i in 1 .. utl_call_stack.dynamic_depth loop
21
dbms_output.put_line(
22
utl_call_stack.unit_line(i)||'-'||
23
utl_call_stack.concatenate_subprogram(
24
utl_call_stack.subprogram(i))
25
);
26
end loop;
27
raise;
28 end;

206
SQL> exec P;
16-P
1-__anonymous_block
BEGIN P; END;
*
ERROR at line 1:
ORA-01476: divisor is equal to zero
ORA-06512: at "SCOTT.P", line 27
ORA-06512: at line 1
value in "real world"

208
SQL> create or replace package PKG is
2
procedure p;
3
procedure p1;
4
procedure p2;
5
procedure p3;
6 end;
7 /
Package created.
SQL> create or replace package body PKG is
2
3 procedure p is
...
19
20 exception
21
when others then
22
for i in 1 .. utl_call_stack.dynamic_depth loop
23
dbms_output.put_line(
24
utl_call_stack.unit_line(i)||'-'||
25
utl_call_stack.concatenate_subprogram(
26
utl_call_stack.subprogram(i))
27
);
28
end loop;
29
raise;
30 end;
31
32 procedure p1 is begin p; end;
33 procedure p2 is begin p1; end;
34 procedure p3 is begin p2; end;
35
36 end;
37 /
210
SQL> exec pkg.p3
23-PKG.P
32-PKG.P1
33-PKG.P2
34-PKG.P3
1-__anonymous_block
BEGIN pkg.p3; END;
*
ERROR at line 1:
ORA-01476: divisor is equal to zero
ORA-06512: at "SCOTT.PKG", line 29
ORA-06512: at "SCOTT.PKG", line 32
ORA-06512: at "SCOTT.PKG", line 33
ORA-06512: at "SCOTT.PKG", line 34
ORA-06512: at line 1
did you miss it ?

212
SQL> exec pkg.p3
23-PKG.P
32-PKG.P1
33-PKG.P2
34-PKG.P3
1-__anonymous_block

subprogram !!!

BEGIN pkg.p3; END;
*
ERROR at line 1:
ORA-01476: divisor is equal to zero
ORA-06512: at "SCOTT.PKG", line 29
ORA-06512: at "SCOTT.PKG", line 32
ORA-06512: at "SCOTT.PKG", line 33
ORA-06512: at "SCOTT.PKG", line 34
ORA-06512: at line 1
Feature
inline PLSQL in SQL

214
every system ...
... I've worked on

216
struggles with cAsE
no correlation :-)

218
SQL> select surname
2 from
names;
SURNAME
-----------------------------jones
brown
SMITH

sigh...
"no problem.... I'll use initcap"

220
SQL> select initcap(surname)
2 from
names;
INITCAP(SURNAME)
-----------------------------Jones
Brown
Smith
until ...

222
SQL> select initcap(surname)
2 from
names;
INITCAP(SURNAME)
-----------------------------Jones
Brown
Smith
Mcdonald
Johnson'S

uh oh
home grown

224
SQL>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

create or replace
function my_initcap(p_string varchar2) return varchar2 is
l_string varchar2(1000) := p_string;
begin
if regexp_like(l_string,'(Mac[A-Z]|Mc[A-Z])') then
null;
elsif l_string like '''%' then
null;
else
l_string := initcap(l_string);
if l_string like '_''S%' then
null;
else
l_string := replace(l_string,'''S','''s');
end if;
end if;
return l_string;
end;
/

Function created.
cool ...

226
SQL> select my_initcap(surname)
2 from
names;
MY_INITCAP(SURNAME)
-------------------------Jones
Brown
Smith
McDonald
Johnson's
until ...

228
"don't call PLSQL from SQL !!!!"

230
SQL> select max(x)
2 from (
3
select /*+ no_merge */ initcap(source) x
4
from
sys.source$
5 );
...
Elapsed: 00:00:00.48
SQL> select max(x)
2 from (
3
select /*+ no_merge */ initcap(source) x
4
from
sys.source$
5 );
...
SQL> select max(x)
2 from (
Elapsed: select /*+ no_merge */ my_initcap(source) x
00:00:00.48
3
4
from
sys.source$
5 );
Elapsed: 00:00:09.37
it can be done in SQL

232
SQL> select
2
case
3
when regexp_like(surname,'(Mac[A-Z]|Mc[A-Z])') then surname
4
when surname like '''%' then surname
5
when initcap(surname) like '_''S%' then surname
6
else replace(initcap(surname),'''S','''s')
7
end ugh
8 from names;

UGH !!!
------------------------------Jones
Brown
Smith
McDonald
Johnson's
"Always code as if the person who
ends up maintaining your code is a
psychopathic killer who knows
where you live."
- source unknown

234
12c ... user defined functions
SQL> WITH
2
function my_initcap(p_string varchar2) return varchar2 is
3
l_string varchar2(1000) := p_string;
4
begin
5
if regexp_like(l_string,'(Mac[A-Z]|Mc[A-Z])') then
6
null;
7
elsif l_string like '''%' then
...
17
18
return l_string;
19
end;
20 select my_initcap(surname)
21 from
names;
MY_INITCAP(SURNAME)
----------------------------------------Jones
Brown
Smith
McDonald
O'Brien
Johnson's

236
multiple routines
SQL>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

WITH
function is_scottish(p_string varchar2) return boolean is
begin
return regexp_like(p_string,'(Mac[A-Z]|Mc[A-Z])');
end;
function my_initcap(p_string varchar2) return varchar2 is
l_string varchar2(1000) := p_string;
begin
if is_scottish(l_string) then
null;
elsif l_string like '''%' then
null;
else
l_string := initcap(l_string);
if l_string like '_''S%' then
null;
else
l_string := replace(l_string,'''S','''s');
end if;
end if;

return l_string;
end;
select my_initcap(surname)
from
names;
/
238
note: 12c client

239
11.2 and below
SQL> WITH
2
function my_initcap(p_string varchar2) return varchar2 is
3
l_string varchar2(1000) := p_string;
function my_initcap(p_string varchar2) return varchar2 is
*
ERROR at line 2:
ORA-06553: PLS-103: Encountered the symbol "end-of-file" when
expecting one of the following:
. ( * @ % & = - + ; < / > at in is mod remainder not rem
<an exponent (**)> <> or != or ~= >= <= <> and or like like2
like4 likec between || multiset member submultiset
SQL>
2
3
4
5
6
7

begin
if regexp_like(l_string,'(Mac[A-Z]|Mc[A-Z])') then
null;
elsif l_string like '''%' then
null;
else
l_string := initcap(l_string);

241
workaround

SQL> set SQLTERMINATOR ...

242
and a blast from the past :-)
SQL> create or replace
2 procedure NAMES_PROCESSOR is
3
cursor C is
4
WITH
5
function my_initcap(p_string varchar2) return varchar2 is
6
l_string varchar2(1000) := p_string;
7
begin
...
23
select my_initcap(surname)
24
from
names;
25 begin
26
null;
27 end;
28 /
Warning: Procedure created with compilation errors.
SQL> sho err
Errors for PROCEDURE NAMES_PROCESSOR:

LINE/COL
-------3/7
4/18
22/7

ERROR
-----------------------------------------------PL/SQL: SQL Statement ignored
PL/SQL: ORA-00905: missing keyword
PLS-00103: Encountered the symbol "SELECT"
244
SQL> create or replace
2 procedure NAMES_PROCESSOR is
3
rc sys_refcursor;
4 begin
5
open rc for
6
q'{ WITH
7
function my_initcap(p_string varchar2) return varchar2 is
8
l_string varchar2(1000) := p_string;
9
begin
...
23
return l_string;
24
end;
25
select my_initcap(surname)
26
from
names
27
}';
28 end;
29 /
Procedure created.
WITH_PLSQL

unrelated to previous
246
DML (or complex SQL)
SQL> insert into NAMES2
2 WITH
3
function my_initcap(p_string varchar2)
4
return varchar2 is
5
l_string varchar2(1000) := p_string;
6
begin
...
20
end;
21 select my_initcap(surname)
22 from
names;
23 /
WITH
*
ERROR at line 2:
ORA-32034: unsupported use of WITH clause

248
SQL> insert /*+ WITH_PLSQL */ into NAMES2
2 WITH
3
function my_initcap(p_string varchar2)
4
return varchar2 is
5
l_string varchar2(1000) := p_string;
6
begin
...
20
end;
21 select my_initcap(surname)
22 from
names;
23 /
5 rows inserted.
determinism

250
SQL>
2
3
4
5
6
7
8
9

with
function f return timestamp as
begin
return systimestamp;
end;
select f
from dual
connect by level <= 10;
/

F
---------------------------------------05-JAN-14 08.09.43.969000000 PM
05-JAN-14 08.09.43.970000000 PM
05-JAN-14 08.09.43.970000000 PM
05-JAN-14 08.09.43.971000000 PM
...
DETERMINISTIC keyword

252
SQL>
2
3
4
5
6
7
8
9

with
function f return timestamp DETERMINISTIC as
begin
return systimestamp;
end;
select f
from dual
connect by level <= 10;
/

F
---------------------------------------05-JAN-14 08.09.52.145000000 PM
05-JAN-14 08.09.52.146000000 PM
05-JAN-14 08.09.52.146000000 PM
05-JAN-14 08.09.52.147000000 PM
...
conventional scalar caching

254
SQL>
2
3
4
5
6
7
8
9

with
function f return timestamp as
begin
return systimestamp;
end;
select ( select f from dual )
from dual
connect by level <= 10;
/

F
---------------------------------------05-JAN-14 08.11.50.145000000 PM
05-JAN-14 08.11.50.145000000 PM
05-JAN-14 08.11.50.145000000 PM
05-JAN-14 08.11.50.145000000 PM
...
are they really faster ?

256
SQL>
2
3
4
5
6

create or replace
function F return number is
begin
return 1;
end;
/

Function created.
SQL>
2
3
4
5
6
7

select sum(f)
from
( select level from dual
connect by level <= 1000 ),
( select level from dual
connect by level <= 1000 )
;

SUM(F)
---------1000000
Elapsed: 00:00:02.04

258
SQL>
2
3
4
5
6
7
8
9
10
11
12

with
function f1 return number is
begin
return 1;
end;
select sum(f1)
from
( select level from dual
connect by level <= 1000 ),
( select level from dual
connect by level <= 1000 )
/

SUM(F1)
---------1000000
Elapsed: 00:00:00.52
"but what about all my PLSQL !!!"

260
SQL>
2
3
4
5
6
7

create or replace
function F return number is
pragma udf;
begin
return 1;
end;
/

SQL>
2
3
4
5
6
7

select sum(f)
from
( select level from dual
connect by level <= 1000 ),
( select level from dual
connect by level <= 1000 )
;

SUM(F)
---------1000000
Elapsed: 00:00:00.36
Feature
top-n simplifications

262
"5 most recently hired employees"

263
SQL>
2
3
4

select empno, ename, hiredate
from emp
where rownum <= 5
order by hiredate desc;

EMPNO
---------7654
7566
7521
7499
7369

ENAME
---------MARTIN
JONES
WARD
ALLEN
SMITH

HIREDATE
------------------28/09/1981 00:00:00
02/04/1981 00:00:00
22/02/1981 00:00:00
20/02/1981 00:00:00
17/12/1980 00:00:00

264
SQL>
2
3
4

select empno, ename, hiredate
from emp
where rownum <= 5
order by hiredate desc;

EMPNO
---------7654
7566
7521
7499
7369

ENAME
---------MARTIN
JONES
WARD
ALLEN
SMITH

HIREDATE
------------------28/09/1981 00:00:00
02/04/1981 00:00:00
22/02/1981 00:00:00
20/02/1981 00:00:00
17/12/1980 00:00:00

264
inline view

265
SQL>
2
3
4
5
6
7

select *
from (
select empno, ename, hiredate
from emp
order by hiredate desc
)
where rownum <= 2;

EMPNO
---------7876
7788

ENAME
---------ADAMS
SCOTT

HIREDATE
--------23-MAY-87
19-APR-87

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

267
SQL>
2
3
4
5
6
7
8

select *
from (
select
empno, ename, hiredate,
row_number() over ( order by hiredate desc) rn
from emp
)
where rn <= 2;

268
------------------------------------------------| 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"<=2)
2 - filter(ROW_NUMBER() OVER
( ORDER BY HIREDATE") DESC )<=2)

269
12c .... "easier"

270
SQL>
2
3
4

select empno, ename, hiredate
from emp
order by hiredate desc
fetch first 2 rows only;

EMPNO
---------7876
7788

ENAME
---------ADAMS
SCOTT

HIREDATE
--------23-MAY-87
19-APR-87

271
behind the scenes

272
------------------------------------------------| 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"<=2)

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

274
SQL>
2
3
4

select empno, ename, hiredate
from emp
order by hiredate desc
fetch first 1 row only;

EMPNO ENAME
HIREDATE
---------- ---------- --------7876 ADAMS
23-MAY-87

275
SQL>
2
3
4

select empno, ename, hiredate
from emp
order by hiredate desc
fetch first 5 row only;

EMPNO
---------7876
7788
7934
7900
7902

ENAME
---------ADAMS
SCOTT
MILLER
JAMES
FORD

HIREDATE
--------23-MAY-87
19-APR-87
23-JAN-82
03-DEC-81
03-DEC-81

276
SQL>
2
3
4

select empno, ename, hiredate
from emp
order by hiredate desc
fetch first 10 percent rows only;

EMPNO
---------7876
7788

ENAME
---------ADAMS
SCOTT

HIREDATE
--------23-MAY-87
19-APR-87

277
pagination

278
SQL>
2
3
4

select empno, ename, hiredate
from emp
order by hiredate desc
offset 5 rows fetch next 3 rows only;

EMPNO
---------7839
7654
7844

ENAME
---------KING
MARTIN
TURNER

HIREDATE
--------17-NOV-81
28-SEP-81
08-SEP-81

279
can mimic rownum

280
SQL> select empno, ename, hiredate
2 from emp
4

fetch first 3 rows only;

EMPNO
---------7369
7499
7521

ENAME
---------SMITH
ALLEN
WARD

HIREDATE
--------17-DEC-80
20-FEB-81
22-FEB-81

281
----------------------------------------------| 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

282
idiosyncracies

283
SQL>
2
3
4

select empno, ename, hiredate
from emp
order by hiredate desc
fetch LAST 5 rows only;

fetch LAST 5 rows only
*
ERROR at line 4:
ORA-00905: missing keyword

284
SQL>
2
3
4
5
6
7
8

select *
from (
select empno, ename, hiredate
from emp
order by hiredate asc
fetch first 5 rows only
)
order by hiredate desc;

EMPNO
---------7698
7566
7521
7499
7369

ENAME
---------BLAKE
JONES
WARD
ALLEN
SMITH

HIREDATE
--------01-MAY-81
02-APR-81
22-FEB-81
20-FEB-81
17-DEC-80

285
or ...

286
SQL>
2
3
4
5

select empno, ename, hiredate
from emp
order by hiredate desc
offset ( select count(*)-5 from emp) rows
fetch first 5 rows only;

EMPNO
---------7698
7566
7521
7499
7369

ENAME
---------BLAKE
JONES
WARD
ALLEN
SMITH

HIREDATE
--------01-MAY-81
02-APR-81
22-FEB-81
20-FEB-81
17-DEC-80

287
---------------------------------------------| 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
288
no percent pagination

289
SQL>
2
3
4
5

select empno, ename, hiredate
from emp
order by hiredate desc
offset 20 percent fetch
next 10 percent rows only;

offset 20 percent fetch next 10 percent rows only
*
ERROR at line 4:
ORA-00905: missing keyword

290
SQL>
2
3
4
5
6

select empno, ename, hiredate
from emp
order by hiredate desc
offset
( select 20/100*count(*) from emp) rows
fetch next 10 percent rows only;

EMPNO
---------7934
7902

ENAME
---------MILLER
FORD

HIREDATE
--------23-JAN-82
03-DEC-81

291
plsql quirk

292
"Note that in real life,
you would use bind variables
instead of hard-coded literals"
- Tom Kyte,
Oracle Magazine, Sep 13
293
"why" in next session

294
SQL> variable x number
SQL> exec :x := 5
PL/SQL procedure successfully completed.
SQL>
2
3
4

select empno, ename, hiredate
from emp
order by hiredate desc
fetch first :x rows only;

EMPNO
---------7876
7788
7934
7900
7902

ENAME
---------ADAMS
SCOTT
MILLER
JAMES
FORD

HIREDATE
--------23-MAY-87
19-APR-87
23-JAN-82
03-DEC-81
03-DEC-81
295
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 /
declare
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel
Process ID: 26618
Session ID: 25 Serial number: 53023
296
SQL>
2
3
4
5
6
7
8
9
10
11
12
13
14

declare
l_num number := 5;
begin
for i in (
select empno, ename, hiredate
from emp
order by hiredate desc
fetch first cast(l_num as number) rows only
)
loop
null;
end loop;
end;
/

PL/SQL procedure successfully completed.

297
Feature
join enhancements
11.2

299
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

300
but ANSI syntax works …

301
12c

302
SQL>
2
3
4
5
6
7
8

select *
from emp e,
emp2 e2,
dept d
where e.deptno = d.deptno(+)
and
e2.deptno = d.deptno(+)
and
e.empno = e2.empno
/

EMPNO ENAME
JOB
MGR
---------- ---------- --------- ---------7934 MILLER
CLERK
7782
...

303
correlated inline views

304
SQL> drop table DEPT_BENEFITS purge;
Table dropped.
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.

305
SQL>
2
3
4
5

select e.empno, e.deptno, d.benefits
from
emp e,
DEPT_BENEFITS d
where e.deptno = d.deptno
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
...
...

306
"benefits for each employee"

307
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

308
CROSS APPLY

309
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
...
...
"big deal"

311
SQL> select e.empno,
2 from
emp e,
3
( select
4
from
5
where
6
) b
7
8 order by 1,3;

d.deptno, b.benefits
benefits
DEPT_BENEFITS d
d.deptno = e.deptno

312
SQL>
2
3
4
5
6
7
8

select e.empno, d.deptno, b.benefits
from
emp e,
( select benefits
from
DEPT_BENEFITS d
) b
where d.deptno = e.deptno
order by 1,3;

312
"best benefit for each employee"

313
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
...

314
Feature
adaptive plans

315
SQL> create table PARENT ( p int, pdata varchar2(20) );
Table created.
SQL> create table CHILD ( c int, p int, cdata char(200));
Table created.
SQL>
2
3
4

insert into PARENT
select rownum*2+1, rownum
from
dual
connect by level <= 500;

500 rows created.

SQL>
2
3
4

insert into CHILD
select rownum, mod(rownum,1000)*2, rownum
from
dual
connect by level < 10000;

9999 rows created.

316
SQL> exec dbms_stats.gather_table_stats('','PARENT')
PL/SQL procedure successfully completed.
SQL> exec dbms_stats.gather_table_stats('','CHILD')

PL/SQL procedure successfully completed.
SQL> create index CHILD_IX on CHILD ( p ) ;
Index created.
SQL> select count(*) from PARENT
2 where p < 10;
COUNT(*)
---------4
317
SQL> set autotrace traceonly explain
SQL>
2
3
4
5

select *
from
PARENT p,
CHILD c
where p.p < 10
and
p.p = c.p;

--------------------------------------------------------| Id | Operation
| Name
| Rows |
--------------------------------------------------------|
0 | SELECT STATEMENT
|
|
4 |
|
1 | NESTED LOOPS
|
|
|
|
2 |
NESTED LOOPS
|
|
4 |
|* 3 |
TABLE ACCESS FULL
| PARENT
|
4 |
|* 4 |
INDEX RANGE SCAN
| CHILD_IX |
1 |
|
5 |
TABLE ACCESS BY INDEX ROWID| CHILD
|
1 |
--------------------------------------------------------Note
----- this is an adaptive plan
318
now lets mess with it

319
SQL>
2
3
4

insert into PARENT
select mod(rownum,5)*2+1, rownum
from dual
connect by level <= 20000;

20000 rows created.
SQL> commit;
Commit complete.
SQL> select count(*) from PARENT
2 where p < 10;
COUNT(*)
---------20004

320
a new cursor

321
SQL>
2
3
4
5

select /*+ gather_plan_statistics */ *
from
CHILD c,
PARENT p
where p.p < 10
and
p.p = c.p;

no rows selected
SQL> select *
2 from table(
3
dbms_xplan.display_cursor(
4
null,null,'ALLSTATS LAST +ADAPTIVE'));

322
----------------------------------------------------------|
Id | Operation
| Name
|
----------------------------------------------------------|
0 | SELECT STATEMENT
|
|
| * 1 | HASH JOIN
|
|
|2 |
NESTED LOOPS
|
|
|3 |
NESTED LOOPS
|
|
|4 |
STATISTICS COLLECTOR
|
|
| * 5 |
TABLE ACCESS FULL
| PARENT
|
|- * 6 |
INDEX RANGE SCAN
| CHILD_IX |
|7 |
TABLE ACCESS BY INDEX ROWID
| CHILD
|
|
8 |
TABLE ACCESS BY INDEX ROWID BATCHED| CHILD
|
| * 9 |
INDEX RANGE SCAN
| CHILD_IX |
-----------------------------------------------------------
----------------------------------------------------------|
Id | Operation
| Name
|
----------------------------------------------------------|
0 | SELECT STATEMENT
|
|
| * 1 | HASH JOIN
|
|
|2 |
NESTED LOOPS
|
|
|3 |
NESTED LOOPS
|
|
|4 |
STATISTICS COLLECTOR
|
|
| * 5 |
TABLE ACCESS FULL
| PARENT
|
|- * 6 |
INDEX RANGE SCAN
| CHILD_IX |
|7 |
TABLE ACCESS BY INDEX ROWID
| CHILD
|
|
8 |
TABLE ACCESS BY INDEX ROWID BATCHED| CHILD
|
| * 9 |
INDEX RANGE SCAN
| CHILD_IX |
-----------------------------------------------------------
----------------------------------------------------------|
Id | Operation
| Name
|
----------------------------------------------------------|
0 | SELECT STATEMENT
|
|
| * 1 | HASH JOIN
|
|
|2 |
NESTED LOOPS
|
|
|3 |
NESTED LOOPS
|
|
|4 |
STATISTICS COLLECTOR
|
|
| * 5 |
TABLE ACCESS FULL
| PARENT
|
|- * 6 |
INDEX RANGE SCAN
| CHILD_IX |
|7 |
TABLE ACCESS BY INDEX ROWID
| CHILD
|
|
8 |
TABLE ACCESS BY INDEX ROWID BATCHED| CHILD
|
| * 9 |
INDEX RANGE SCAN
| CHILD_IX |
-----------------------------------------------------------
----------------------------------------------------------|
Id | Operation
| Name
|
----------------------------------------------------------|
0 | SELECT STATEMENT
|
|
| * 1 | HASH JOIN
|
|
|2 |
NESTED LOOPS
|
|
|3 |
NESTED LOOPS
|
|
|4 |
STATISTICS COLLECTOR
|
|
| * 5 |
TABLE ACCESS FULL
| PARENT
|
|- * 6 |
INDEX RANGE SCAN
| CHILD_IX |
|7 |
TABLE ACCESS BY INDEX ROWID
| CHILD
|
|
8 |
TABLE ACCESS BY INDEX ROWID BATCHED| CHILD
|
| * 9 |
INDEX RANGE SCAN
| CHILD_IX |
-----------------------------------------------------------
SQL> select *
2 from table(
3
dbms_xplan.display_cursor(
4
null,null,'ALLSTATS LAST'));
--------------------------------------------------------| Id | Operation
| Name
|
--------------------------------------------------------|
0 | SELECT STATEMENT
|
|
|* 1 | HASH JOIN
|
|
|* 2 |
TABLE ACCESS FULL
| PARENT
|
|
3 |
TABLE ACCESS BY INDEX ROWID BATCHED| CHILD
|
|* 4 |
INDEX RANGE SCAN
| CHILD_IX |
--------------------------------------------------------Note
----- this is an adaptive plan

327
just be aware

328
tools will (hopefully) catch up

329
Feature
invisible columns

330
have been there "forever"

331
function based indexes

332
set column unused

333
SQL> create table T
2
( x int,
3
y int);
Table created.
SQL> create index IX on T (x+0);
Index created.
SQL> alter table T set unused column Y;
Table altered.

334
SQL>
2
3
4

select
from
where
order

column_name, data_default
USER_TAB_COLS
table_name = 'T'
by column_id;

COLUMN_NAME
DATA_DEFAULT
------------------------------ ---------------X
SYS_NC00003$
"X"+0
SYS_C00002_14020720:50:28$

335
now exposed to us

336
SQL> create table T ( c1 int, c2 int, c3 int );
SQL> desc T
Name
Null?
---------------------------- -------C1
C2
C3

Type
------NUMBER(38)
NUMBER(38)
NUMBER(38)

SQL> alter table T modify c1 invisible;
SQL> desc T
Name
Null?
---------------------------- -------C2
C3

Type
------NUMBER(38)
NUMBER(38)

337
and an idiosyncracy...

338
SQL> alter table T modify c1 visible;
SQL> desc T
Name
Null?
---------------------------- -------C2
C3
C1

Type
------NUMBER(38)
NUMBER(38)
NUMBER(38)

339
requires discipline

340
SQL>
2
3
4
5
6
7

create or replace
procedure P is
begin
insert into T (c1,c2,c3)
values (1,10,100);
end;
/

Procedure created.
SQL> exec P
PL/SQL procedure successfully completed.
SQL> alter table T modify c1 invisible;
Table altered.
SQL> alter table T modify c1 visible;

Table altered.
341
SQL> exec P
PL/SQL procedure successfully completed.

SQL> select * from T;
C2
C3
C1
---------- ---------- ---------10
100
1
1
10
100
SQL> desc T
Name
Null?
------------------- -------C2
C3
C1

Type
-------------------NUMBER(38)
NUMBER(38)
NUMBER(38)

342
SQL>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

create or replace
procedure FIX_COLS(p_tab varchar2, p_col_list varchar2) is
l_col_list varchar2(1000) := p_col_list||',';
type clist is table of varchar2(30)
index by pls_integer;
c clist;
l_col varchar2(30);
l_id int;
begin
while instr(l_col_list,',') > 1 loop
c(c.count+1) := substr(l_col_list,1,instr(l_col_list,',')-1);
l_col_list
:= substr(l_col_list,instr(l_col_list,',')+1);
dbms_output.put_line(c(c.count));
end loop;
for i in 1 .. c.count loop
loop
select column_name
into
l_col
from
user_tab_columns
where table_name = p_tab
and
column_id = i;
exit when l_col = c(i);
execute immediate 'alter table '||p_tab||' modify '||l_col||' invisible';
execute immediate 'alter table '||p_tab||' modify '||l_col||' visible';
end loop;
end loop;
end;
/

343
SQL> exec FIX_COLS('T','C1,C2,C3');
PL/SQL procedure successfully completed.
SQL> desc T
Name
Null?
---------------------------- -------C1
C2
C3

Type
------NUMBER(38)
NUMBER(38)
NUMBER(38)

344
so what's the appeal ?

345
rollout changes online

346
SQL> create table T ( c1 int, c2 int ) ;
Table created.

SQL>
2
3
4
5
6
7
8
9

create or replace
procedure APP1 is
begin
insert into T
select object_id, data_object_id
from
all_objects
where rownum < 10;
end;
/

Procedure created.
SQL> exec APP1;
PL/SQL procedure successfully completed.

347
new application

348
SQL> alter table T add c3 int;
Table altered.

SQL>
2
3
4
5
6
7
8
9
10
11

create or replace
procedure APP2 is
begin
for i in ( select c1,c2,c3 from T )
loop
dbms_output.put_line(i.c1);
dbms_output.put_line(i.c2);
dbms_output.put_line(i.c3);
end loop;
end;
/

Procedure created.

349
SQL> exec APP2;
28
28
15
15
29
29
25
25
54
PL/SQL procedure successfully completed.

350
351
SQL> exec APP1
BEGIN APP1; END;

*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00905: object SCOTT.APP1 is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

353
SQL> alter table T modify c3 invisible;
Table altered.

SQL> exec APP2;
28
28
15
15
29
29
25
25
54
PL/SQL procedure successfully completed.
SQL> exec APP1;

PL/SQL procedure successfully completed.
354
tools

355
SQL> create table T ( c1 int, c2 int invisible);
Table created.

SQL> desc T
Name
Null?
Type
------------------------- -------- -----------------C1
NUMBER(38)
SQL> set colinvisible ON
SQL> desc T
Name
Null?
------------------------- -------C1
C2 (INVISIBLE)

Type
----------NUMBER(38)
NUMBER(38)

356
357
SQL> alter table T add "C3 (INVISIBLE)" int;
Table altered.

358
SQL> alter table T add "C3 (INVISIBLE)" int;
Table altered.

SQL> desc T
Name
Null?
------------------------- -------C1
C3 (INVISIBLE)
C2 (INVISIBLE)

Type
-----------NUMBER(38)
NUMBER(38)
NUMBER(38)

358
and a whole lot more features

we didnt get to today ...

359
wrap up

396
there's a lot in 12c

397
lots not covered today

398
399

Más contenido relacionado

La actualidad más candente

Thomas+Niewel+ +Oracletuning
Thomas+Niewel+ +OracletuningThomas+Niewel+ +Oracletuning
Thomas+Niewel+ +Oracletuning
afa reg
 
Upgrade 10204-to-10205 on-2-node_rac_linux_x86_64_detail-steps_v0.1
Upgrade 10204-to-10205 on-2-node_rac_linux_x86_64_detail-steps_v0.1Upgrade 10204-to-10205 on-2-node_rac_linux_x86_64_detail-steps_v0.1
Upgrade 10204-to-10205 on-2-node_rac_linux_x86_64_detail-steps_v0.1
Raheel Syed
 
Mha procedure
Mha procedureMha procedure
Mha procedure
Louis liu
 

La actualidad más candente (19)

PostgreSQL Portland Performance Practice Project - Database Test 2 Tuning
PostgreSQL Portland Performance Practice Project - Database Test 2 TuningPostgreSQL Portland Performance Practice Project - Database Test 2 Tuning
PostgreSQL Portland Performance Practice Project - Database Test 2 Tuning
 
A close encounter_with_real_world_and_odd_perf_issues
A close encounter_with_real_world_and_odd_perf_issuesA close encounter_with_real_world_and_odd_perf_issues
A close encounter_with_real_world_and_odd_perf_issues
 
Rmoug ashmaster
Rmoug ashmasterRmoug ashmaster
Rmoug ashmaster
 
Thomas+Niewel+ +Oracletuning
Thomas+Niewel+ +OracletuningThomas+Niewel+ +Oracletuning
Thomas+Niewel+ +Oracletuning
 
PostgreSQL Portland Performance Practice Project - Database Test 2 Howto
PostgreSQL Portland Performance Practice Project - Database Test 2 HowtoPostgreSQL Portland Performance Practice Project - Database Test 2 Howto
PostgreSQL Portland Performance Practice Project - Database Test 2 Howto
 
Upgrade 10204-to-10205 on-2-node_rac_linux_x86_64_detail-steps_v0.1
Upgrade 10204-to-10205 on-2-node_rac_linux_x86_64_detail-steps_v0.1Upgrade 10204-to-10205 on-2-node_rac_linux_x86_64_detail-steps_v0.1
Upgrade 10204-to-10205 on-2-node_rac_linux_x86_64_detail-steps_v0.1
 
Let's scale-out PostgreSQL using Citus (English)
Let's scale-out PostgreSQL using Citus (English)Let's scale-out PostgreSQL using Citus (English)
Let's scale-out PostgreSQL using Citus (English)
 
Variations on PostgreSQL Replication
 Variations on PostgreSQL Replication Variations on PostgreSQL Replication
Variations on PostgreSQL Replication
 
Patch
PatchPatch
Patch
 
A deep dive about VIP,HAIP, and SCAN
A deep dive about VIP,HAIP, and SCAN A deep dive about VIP,HAIP, and SCAN
A deep dive about VIP,HAIP, and SCAN
 
Mha procedure
Mha procedureMha procedure
Mha procedure
 
Debunking myths about_redo_ppt
Debunking myths about_redo_pptDebunking myths about_redo_ppt
Debunking myths about_redo_ppt
 
Rac introduction
Rac introductionRac introduction
Rac introduction
 
Powervc upgrade from_1.3.0.2_to_1.3.2.0
Powervc upgrade from_1.3.0.2_to_1.3.2.0Powervc upgrade from_1.3.0.2_to_1.3.2.0
Powervc upgrade from_1.3.0.2_to_1.3.2.0
 
Optimizer Cost Model MySQL 5.7
Optimizer Cost Model MySQL 5.7Optimizer Cost Model MySQL 5.7
Optimizer Cost Model MySQL 5.7
 
Connor McDonald Partitioning
Connor McDonald PartitioningConnor McDonald Partitioning
Connor McDonald Partitioning
 
Rac 12c optimization
Rac 12c optimizationRac 12c optimization
Rac 12c optimization
 
Xen server 6.0 xe command reference (1.1)
Xen server 6.0 xe command reference (1.1)Xen server 6.0 xe command reference (1.1)
Xen server 6.0 xe command reference (1.1)
 
Ash masters : advanced ash analytics on Oracle
Ash masters : advanced ash analytics on Oracle Ash masters : advanced ash analytics on Oracle
Ash masters : advanced ash analytics on Oracle
 

Destacado (8)

Transaction unit1 topic 2
Transaction unit1 topic 2Transaction unit1 topic 2
Transaction unit1 topic 2
 
Locks with updt nowait
Locks with updt nowaitLocks with updt nowait
Locks with updt nowait
 
Transaction unit 1 topic 4
Transaction unit 1 topic 4Transaction unit 1 topic 4
Transaction unit 1 topic 4
 
Locking unit 1 topic 3
Locking unit 1 topic 3Locking unit 1 topic 3
Locking unit 1 topic 3
 
Troubleshooting Complex Performance issues - Oracle SEG$ contention
Troubleshooting Complex Performance issues - Oracle SEG$ contentionTroubleshooting Complex Performance issues - Oracle SEG$ contention
Troubleshooting Complex Performance issues - Oracle SEG$ contention
 
分区表基础知识培训
分区表基础知识培训分区表基础知识培训
分区表基础知识培训
 
Transaction concurrency control
Transaction concurrency controlTransaction concurrency control
Transaction concurrency control
 
Transaction management
Transaction managementTransaction management
Transaction management
 

Similar a 12c for Developers - Feb 2014

11thingsabout11g 12659705398222 Phpapp01
11thingsabout11g 12659705398222 Phpapp0111thingsabout11g 12659705398222 Phpapp01
11thingsabout11g 12659705398222 Phpapp01
Karam Abuataya
 
Oracle Basics and Architecture
Oracle Basics and ArchitectureOracle Basics and Architecture
Oracle Basics and Architecture
Sidney Chen
 
DB2UDB_the_Basics Day 4
DB2UDB_the_Basics Day 4DB2UDB_the_Basics Day 4
DB2UDB_the_Basics Day 4
Pranav Prakash
 

Similar a 12c for Developers - Feb 2014 (20)

Connor McDonald 11g for developers
Connor McDonald 11g for developersConnor McDonald 11g for developers
Connor McDonald 11g for developers
 
Percona xtra db cluster(pxc) non blocking operations, what you need to know t...
Percona xtra db cluster(pxc) non blocking operations, what you need to know t...Percona xtra db cluster(pxc) non blocking operations, what you need to know t...
Percona xtra db cluster(pxc) non blocking operations, what you need to know t...
 
11thingsabout11g 12659705398222 Phpapp01
11thingsabout11g 12659705398222 Phpapp0111thingsabout11g 12659705398222 Phpapp01
11thingsabout11g 12659705398222 Phpapp01
 
11 Things About11g
11 Things About11g11 Things About11g
11 Things About11g
 
Oracle Basics and Architecture
Oracle Basics and ArchitectureOracle Basics and Architecture
Oracle Basics and Architecture
 
Oracle Database 12c Application Development
Oracle Database 12c Application DevelopmentOracle Database 12c Application Development
Oracle Database 12c Application Development
 
SQL Macros - Game Changing Feature for SQL Developers?
SQL Macros - Game Changing Feature for SQL Developers?SQL Macros - Game Changing Feature for SQL Developers?
SQL Macros - Game Changing Feature for SQL Developers?
 
SQL techniques for faster applications
SQL techniques for faster applicationsSQL techniques for faster applications
SQL techniques for faster applications
 
Sangam 2019 - The Latest Features
Sangam 2019 - The Latest FeaturesSangam 2019 - The Latest Features
Sangam 2019 - The Latest Features
 
Les12 creating views
Les12 creating viewsLes12 creating views
Les12 creating views
 
Flashback ITOUG
Flashback ITOUGFlashback ITOUG
Flashback ITOUG
 
DB2UDB_the_Basics Day 4
DB2UDB_the_Basics Day 4DB2UDB_the_Basics Day 4
DB2UDB_the_Basics Day 4
 
Sqlplus
SqlplusSqlplus
Sqlplus
 
Deep review of LMS process
Deep review of LMS processDeep review of LMS process
Deep review of LMS process
 
Oracle Database SQL Tuning Concept
Oracle Database SQL Tuning ConceptOracle Database SQL Tuning Concept
Oracle Database SQL Tuning Concept
 
Oracle trace data collection errors: the story about oceans, islands, and rivers
Oracle trace data collection errors: the story about oceans, islands, and riversOracle trace data collection errors: the story about oceans, islands, and rivers
Oracle trace data collection errors: the story about oceans, islands, and rivers
 
UKOUG 2019 - SQL features
UKOUG 2019 - SQL featuresUKOUG 2019 - SQL features
UKOUG 2019 - SQL features
 
OpenWorld 2018 - Common Application Developer Disasters
OpenWorld 2018 - Common Application Developer DisastersOpenWorld 2018 - Common Application Developer Disasters
OpenWorld 2018 - Common Application Developer Disasters
 
Analytic SQL Sep 2013
Analytic SQL Sep 2013Analytic SQL Sep 2013
Analytic SQL Sep 2013
 
حل اسئلة الكتاب السعودى فى شرح قواعد البيانات اوراكل
حل اسئلة الكتاب السعودى فى شرح قواعد البيانات اوراكلحل اسئلة الكتاب السعودى فى شرح قواعد البيانات اوراكل
حل اسئلة الكتاب السعودى فى شرح قواعد البيانات اوراكل
 

Más de Connor McDonald

Más de Connor McDonald (20)

Sangam 19 - PLSQL still the coolest
Sangam 19 - PLSQL still the coolestSangam 19 - PLSQL still the coolest
Sangam 19 - PLSQL still the coolest
 
Sangam 19 - Analytic SQL
Sangam 19 - Analytic SQLSangam 19 - Analytic SQL
Sangam 19 - Analytic SQL
 
UKOUG - 25 years of hints and tips
UKOUG - 25 years of hints and tipsUKOUG - 25 years of hints and tips
UKOUG - 25 years of hints and tips
 
Sangam 19 - Successful Applications on Autonomous
Sangam 19 - Successful Applications on AutonomousSangam 19 - Successful Applications on Autonomous
Sangam 19 - Successful Applications on Autonomous
 
APEX tour 2019 - successful development with autonomous
APEX tour 2019 - successful development with autonomousAPEX tour 2019 - successful development with autonomous
APEX tour 2019 - successful development with autonomous
 
APAC Groundbreakers 2019 - Perth/Melbourne
APAC Groundbreakers 2019 - Perth/Melbourne APAC Groundbreakers 2019 - Perth/Melbourne
APAC Groundbreakers 2019 - Perth/Melbourne
 
OOW19 - Flashback, not just for DBAs
OOW19 - Flashback, not just for DBAsOOW19 - Flashback, not just for DBAs
OOW19 - Flashback, not just for DBAs
 
OOW19 - Read consistency
OOW19 - Read consistencyOOW19 - Read consistency
OOW19 - Read consistency
 
OOW19 - Slower and less secure applications
OOW19 - Slower and less secure applicationsOOW19 - Slower and less secure applications
OOW19 - Slower and less secure applications
 
OOW19 - Killing database sessions
OOW19 - Killing database sessionsOOW19 - Killing database sessions
OOW19 - Killing database sessions
 
OOW19 - Ten Amazing SQL features
OOW19 - Ten Amazing SQL featuresOOW19 - Ten Amazing SQL features
OOW19 - Ten Amazing SQL features
 
Latin America Tour 2019 - 18c and 19c featues
Latin America Tour 2019   - 18c and 19c featuesLatin America Tour 2019   - 18c and 19c featues
Latin America Tour 2019 - 18c and 19c featues
 
Latin America tour 2019 - Flashback
Latin America tour 2019 -  FlashbackLatin America tour 2019 -  Flashback
Latin America tour 2019 - Flashback
 
Latin America Tour 2019 - 10 great sql features
Latin America Tour 2019  - 10 great sql featuresLatin America Tour 2019  - 10 great sql features
Latin America Tour 2019 - 10 great sql features
 
Latin America Tour 2019 - pattern matching
Latin America Tour 2019 - pattern matchingLatin America Tour 2019 - pattern matching
Latin America Tour 2019 - pattern matching
 
Latin America Tour 2019 - slow data and sql processing
Latin America Tour 2019  - slow data and sql processingLatin America Tour 2019  - slow data and sql processing
Latin America Tour 2019 - slow data and sql processing
 
ANSI vs Oracle language
ANSI vs Oracle languageANSI vs Oracle language
ANSI vs Oracle language
 
OG Yatra - upgrading to the new 12c+ optimizer
OG Yatra - upgrading to the new 12c+ optimizerOG Yatra - upgrading to the new 12c+ optimizer
OG Yatra - upgrading to the new 12c+ optimizer
 
OG Yatra - 25 years of hints and tips
OG Yatra - 25 years of hints and tipsOG Yatra - 25 years of hints and tips
OG Yatra - 25 years of hints and tips
 
OG Yatra - Flashback, not just for developers
OG Yatra - Flashback, not just for developersOG Yatra - Flashback, not just for developers
OG Yatra - Flashback, not just for developers
 

Último

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Último (20)

Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 

12c for Developers - Feb 2014

  • 1. NOTE itty bitty fonts in this presentation SQL> exec sample_font Can you read this ? 1
  • 3. 3
  • 5.
  • 10. 6
  • 13. 9
  • 16.
  • 17. there's a lot in 12c ! 13
  • 18. but not widely advertised 14
  • 22. some not so cool things.... 18
  • 24. tough for "home" exploring 20
  • 25. SQL> create user DEV_TESTING 2 identified by MYPASS; create user DEV_TESTING identified by MYPASS * ERROR at line 1: ORA-65096: invalid common user or role name ? 21
  • 27. 23
  • 28. or let someone else do it 24
  • 30. 26
  • 34.
  • 35.
  • 36. why talk about it ? 31
  • 37. we've all done it... 32
  • 38. site to site to site... 33
  • 40. SQL> desc T Name ----------------------------OWNER OBJECT_NAME Null? -------NOT NULL NOT NULL Type ------------VARCHAR2(30) VARCHAR2(30) SQL> desc T_AUDIT Name ----------------------------AUDIT_DATE AUDIT_ACTION OWNER OBJECT_NAME Null? Type -------- -------------DATE CHAR(1) NOT NULL VARCHAR2(30) NOT NULL VARCHAR2(30) 35
  • 41. SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 create or replace trigger AUDIT_TRG after insert or update or delete on T for each row declare v_action varchar2(1) := case when updating then 'U' when deleting then 'D' else 'I' end; begin if updating or inserting then insert into T_AUDIT values (sysdate ,v_action ,:new.owner ,:new.object_name); else insert into T_AUDIT values (sysdate ,v_action ,:old.owner ,:old.object_name); end if; end; / Trigger created. 36
  • 44. SQL> insert 2 select 3 from insert where 4 into T into T owner, object_name all_objects rownum <= 10000; select owner, object_name from all_objects 10000 rownum <= 10000 rows created. where call count ------- -----Parse 1 Execute 1 Fetch 0 ------- -----total 2 cpu elapsed disk query current ------- ---------- -------- --------- ---------0.01 0.00 0 0 0 3.10 3.05 88 123 10642 0.00 0.00 0 0 0 ------- ---------- -------- --------- ---------3.12 3.06 88 123 10642 rows ---------0 10000 0 ---------10000 INSERT INTO T_AUDIT VALUES (SYSDATE ,:B3 ,:B1 ,:B2 ) call count ------- -----Parse 1 Execute 10000 Fetch 0 ------- -----total 10001 cpu elapsed disk query current ------- ---------- -------- --------- ---------0.00 0.00 0 0 0 0.79 0.97 2 109 10845 0.00 0.00 0 0 0 ------- ---------- -------- --------- ---------0.79 0.97 2 109 10845 rows ---------0 10000 0 ---------10000 38
  • 45. if you were dilligent 39
  • 49. a better, faster, robust version ... 49
  • 51. SQL> create tablespace SPACE_FOR_ARCHIVE 2 datafile 'C:ORACLEDB11ARCH_SPACE.DBF' 3 size 100M; Tablespace created. 51
  • 52. SQL> CREATE FLASHBACK ARCHIVE longterm 2 TABLESPACE space_for_archive 3 RETENTION 1 YEAR; Flashback archive created. 52
  • 53. SQL> ALTER TABLE EMP FLASHBACK ARCHIVE LONGTERM; Table altered. [lots of DML] 53
  • 54. SQL> select * from EMP; -------------------------------------------------| Id | Operation | Name | Rows | Bytes | -------------------------------------------------| 0 | SELECT STATEMENT | | 14 | 518 | | 1 | TABLE ACCESS FULL| EMP | 14 | 518 | -------------------------------------------------- 54
  • 55. SQL> select * from EMP 2 AS OF TIMESTAMP SYSDATE-3; -------------------------------------------------| Id | Operation | Name | Rows | Bytes | -------------------------------------------------| 0 | SELECT STATEMENT | | 14 | 518 | | 1 | TABLE ACCESS FULL| EMP | 14 | 518 | -------------------------------------------------- 55
  • 56. [after DML and time passing] SQL> select * from EMP 2 AS OF TIMESTAMP SYSDATE-3; ----------------------------------------------------------------| Id | Operation | Name | Rows | ----------------------------------------------------------------| 0 | SELECT STATEMENT | | 446 | | 1 | VIEW | | 446 | | 2 | UNION-ALL | | | |* 3 | FILTER | | | | 4 | PARTITION RANGE ITERATOR| | 445 | |* 5 | TABLE ACCESS FULL | SYS_FBA_HIST_69539 | 445 | |* 6 | FILTER | | | |* 7 | HASH JOIN OUTER | | 1 | |* 8 | TABLE ACCESS FULL | EMP | 1 | |* 9 | TABLE ACCESS FULL | SYS_FBA_TCRV_69539 | 14 | ------------------------------------------------------------------ 56
  • 57. SQL> select table_name 2 from user_tables 3 / TABLE_NAME --------------------------SYS_FBA_HIST_71036 SYS_FBA_TCRV_71036 SYS_FBA_DDL_COLMAP_71036 EMP 57
  • 58. but can also be your audit ! 58
  • 59. SQL> alter table EMP add 2 LAST_MOD timestamp default systimestamp; SQL> update EMP 2 set sal = sal*10 3 where empno = 7369; SQL> delete from EMP 2 where empno = 7934; SQL> update EMP 2 set job = 'SALES' 3 where ename = 'SMITH'; SQL> update EMP 2 set comm = 1000 3 where empno = 7369; SQL> commit; 59
  • 60. SQL> 2 3 4 5 6 7 8 select empno, ename, job, sal, comm, nvl(VERSIONS_STARTTIME,LAST_MOD) TS ,nvl(VERSIONS_OPERATION,'I') op from EMP versions between timestamp timestamp '2014-02-11 20:12:00' and systimestamp order by empno; EMPNO ---------7369 7369 7499 7521 7566 ... 7900 7902 7934 7934 ENAME ---------SMITH SMITH ALLEN WARD JONES JOB SAL COMM TS --------- ---------- ---------- -----------CLERK 806 08.10.51 PM SALES 8060 1000 08.12.10 PM SALESMAN 1606 300000000 08.10.51 PM SALESMAN 1256 500000000 08.10.51 PM MANAGER 2981 08.10.51 PM O I U I I I JAMES FORD MILLER MILLER CLERK ANALYST CLERK CLERK I I I D 956 3006 1306 1306 08.10.51 08.10.51 08.10.51 08.12.10 PM PM PM PM 60
  • 61. so why didn't we ? 61
  • 63. "yeah...but who ? where ? how ?" 63
  • 64. SQL> alter table EMP add UPDATED_BY varchar2(10); Table altered. SQL> alter table EMP add UPDATED_PGM varchar2(10); Table altered. [etc] [etc] 64
  • 66.
  • 68. can 12c help ? 68
  • 70. SQL> begin 2 dbms_flashback_archive.set_context_level( 3 level=> 'ALL'); 4 end; PL/SQL procedure successfully completed. 70
  • 71. SQL> update EMP 2 set sal = sal*10 3 where empno = 7499; 1 row updated. SQL> commit; 71
  • 72. SQL> select XID from SYS_FBA_HIST_510592; XID ---------------09000B00C7080000 72
  • 73. SQL> set serverout on SQL> begin 2 dbms_output.put_line( 3 dbms_flashback_archive.get_sys_context ( 4 '09000B00C7080000', 'USERENV', 'SESSION_USER')); 5 6 dbms_output.put_line( 7 dbms_flashback_archive.get_sys_context ( 8 '09000B00C7080000', 'USERENV', 'HOST')); 9 10 dbms_output.put_line( 11 dbms_flashback_archive.get_sys_context ( 12 '09000B00C7080000', 'USERENV', 'MODULE')); 13 end; 14 / SCOTT WORKGROUPXPS SQL*Plus 73
  • 74. 74
  • 75. SQL> desc SYS.SYS_FBA_CONTEXT_AUD Name Null? ------------------------- -------XID ACTION AUTHENTICATED_IDENTITY CLIENT_IDENTIFIER CLIENT_INFO CURRENT_EDITION_NAME CURRENT_SCHEMA CURRENT_USER DATABASE_ROLE DB_NAME GLOBAL_UID HOST IDENTIFICATION_TYPE INSTANCE_NAME IP_ADDRESS MODULE OS_USER SERVER_HOST SERVICE_NAME Type -----------------RAW(8) VARCHAR2(256) VARCHAR2(256) VARCHAR2(256) VARCHAR2(256) VARCHAR2(256) VARCHAR2(256) VARCHAR2(256) VARCHAR2(256) VARCHAR2(256) VARCHAR2(256) VARCHAR2(256) VARCHAR2(256) VARCHAR2(256) VARCHAR2(256) VARCHAR2(256) VARCHAR2(256) VARCHAR2(256) VARCHAR2(256) 75
  • 77. SQL> @pt "select * from SYS.SYS_FBA_CONTEXT_AUD where xid = '09000B00C7080000'" XID AUTHENTICATED_IDENTITY CLIENT_IDENTIFIER CLIENT_INFO CURRENT_EDITION_NAME CURRENT_SCHEMA CURRENT_USER DATABASE_ROLE DB_NAME HOST IDENTIFICATION_TYPE INSTANCE_NAME MODULE OS_USER SERVER_HOST SERVICE_NAME SESSION_EDITION_NAME SESSION_USER SESSION_USERID SESSIONID TERMINAL : : : : : : : : : : : : : : : : : : : : : 09000B00C7080000 scott ORA$BASE SYS SYS PRIMARY np12 WORKGROUPXPS LOCAL np12 SQL*Plus xpshamcdc xps SYS$USERS ORA$BASE SCOTT 103 230698 XPS 77
  • 78. SQL> 2 3 4 5 6 7 select empno, ename, job, sal, comm, VERSIONS_XID from EMP versions between timestamp timestamp '2014-02-11 20:12:00' and systimestamp order by empno; EMPNO ---------7369 7369 7499 7499 7499 7521 ENAME ---------SMITH SMITH ALLEN ALLEN ALLEN WARD JOB SAL COMM VERSIONS_XID --------- ---------- ---------- ---------------CLERK 806 SALES 8060 1000 09001C00E04A0000 CLERK 16060 300000000 0A000A0024080000 SALESMAN 16060 300000000 09000B00C7080000 SALESMAN 1606 300000000 SALESMAN 1256 500000000 78
  • 79. SQL> 2 3 4 5 6 7 8 9 10 11 select ... from ( select empno, ename, job, sal, comm, VERSIONS_XID from EMP versions between timestamp timestamp '2014-02-11 20:12:00' and systimestamp ) e, SYS.SYS_FBA_CONTEXT_AUD a where e.VERSIONS_XID = a.XID; 79
  • 80. keep an eye on space SYSTEM tablespace 80
  • 81. 2) 81
  • 82. total recall is now … 75
  • 85. oracle feature that is free ! 78
  • 88. so think about total recall 81
  • 94. SQL> ALTER TABLE EMP FLASHBACK ARCHIVE LONGTERM; Table altered. Flashback Archive: Error ORA-1950 in SQL create table "SCOTT".SYS_FBA_DDL_COLMAP_91938 (STARTSCN NUMBER, ENDSCN NUMBER... Flashback Archive: Error ORA-942 in SQL insert into "SCOTT".SYS_FBA_DDL_COLMAP_91938 (ENDSCN, COLUMN_NAME, TYPE, ... Flashback Archive: Error ORA-942 in SQL "select count(*) from "SCOTT".SYS_FBA_DDL_COLMAP_91938" 94
  • 96. SQL> create table PARENT ( p int primary key ); Table created. SQL> create table CHILD 2 ( c int primary key, 3 p int references PARENT ( p ) 4 ); Table created. SQL> insert into PARENT values (1); 1 row created. SQL> insert into CHILD values (1,1); 1 row created. 89
  • 97. SQL> truncate table PARENT; truncate table PARENT * ERROR at line 1: ORA-02266: unique/primary keys in table referenced by enabled foreign keys 90
  • 98. SQL> create table CHILD 2 ( c int primary key, 3 p int references PARENT ( p ) 4 on delete cascade); Table created. SQL> insert into PARENT values (1); 1 row created. SQL> insert into CHILD values (1,1); 1 row created. SQL> truncate table PARENT; truncate table PARENT * ERROR at line 1: ORA-02266: unique/primary keys in table referenced by enabled foreign keys 91
  • 100. SQL> truncate table PARENT cascade; Table truncated. 93
  • 101. must be on delete cascade 94
  • 102. SQL> alter table child modify 2 constraint CHILD_FK on delete cascade; ERROR at line 1: ORA-00933: SQL command not properly ended SQL> alter table child add 2 constraint NEW_FK foreign key ( p ) 3 references parent ( p ) on delete cascade; ERROR at line 1: ORA-02275: such a referential constraint already exists in the table 95
  • 106. SQL> create sequence SESS_SEQ session; Sequence created. 99
  • 107. SQL> select sess_seq.nextval from dual; NEXTVAL ---------1 SQL> conn scott/tiger Connected. SQL> select sess_seq.nextval from dual; NEXTVAL ---------1 100
  • 110. SQL> select X 2 from GTT; SQL> select X 2 from GTT; X ---------1 2 3 4 5 6 7 8 9 ... X ---------1 2 3 4 5 6 7 8 9 ... 103
  • 113. SQL> create sequence NORMAL cache 1000; Sequence created. SQL> alter session set sql_trace = true; Session altered. SQL> 2 3 4 insert into GTT select SESS_SEQ.NEXTVAL from dual connect by level < 50000; 49999 rows created. SQL> 2 3 4 insert into GTT select NORMAL.NEXTVAL from dual connect by level < 50000; 49999 rows created. 106
  • 114. insert into GTT select NORMAL.NEXTVAL from dual connect by level < 50000 call count ------- -----Parse 1 Execute 1 Fetch 0 ------- -----total 2 cpu elapsed disk query current -------- ---------- ---------- ---------- ---------0.00 0.00 0 0 0 0.35 0.35 0 147 642 0.00 0.00 0 0 0 -------- ---------- ---------- ---------- ---------0.35 0.35 0 147 642 rows ---------0 49999 0 ---------49999 107
  • 115. insert into GTT select SESS_SEQ.NEXTVAL from dual connect by level < 50000 call count ------- -----Parse 1 Execute 1 Fetch 0 ------- -----total 2 cpu elapsed disk query current -------- ---------- ---------- ---------- ---------0.00 0.00 0 0 0 0.25 0.25 0 145 592 0.00 0.00 0 0 0 -------- ---------- ---------- ---------- ---------0.25 0.25 0 145 592 rows ---------0 49999 0 ---------49999 108
  • 116. update SEQ$ set increment$=:2,minvalue=:3,maxvalue=:4, cycle#=:5,order$=:6, cache=:7,highwater=:8,audit$=:9, flags=:10,partcount=:11 where obj#=:1 call count ------- -----Parse 1 Execute 50 Fetch 0 ------- -----total 51 cpu elapsed disk query current -------- ---------- ---------- ---------- ---------0.00 0.00 0 0 0 0.00 0.00 0 50 103 0.00 0.00 0 0 0 -------- ---------- ---------- ---------- ---------0.00 0.00 0 50 103 rows ---------0 50 0 ---------50 109
  • 118. the most common ... 111
  • 119. and the absolute worst ... 112
  • 121. SQL> create sequence seq; Sequence created. SQL> create table T ( pk number , c1 int); Table created. SQL> 2 3 4 5 6 7 8 create or replace trigger FILL_IN_PK before insert on T for each row begin select seq.nextval into :new.pk from dual; end; / Trigger created. 114
  • 122. SQL> insert into T values (10,20); 1 row created. SQL> select * from T; PK C1 ---------- ---------1 20 115
  • 124. SQL> 2 3 4 5 6 7 8 9 create or replace trigger FILL_IN_PK before insert on T for each row when ( new.pk is null ) begin select seq.nextval into :new.pk from dual; end; / Trigger created. SQL> insert into T values (20,20); 1 row created. SQL> select * from T; PK C1 ---------- ---------1 20 20 20 117
  • 126. over rated ... for that stuff
  • 127. insert /* with trigger */ into T select rownum, rownum from dual connect by level <= 50000 call count ------- -----Parse 1 Execute 1 Fetch 0 ------- -----total 2 cpu elapsed disk query current -------- ---------- ---------- ---------- ---------0.00 0.00 0 0 0 5.64 5.64 0 466 1608 0.00 0.00 0 0 0 -------- ---------- ---------- ---------- ---------5.64 5.65 0 466 1608 rows ---------0 50000 0 ---------50000
  • 128. insert /* without trigger */ into T select rownum, rownum from dual connect by level <= 50000 call count ------- -----Parse 1 Execute 1 Fetch 0 ------- -----total 2 cpu elapsed disk query current -------- ---------- ---------- ---------- ---------0.00 0.00 0 0 0 0.09 0.15 0 466 1620 0.00 0.00 0 0 0 -------- ---------- ---------- ---------- ---------0.09 0.15 0 466 1620 rows ---------0 50000 0 ---------50000
  • 130. SQL> create table T ( pk number default seq.nextval , 2 c1 int); Table created. SQL> insert into T ( c1 ) values ( 0); SQL> select * from T; PK C1 ---------- ---------2 0 SQL> insert into T ( pk, c1 ) values (default, 1) ; SQL> select * from T; PK C1 ---------- ---------2 0 3 1 123
  • 131. insert /* with default */ into T select rownum, rownum from dual connect by level <= 50000 call count ------- -----Parse 1 Execute 1 Fetch 0 ------- -----total 2 cpu elapsed disk query current -------- ---------- ---------- ---------- ---------0.00 0.00 0 0 0 0.06 0.07 0 467 1608 0.00 0.00 0 0 0 -------- ---------- ---------- ---------- ---------0.06 0.08 0 467 1608 rows ---------0 50000 0 ---------50000
  • 134. SQL> drop table t purge; Table dropped. SQL> create table T 2 ( pk number generated as identity , 3 c1 int); Table created. SQL> select object_id, object_name, 2 object_type from user_objects; OBJECT_ID ---------414914 414915 OBJECT_NAME -----------------T ISEQ$$_414914 OBJECT_TYPE -----------TABLE SEQUENCE 127
  • 135. SQL> @pr "select * from user_sequences" SEQUENCE_NAME MIN_VALUE MAX_VALUE INCREMENT_BY CYCLE_FLAG ORDER_FLAG CACHE_SIZE LAST_NUMBER PARTITION_COUNT SESSION_FLAG KEEP_VALUE : : : : : : : : : : : ISEQ$$_414914 1 9999999999999999999999 1 N N 20 1 N N 128
  • 136. SQL> create table T 2 ( pk number 3 generated as identity (cache 1000) 4 , c1 int); Table created. SQL> insert into T values (1,2); insert into T values (1,2) * ERROR at line 1: ORA-32795: cannot insert into a generated always identity column can choose 129
  • 139. SQL> create table T ( 2 pk int, 3 status varchar2(1) default 'N' ); Table created. SQL> insert into T (pk) values (1); 1 row created. SQL> insert into T (pk, status) values (2,default); 1 row created. SQL> insert into T (pk, status) values (3,null); 1 row created. 132
  • 140. SQL> select * from T; PK STATUS ---------- -----1 N 2 N 3 133
  • 142. SQL> 2 3 4 5 6 7 8 9 10 11 12 create or replace procedure ins(p_pk int, p_status varchar2) is begin if p_status is null then insert into T (pk, status) values (p_pk, default ); else insert into T (pk, status) values (p_pk, p_status ); end if; end; / Procedure created. 135
  • 144. SQL> create table T ( 2 pk int, 3 status varchar2(1) 4 start_date date 5 6 commission int 7 job_level int 8 ); default on null 'N' , default on null trunc(sysdate,'MM'), default on null 1000, default on null 1 Table created. SQL> insert into T values (1,null,null,null,null); 1 row created. SQL> select * from T; PK S START_DAT COMMISSION JOB_LEVEL ---------- - --------- ---------- ---------1 N 01-JAN-14 1000 1 137
  • 146. wtf
  • 148. "when" is a row valid 141
  • 149. SQL> CREATE TABLE 2 empno 3 name 4 sal 5 deptno 6 start_dt 7 end_dt 8 9 ); emp_temporal ( NUMBER, VARCHAR2(30), NUMBER, NUMBER, DATE, DATE, Table created. 142
  • 150. 12c part of the definition 143
  • 151. 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. 144
  • 153. SQL> select * from emp_temporal 2 order by empno, start_dt; EMPNO ---------7369 7369 7499 7499 7521 7521 7566 7566 7654 7654 7698 NAME SAL DEPTNO START_DT END_DT ------------ ---------- ---------- --------- --------SMITH 806 20 01-JAN-14 01-MAR-14 SMITHX 8060 21 02-MAR-14 01-OCT-14 ALLEN 1606 30 01-JAN-14 01-MAR-14 ALLENX 16060 31 02-MAR-14 01-OCT-14 WARD 1256 30 01-JAN-14 01-MAR-14 WARDX 12560 31 02-MAR-14 01-OCT-14 JONES 2981 20 01-JAN-14 01-MAR-14 JONESX 29810 21 02-MAR-14 01-OCT-14 MARTIN 1256 30 01-JAN-14 01-MAR-14 MARTINX 12560 31 02-MAR-14 01-OCT-14 BLAKE 2856 30 01-JAN-14 01-MAR-14 146
  • 154. SQL> select * from emp_temporal 2 as of period for valid_range '01-FEB-14'; EMPNO ---------7369 7499 7521 7566 7654 NAME SAL DEPTNO START_DT END_DT ------------ ---------- ---------- --------- --------SMITH 806 20 01-JAN-14 01-MAR-14 ALLEN 1606 30 01-JAN-14 01-MAR-14 WARD 1256 30 01-JAN-14 01-MAR-14 JONES 2981 20 01-JAN-14 01-MAR-14 MARTIN 1256 30 01-JAN-14 01-MAR-14 147
  • 158. SQL> set autotrace traceonly stat SQL> select * from MY_VIEW 2 where CREATED > sysdate Statistics -----------------------------------------651 recursive calls 0 db block gets 2243 consistent gets 24 physical reads 151
  • 159. SQL> variable c clob SQL> begin 2 dbms_utility.expand_sql_text 3 ( 'select * from MY_VIEW'|| 4 'where created > sysdate',:c); 5 end; 6 / PL/SQL procedure successfully completed. SQL> print c 152
  • 160. SQL> 2 3 4 5 6 7 8 9 10 11 12 create or replace view MY_VIEW as select o.owner, o.created, s.bytes, s.tablespace_name from dba_segments s, all_objects o where o.owner = s.owner and o.object_name = s.segment_name; View created. 153
  • 161. 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", 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", 154
  • 162. "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", DECODE("A4"."BUFFER_POOL_ID",1,'KEEP',2,'RECYCLE','DEFAULT') "BUFFER_POOL", DECODE("A4"."FLASH_CACHE",1,'KEEP',2, 'NONE','DEFAULT') "FLASH_CACHE",DECODE("A4"."CELL_FLASH_CACHE",1,'KEEP',2,'NONE','DEFAULT') "CELL_FLASH_CACHE" FROM ( (SELECT NVL("A199"."NAME",'SYS') "OWNER", "A198"."NAME" "SEGMENT_NAME", 155
  • 163. "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'),N ULL)) "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"."G ROUPS",0,1, "A195"."GROUPS")) "FREELIST_GROUPS", "A195"."FILE#" "RELATIVE_FNO",BITAND("A195"."CACHEHINT",3) "BUFFER_POOL_ID", BITAND("A195"."CACHEHINT",12)/4 "FLASH_CACHE",BITAND("A195"."CACHEHINT",48)/16 "CELL_FLASH_CACHE", NVL("A195"."SPARE1",0) "SEGMENT_FLAGS",DECODE(BITAND("A195"."SPARE1",1),1, "A195"."HWMINCR", "A198"."DATAOBJ#") "SEGMENT_OBJD" FROM "SYS"."USER$" "A199", "SYS"."OBJ$" "A198", "SYS"."TS$" "A197", ( (SELECT 156
  • 164. 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 "A206"."TYPE#"=7 OR "A206"."TYPE#"=8 OR "A206"."TYPE#"=9) UNION ALL (SELECT 'INDEX PARTITION' "OBJECT_TYPE",20 "OBJECT_TYPE_ID",6 "SEGMENT_TYPE_ID", "A205"."OBJ#" "OBJECT_ID", "A205"."FILE#" "HEADER_FILE", "A205"."BLOCK#" "HEADER_BLOCK", 157
  • 165. "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", "SYS"."FILE$" "A194" WHERE "A195"."FILE#"="A196"."HEADER_FILE" AND "A195"."BLOCK#"="A196"."HEADER_BLOCK" AND "A195"."TS#"="A196"."TS_NUMBER" AND "A195"."TS#"="A197"."TS#" AND "A198"."OBJ#"="A196"."OBJECT_ID" AND "A198"."OWNER#"="A199"."USER#"(+) AND "A195"."TYPE#"="A196"."SEGMENT_TYPE_ID" AND "A198"."TYPE#"="A196"."OBJECT_TYPE_ID" AND "A195"."TS#"="A194"."TS#" AND 158
  • 166. "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("A190" ."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", "A191"."US#" "SEGMENT_OBJD" FROM "SYS"."USER$" "A193","SYS"."TS$" "A192", "SYS"."UNDO$" "A191", "SYS"."SEG$" "A190", "SYS"."FILE$" "A189" WHERE "A190"."FILE#"="A191"."FILE#" AND "A190"."BLOCK#"="A191"."BLOCK#" AND "A190"."TS#"="A191"."TS#" AND "A190"."TS#"="A192"."TS#" AND "A190"."USER#"="A193"."USER#"(+) AND ("A190"."TYPE#"=1 OR "A190"."TYPE#"=10) AND "A191"."STATUS$"<>1 AND 159
  • 167. "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("A186" ."LISTS",0,1, "A186"."LISTS")) "FREELISTS",DECODE(BITAND("A187"."FLAGS",32),32,TO_NUMBER(NULL),DECODE("A186"."G ROUPS",0,1, "A186"."GROUPS")) "FREELIST_GROUPS", "A186"."FILE#" "RELATIVE_FNO",BITAND("A186"."CACHEHINT",3) "BUFFER_POOL_ID",BITAND("A186"."CACHEHINT",12)/4 "FLASH_CACHE",BITAND("A186"."CACHEHINT",48)/16 "CELL_FLASH_CACHE",NVL("A186"."SPARE1",0) "SEGMENT_FLAGS", "A186"."HWMINCR" "SEGMENT_OBJD" FROM "SYS"."USER$" "A188", "SYS"."TS$" "A187", "SYS"."SEG$" "A186", "SYS"."FILE$" "A185" WHERE "A186"."TS#"="A187"."TS#" AND "A186"."USER#"="A188"."USER#"(+) AND "A186"."TYPE#"<>1 AND "A186"."TYPE#"<>5 AND 160
  • 168. "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 ODE("A182"."LISTS",0,1, "A182"."LISTS")) "FREELISTS",DECODE(BITAND("A183"."FLAGS",32),32,TO_NUMBER(NULL),DECODE("A182"."G ROUPS",0,1, "A182"."GROUPS")) "FREELIST_GROUPS", "A182"."FILE#" "RELATIVE_FNO",BITAND("A182"."CACHEHINT",3) "BUFFER_POOL_ID", BITAND("A182"."CACHEHINT",12)/4 "FLASH_CACHE",BITAND("A18 2"."CACHEHINT",48)/16 "CELL_FLASH_CACHE",NVL("A182"."SPARE1",0) "SEGMENT_FLAGS", "A182"."HWMINCR" "SEGMENT_OBJD" FROM "SYS"."USER$" "A184", 161
  • 169. "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", "A6"."MTIME" "LAST_DDL_TIME",TO_CHAR("A6"."STIME",'YYYY-MM-DD:HH24:MI:SS') "TIMESTAMP",DEC ODE("A6"."STATUS",0,'N/A',1,'VALID','INVALID') "STATUS",DECODE(BITAND("A6"."FLAGS",2),0,'N',2,'Y','N') "TEMPORARY",DECODE(BITAND("A6"."FLAGS",4),0,'N',4,'Y','N') "GENERATED",DECODE(BITAND("A6"."FLAGS",16),0,'N',16,'Y','N') "SECONDARY", "A6"."NAMESPACE" "NAMESPACE", "A6"."DEFINING_EDITION" "EDITION_NAM E",DECODE(BITAND("A6"."FLAGS",196608),65536,'METADATA LINK',131072,'OBJECT LINK','NONE') "SHARING", CASE WHEN ("A6"."TYPE#"=4 OR "A6"."TYPE#"=5 OR 162
  • 171. back to temporal validity 164
  • 172. 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 /
  • 173. 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" 166
  • 175. SQL> desc EMPLOYEE Name Null? ------------------------- -------EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO Type --------------NUMBER(4) VARCHAR2(10) VARCHAR2(9) NUMBER(4) DATE NUMBER(7,2) NUMBER(12,2) NUMBER(2) SQL> alter table EMPLOYEE add period for TIME_RANGE; Table altered. 168
  • 176. SQL> desc EMPLOYEE Name Null? ------------------------- -------EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO Type --------------NUMBER(4) VARCHAR2(10) VARCHAR2(9) NUMBER(4) DATE NUMBER(7,2) NUMBER(12,2) NUMBER(2) still looks the same ? 169
  • 177. SQL> 2 3 4 select column_name , hidden_column from user_tab_cols where table_name = 'EMPLOYEE' order by column_id; COLUMN_NAME -----------------------------EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO TIME_RANGE_START TIME_RANGE_END TIME_RANGE HIDDEN_COLUMN ------------NO NO NO NO NO NO NO NO YES YES YES 170
  • 179. SQL> alter table EMP_TEMPORAL add period for CAL_RANGE; Table altered. SQL> alter table EMP_TEMPORAL add period for FINYR_RANGE; Table altered. 172
  • 180. maybe a 12.x feature ? 173
  • 182. 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 175
  • 183. add START_DT to primary key ?
  • 185. 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.
  • 187. SQL> 2 3 4 update EMP_TEMPORAL as of period for valid_range '01-FEB-14' set sal = 10 where empno = 20; as of period for valid_range '01-FEB-14' * ERROR at line 2: ORA-08187: snapshot expression not allowed here
  • 188. 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. 181
  • 189. and one more issue…
  • 190. "Temporal validity is not supported with a multitenant container database" 183
  • 192. it all starts off easy 185
  • 193. SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 create or replace procedure P is x int; y int; begin x := 10; select into from where count(*) y all_objects object_name = 'NUFFIN'; x := x / y; select rownum into x from dual; end; / Procedure created. 186
  • 194. SQL> exec P; BEGIN P; END; * ERROR at line 1: ORA-01476: divisor is equal to zero ORA-06512: at "SCOTT.P", line 13 ORA-06512: at line 1 187
  • 195. SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 create or replace procedure P is x int; y int; begin x := 10; select into from where count(*) y all_objects object_name = 'NUFFIN'; x := x / y; select rownum into x from dual; end; / Procedure created. 188
  • 196. ... and downhill from there
  • 197. SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 create or replace procedure P is x int; y int; begin x := 10; select into from where count(*) y all_objects object_name = 'NUFFIN'; x := x / y; select rownum into x from dual; exception when others then log_error; raise; end; / 190
  • 198. SQL> exec P; BEGIN P; END; * ERROR at line 1: ORA-01476: divisor is equal to zero ORA-06512: at "SCOTT.P", line 22
  • 199. SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 create or replace procedure P is x int; y int; begin x := 10; select into from where count(*) y all_objects object_name = 'NUFFIN'; ? x := x / y; select rownum into x from dual; exception when others then log_error; raise; end; / 192
  • 200. SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 create or replace procedure P is x int; y int; begin x := 10; select into from where count(*) y all_objects object_name = 'NUFFIN'; x := x / y; select rownum into x from dual; exception when others then dbms_output.put_line( dbms_utility.format_call_stack); raise; end; /
  • 201. SQL> exec P; ----- PL/SQL Call Stack ----object line object handle number name 0x14b1e3900 21 procedure SCOTT.P 0x12521b8d8 1 anonymous block BEGIN P; END; * ERROR at line 1: ORA-01476: divisor is equal to zero ORA-06512: at "SCOTT.P", line 23 ORA-06512: at line 1 194
  • 202. SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 create or replace procedure P is x int; y int; l_debug varchar2(4000); begin l_debug := dbms_utility.format_call_stack; x := 10; l_debug := dbms_utility.format_call_stack; select count(*) into y from all_objects where object_name = 'NUFFIN'; l_debug := dbms_utility.format_call_stack; x := x / y; l_debug := dbms_utility.format_call_stack; select rownum into x from dual; exception when others then dbms_output.put_line(l_debug); raise; end;
  • 203. SQL> exec P; ----- PL/SQL Call Stack ----object line object handle number name 0x14b1e3900 16 procedure SCOTT.P 0x12521b8d8 1 anonymous block BEGIN P; END; * ERROR at line 1: ORA-01476: divisor is equal to zero ORA-06512: at "SCOTT.P", line 27 ORA-06512: at line 1 196
  • 204. SQL> create or replace procedure P is 2 x int; 3 y int; 4 l_debug varchar2(4000); 5 begin 6 l_debug := dbms_utility.format_call_stack; 7 ... 24 25 26 27 28 29 30 31 exception when others then l_debug := substr(l_debug,instr(l_debug,chr(10),1,3)); l_debug := regexp_replace(l_debug,chr(10)||'.*$'); dbms_output.put_line(l_debug); raise; end; /
  • 205. SQL> exec P; 0x14b1e3900 BEGIN P; END; 16 procedure SCOTT.P * ERROR at line 1: ORA-01476: divisor is equal to zero ORA-06512: at "SCOTT.P", line 29 ORA-06512: at line 1 198
  • 208. SQL> create or replace procedure P is 2 x int; 3 y int; 4 l_debug varchar2(4000); 5 begin 6 l_debug := dbms_utility.format_call_stack; 7 8 x := 10; 9 ... 23 24 exception 25 when others then 26 dbms_output.put_line( 27 DBMS_UTILITY.FORMAT_ERROR_BACKTRACE ); 28 raise; 29 end;
  • 209. SQL> exec P; ORA-06512: at "SCOTT.P", line 17 BEGIN P; END; * ERROR at line 1: ORA-01476: divisor is equal to zero ORA-06512: at "SCOTT.P", line 27 ORA-06512: at line 1 202
  • 213. SQL> create or replace procedure P is 2 x int; 3 y int; 4 begin 5 x := 10; 6 ... 17 18 exception 19 when others then 20 for i in 1 .. utl_call_stack.dynamic_depth loop 21 dbms_output.put_line( 22 utl_call_stack.unit_line(i)||'-'|| 23 utl_call_stack.concatenate_subprogram( 24 utl_call_stack.subprogram(i)) 25 ); 26 end loop; 27 raise; 28 end; 206
  • 214. SQL> exec P; 16-P 1-__anonymous_block BEGIN P; END; * ERROR at line 1: ORA-01476: divisor is equal to zero ORA-06512: at "SCOTT.P", line 27 ORA-06512: at line 1
  • 215. value in "real world" 208
  • 216. SQL> create or replace package PKG is 2 procedure p; 3 procedure p1; 4 procedure p2; 5 procedure p3; 6 end; 7 / Package created.
  • 217. SQL> create or replace package body PKG is 2 3 procedure p is ... 19 20 exception 21 when others then 22 for i in 1 .. utl_call_stack.dynamic_depth loop 23 dbms_output.put_line( 24 utl_call_stack.unit_line(i)||'-'|| 25 utl_call_stack.concatenate_subprogram( 26 utl_call_stack.subprogram(i)) 27 ); 28 end loop; 29 raise; 30 end; 31 32 procedure p1 is begin p; end; 33 procedure p2 is begin p1; end; 34 procedure p3 is begin p2; end; 35 36 end; 37 / 210
  • 218. SQL> exec pkg.p3 23-PKG.P 32-PKG.P1 33-PKG.P2 34-PKG.P3 1-__anonymous_block BEGIN pkg.p3; END; * ERROR at line 1: ORA-01476: divisor is equal to zero ORA-06512: at "SCOTT.PKG", line 29 ORA-06512: at "SCOTT.PKG", line 32 ORA-06512: at "SCOTT.PKG", line 33 ORA-06512: at "SCOTT.PKG", line 34 ORA-06512: at line 1
  • 219. did you miss it ? 212
  • 220. SQL> exec pkg.p3 23-PKG.P 32-PKG.P1 33-PKG.P2 34-PKG.P3 1-__anonymous_block subprogram !!! BEGIN pkg.p3; END; * ERROR at line 1: ORA-01476: divisor is equal to zero ORA-06512: at "SCOTT.PKG", line 29 ORA-06512: at "SCOTT.PKG", line 32 ORA-06512: at "SCOTT.PKG", line 33 ORA-06512: at "SCOTT.PKG", line 34 ORA-06512: at line 1
  • 223. ... I've worked on 216
  • 226. SQL> select surname 2 from names; SURNAME -----------------------------jones brown SMITH sigh...
  • 227. "no problem.... I'll use initcap" 220
  • 228. SQL> select initcap(surname) 2 from names; INITCAP(SURNAME) -----------------------------Jones Brown Smith
  • 230. SQL> select initcap(surname) 2 from names; INITCAP(SURNAME) -----------------------------Jones Brown Smith Mcdonald Johnson'S uh oh
  • 232. SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 create or replace function my_initcap(p_string varchar2) return varchar2 is l_string varchar2(1000) := p_string; begin if regexp_like(l_string,'(Mac[A-Z]|Mc[A-Z])') then null; elsif l_string like '''%' then null; else l_string := initcap(l_string); if l_string like '_''S%' then null; else l_string := replace(l_string,'''S','''s'); end if; end if; return l_string; end; / Function created.
  • 234. SQL> select my_initcap(surname) 2 from names; MY_INITCAP(SURNAME) -------------------------Jones Brown Smith McDonald Johnson's
  • 236.
  • 237. "don't call PLSQL from SQL !!!!" 230
  • 238. SQL> select max(x) 2 from ( 3 select /*+ no_merge */ initcap(source) x 4 from sys.source$ 5 ); ... Elapsed: 00:00:00.48
  • 239. SQL> select max(x) 2 from ( 3 select /*+ no_merge */ initcap(source) x 4 from sys.source$ 5 ); ... SQL> select max(x) 2 from ( Elapsed: select /*+ no_merge */ my_initcap(source) x 00:00:00.48 3 4 from sys.source$ 5 ); Elapsed: 00:00:09.37
  • 240. it can be done in SQL 232
  • 241. SQL> select 2 case 3 when regexp_like(surname,'(Mac[A-Z]|Mc[A-Z])') then surname 4 when surname like '''%' then surname 5 when initcap(surname) like '_''S%' then surname 6 else replace(initcap(surname),'''S','''s') 7 end ugh 8 from names; UGH !!! ------------------------------Jones Brown Smith McDonald Johnson's
  • 242. "Always code as if the person who ends up maintaining your code is a psychopathic killer who knows where you live." - source unknown 234
  • 243. 12c ... user defined functions
  • 244. SQL> WITH 2 function my_initcap(p_string varchar2) return varchar2 is 3 l_string varchar2(1000) := p_string; 4 begin 5 if regexp_like(l_string,'(Mac[A-Z]|Mc[A-Z])') then 6 null; 7 elsif l_string like '''%' then ... 17 18 return l_string; 19 end; 20 select my_initcap(surname) 21 from names; MY_INITCAP(SURNAME) ----------------------------------------Jones Brown Smith McDonald O'Brien Johnson's 236
  • 246. SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 WITH function is_scottish(p_string varchar2) return boolean is begin return regexp_like(p_string,'(Mac[A-Z]|Mc[A-Z])'); end; function my_initcap(p_string varchar2) return varchar2 is l_string varchar2(1000) := p_string; begin if is_scottish(l_string) then null; elsif l_string like '''%' then null; else l_string := initcap(l_string); if l_string like '_''S%' then null; else l_string := replace(l_string,'''S','''s'); end if; end if; return l_string; end; select my_initcap(surname) from names; / 238
  • 249. SQL> WITH 2 function my_initcap(p_string varchar2) return varchar2 is 3 l_string varchar2(1000) := p_string; function my_initcap(p_string varchar2) return varchar2 is * ERROR at line 2: ORA-06553: PLS-103: Encountered the symbol "end-of-file" when expecting one of the following: . ( * @ % & = - + ; < / > at in is mod remainder not rem <an exponent (**)> <> or != or ~= >= <= <> and or like like2 like4 likec between || multiset member submultiset SQL> 2 3 4 5 6 7 begin if regexp_like(l_string,'(Mac[A-Z]|Mc[A-Z])') then null; elsif l_string like '''%' then null; else l_string := initcap(l_string); 241
  • 251. and a blast from the past :-)
  • 252. SQL> create or replace 2 procedure NAMES_PROCESSOR is 3 cursor C is 4 WITH 5 function my_initcap(p_string varchar2) return varchar2 is 6 l_string varchar2(1000) := p_string; 7 begin ... 23 select my_initcap(surname) 24 from names; 25 begin 26 null; 27 end; 28 / Warning: Procedure created with compilation errors. SQL> sho err Errors for PROCEDURE NAMES_PROCESSOR: LINE/COL -------3/7 4/18 22/7 ERROR -----------------------------------------------PL/SQL: SQL Statement ignored PL/SQL: ORA-00905: missing keyword PLS-00103: Encountered the symbol "SELECT" 244
  • 253. SQL> create or replace 2 procedure NAMES_PROCESSOR is 3 rc sys_refcursor; 4 begin 5 open rc for 6 q'{ WITH 7 function my_initcap(p_string varchar2) return varchar2 is 8 l_string varchar2(1000) := p_string; 9 begin ... 23 return l_string; 24 end; 25 select my_initcap(surname) 26 from names 27 }'; 28 end; 29 / Procedure created.
  • 256. SQL> insert into NAMES2 2 WITH 3 function my_initcap(p_string varchar2) 4 return varchar2 is 5 l_string varchar2(1000) := p_string; 6 begin ... 20 end; 21 select my_initcap(surname) 22 from names; 23 / WITH * ERROR at line 2: ORA-32034: unsupported use of WITH clause 248
  • 257. SQL> insert /*+ WITH_PLSQL */ into NAMES2 2 WITH 3 function my_initcap(p_string varchar2) 4 return varchar2 is 5 l_string varchar2(1000) := p_string; 6 begin ... 20 end; 21 select my_initcap(surname) 22 from names; 23 / 5 rows inserted.
  • 259. SQL> 2 3 4 5 6 7 8 9 with function f return timestamp as begin return systimestamp; end; select f from dual connect by level <= 10; / F ---------------------------------------05-JAN-14 08.09.43.969000000 PM 05-JAN-14 08.09.43.970000000 PM 05-JAN-14 08.09.43.970000000 PM 05-JAN-14 08.09.43.971000000 PM ...
  • 261. SQL> 2 3 4 5 6 7 8 9 with function f return timestamp DETERMINISTIC as begin return systimestamp; end; select f from dual connect by level <= 10; / F ---------------------------------------05-JAN-14 08.09.52.145000000 PM 05-JAN-14 08.09.52.146000000 PM 05-JAN-14 08.09.52.146000000 PM 05-JAN-14 08.09.52.147000000 PM ...
  • 263. SQL> 2 3 4 5 6 7 8 9 with function f return timestamp as begin return systimestamp; end; select ( select f from dual ) from dual connect by level <= 10; / F ---------------------------------------05-JAN-14 08.11.50.145000000 PM 05-JAN-14 08.11.50.145000000 PM 05-JAN-14 08.11.50.145000000 PM 05-JAN-14 08.11.50.145000000 PM ...
  • 264. are they really faster ? 256
  • 265. SQL> 2 3 4 5 6 create or replace function F return number is begin return 1; end; / Function created.
  • 266. SQL> 2 3 4 5 6 7 select sum(f) from ( select level from dual connect by level <= 1000 ), ( select level from dual connect by level <= 1000 ) ; SUM(F) ---------1000000 Elapsed: 00:00:02.04 258
  • 267. SQL> 2 3 4 5 6 7 8 9 10 11 12 with function f1 return number is begin return 1; end; select sum(f1) from ( select level from dual connect by level <= 1000 ), ( select level from dual connect by level <= 1000 ) / SUM(F1) ---------1000000 Elapsed: 00:00:00.52
  • 268. "but what about all my PLSQL !!!" 260
  • 269. SQL> 2 3 4 5 6 7 create or replace function F return number is pragma udf; begin return 1; end; / SQL> 2 3 4 5 6 7 select sum(f) from ( select level from dual connect by level <= 1000 ), ( select level from dual connect by level <= 1000 ) ; SUM(F) ---------1000000 Elapsed: 00:00:00.36
  • 271. "5 most recently hired employees" 263
  • 272. SQL> 2 3 4 select empno, ename, hiredate from emp where rownum <= 5 order by hiredate desc; EMPNO ---------7654 7566 7521 7499 7369 ENAME ---------MARTIN JONES WARD ALLEN SMITH HIREDATE ------------------28/09/1981 00:00:00 02/04/1981 00:00:00 22/02/1981 00:00:00 20/02/1981 00:00:00 17/12/1980 00:00:00 264
  • 273. SQL> 2 3 4 select empno, ename, hiredate from emp where rownum <= 5 order by hiredate desc; EMPNO ---------7654 7566 7521 7499 7369 ENAME ---------MARTIN JONES WARD ALLEN SMITH HIREDATE ------------------28/09/1981 00:00:00 02/04/1981 00:00:00 22/02/1981 00:00:00 20/02/1981 00:00:00 17/12/1980 00:00:00 264
  • 275. SQL> 2 3 4 5 6 7 select * from ( select empno, ename, hiredate from emp order by hiredate desc ) where rownum <= 2; EMPNO ---------7876 7788 ENAME ---------ADAMS SCOTT HIREDATE --------23-MAY-87 19-APR-87 266
  • 276. -----------------------------------------------| Id | Operation | Name | Rows | -----------------------------------------------| 0 | SELECT STATEMENT | | 2 | |* 1 | COUNT STOPKEY | | | | 2 | VIEW | | 14 | |* 3 | SORT ORDER BY STOPKEY| | 14 | | 4 | TABLE ACCESS FULL | EMP | 14 | ------------------------------------------------ 267
  • 277. SQL> 2 3 4 5 6 7 8 select * from ( select empno, ename, hiredate, row_number() over ( order by hiredate desc) rn from emp ) where rn <= 2; 268
  • 278. ------------------------------------------------| 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"<=2) 2 - filter(ROW_NUMBER() OVER ( ORDER BY HIREDATE") DESC )<=2) 269
  • 280. SQL> 2 3 4 select empno, ename, hiredate from emp order by hiredate desc fetch first 2 rows only; EMPNO ---------7876 7788 ENAME ---------ADAMS SCOTT HIREDATE --------23-MAY-87 19-APR-87 271
  • 282. ------------------------------------------------| 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"<=2) 2 - filter(ROW_NUMBER() OVER ( ORDER BY HIREDATE") DESC )<=2) 273
  • 284. SQL> 2 3 4 select empno, ename, hiredate from emp order by hiredate desc fetch first 1 row only; EMPNO ENAME HIREDATE ---------- ---------- --------7876 ADAMS 23-MAY-87 275
  • 285. SQL> 2 3 4 select empno, ename, hiredate from emp order by hiredate desc fetch first 5 row only; EMPNO ---------7876 7788 7934 7900 7902 ENAME ---------ADAMS SCOTT MILLER JAMES FORD HIREDATE --------23-MAY-87 19-APR-87 23-JAN-82 03-DEC-81 03-DEC-81 276
  • 286. SQL> 2 3 4 select empno, ename, hiredate from emp order by hiredate desc fetch first 10 percent rows only; EMPNO ---------7876 7788 ENAME ---------ADAMS SCOTT HIREDATE --------23-MAY-87 19-APR-87 277
  • 288. SQL> 2 3 4 select empno, ename, hiredate from emp order by hiredate desc offset 5 rows fetch next 3 rows only; EMPNO ---------7839 7654 7844 ENAME ---------KING MARTIN TURNER HIREDATE --------17-NOV-81 28-SEP-81 08-SEP-81 279
  • 290. SQL> select empno, ename, hiredate 2 from emp 4 fetch first 3 rows only; EMPNO ---------7369 7499 7521 ENAME ---------SMITH ALLEN WARD HIREDATE --------17-DEC-80 20-FEB-81 22-FEB-81 281
  • 291. ----------------------------------------------| 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 282
  • 293. SQL> 2 3 4 select empno, ename, hiredate from emp order by hiredate desc fetch LAST 5 rows only; fetch LAST 5 rows only * ERROR at line 4: ORA-00905: missing keyword 284
  • 294. SQL> 2 3 4 5 6 7 8 select * from ( select empno, ename, hiredate from emp order by hiredate asc fetch first 5 rows only ) order by hiredate desc; EMPNO ---------7698 7566 7521 7499 7369 ENAME ---------BLAKE JONES WARD ALLEN SMITH HIREDATE --------01-MAY-81 02-APR-81 22-FEB-81 20-FEB-81 17-DEC-80 285
  • 296. SQL> 2 3 4 5 select empno, ename, hiredate from emp order by hiredate desc offset ( select count(*)-5 from emp) rows fetch first 5 rows only; EMPNO ---------7698 7566 7521 7499 7369 ENAME ---------BLAKE JONES WARD ALLEN SMITH HIREDATE --------01-MAY-81 02-APR-81 22-FEB-81 20-FEB-81 17-DEC-80 287
  • 297. ---------------------------------------------| 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 288
  • 299. SQL> 2 3 4 5 select empno, ename, hiredate from emp order by hiredate desc offset 20 percent fetch next 10 percent rows only; offset 20 percent fetch next 10 percent rows only * ERROR at line 4: ORA-00905: missing keyword 290
  • 300. SQL> 2 3 4 5 6 select empno, ename, hiredate from emp order by hiredate desc offset ( select 20/100*count(*) from emp) rows fetch next 10 percent rows only; EMPNO ---------7934 7902 ENAME ---------MILLER FORD HIREDATE --------23-JAN-82 03-DEC-81 291
  • 302. "Note that in real life, you would use bind variables instead of hard-coded literals" - Tom Kyte, Oracle Magazine, Sep 13 293
  • 303. "why" in next session 294
  • 304. SQL> variable x number SQL> exec :x := 5 PL/SQL procedure successfully completed. SQL> 2 3 4 select empno, ename, hiredate from emp order by hiredate desc fetch first :x rows only; EMPNO ---------7876 7788 7934 7900 7902 ENAME ---------ADAMS SCOTT MILLER JAMES FORD HIREDATE --------23-MAY-87 19-APR-87 23-JAN-82 03-DEC-81 03-DEC-81 295
  • 305. 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 / declare * ERROR at line 1: ORA-03113: end-of-file on communication channel Process ID: 26618 Session ID: 25 Serial number: 53023 296
  • 306. SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14 declare l_num number := 5; begin for i in ( select empno, ename, hiredate from emp order by hiredate desc fetch first cast(l_num as number) rows only ) loop null; end loop; end; / PL/SQL procedure successfully completed. 297
  • 309. 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 300
  • 310. but ANSI syntax works … 301
  • 312. SQL> 2 3 4 5 6 7 8 select * from emp e, emp2 e2, dept d where e.deptno = d.deptno(+) and e2.deptno = d.deptno(+) and e.empno = e2.empno / EMPNO ENAME JOB MGR ---------- ---------- --------- ---------7934 MILLER CLERK 7782 ... 303
  • 314. SQL> drop table DEPT_BENEFITS purge; Table dropped. 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. 305
  • 315. SQL> 2 3 4 5 select e.empno, e.deptno, d.benefits from emp e, DEPT_BENEFITS d where e.deptno = d.deptno 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 ... ... 306
  • 316. "benefits for each employee" 307
  • 317. 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 308
  • 319. 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 ... ...
  • 321. SQL> select e.empno, 2 from emp e, 3 ( select 4 from 5 where 6 ) b 7 8 order by 1,3; d.deptno, b.benefits benefits DEPT_BENEFITS d d.deptno = e.deptno 312
  • 322. SQL> 2 3 4 5 6 7 8 select e.empno, d.deptno, b.benefits from emp e, ( select benefits from DEPT_BENEFITS d ) b where d.deptno = e.deptno order by 1,3; 312
  • 323. "best benefit for each employee" 313
  • 324. 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 ... 314
  • 326. SQL> create table PARENT ( p int, pdata varchar2(20) ); Table created. SQL> create table CHILD ( c int, p int, cdata char(200)); Table created. SQL> 2 3 4 insert into PARENT select rownum*2+1, rownum from dual connect by level <= 500; 500 rows created. SQL> 2 3 4 insert into CHILD select rownum, mod(rownum,1000)*2, rownum from dual connect by level < 10000; 9999 rows created. 316
  • 327. SQL> exec dbms_stats.gather_table_stats('','PARENT') PL/SQL procedure successfully completed. SQL> exec dbms_stats.gather_table_stats('','CHILD') PL/SQL procedure successfully completed. SQL> create index CHILD_IX on CHILD ( p ) ; Index created. SQL> select count(*) from PARENT 2 where p < 10; COUNT(*) ---------4 317
  • 328. SQL> set autotrace traceonly explain SQL> 2 3 4 5 select * from PARENT p, CHILD c where p.p < 10 and p.p = c.p; --------------------------------------------------------| Id | Operation | Name | Rows | --------------------------------------------------------| 0 | SELECT STATEMENT | | 4 | | 1 | NESTED LOOPS | | | | 2 | NESTED LOOPS | | 4 | |* 3 | TABLE ACCESS FULL | PARENT | 4 | |* 4 | INDEX RANGE SCAN | CHILD_IX | 1 | | 5 | TABLE ACCESS BY INDEX ROWID| CHILD | 1 | --------------------------------------------------------Note ----- this is an adaptive plan 318
  • 329. now lets mess with it 319
  • 330. SQL> 2 3 4 insert into PARENT select mod(rownum,5)*2+1, rownum from dual connect by level <= 20000; 20000 rows created. SQL> commit; Commit complete. SQL> select count(*) from PARENT 2 where p < 10; COUNT(*) ---------20004 320
  • 332. SQL> 2 3 4 5 select /*+ gather_plan_statistics */ * from CHILD c, PARENT p where p.p < 10 and p.p = c.p; no rows selected SQL> select * 2 from table( 3 dbms_xplan.display_cursor( 4 null,null,'ALLSTATS LAST +ADAPTIVE')); 322
  • 333. ----------------------------------------------------------| Id | Operation | Name | ----------------------------------------------------------| 0 | SELECT STATEMENT | | | * 1 | HASH JOIN | | |2 | NESTED LOOPS | | |3 | NESTED LOOPS | | |4 | STATISTICS COLLECTOR | | | * 5 | TABLE ACCESS FULL | PARENT | |- * 6 | INDEX RANGE SCAN | CHILD_IX | |7 | TABLE ACCESS BY INDEX ROWID | CHILD | | 8 | TABLE ACCESS BY INDEX ROWID BATCHED| CHILD | | * 9 | INDEX RANGE SCAN | CHILD_IX | -----------------------------------------------------------
  • 334. ----------------------------------------------------------| Id | Operation | Name | ----------------------------------------------------------| 0 | SELECT STATEMENT | | | * 1 | HASH JOIN | | |2 | NESTED LOOPS | | |3 | NESTED LOOPS | | |4 | STATISTICS COLLECTOR | | | * 5 | TABLE ACCESS FULL | PARENT | |- * 6 | INDEX RANGE SCAN | CHILD_IX | |7 | TABLE ACCESS BY INDEX ROWID | CHILD | | 8 | TABLE ACCESS BY INDEX ROWID BATCHED| CHILD | | * 9 | INDEX RANGE SCAN | CHILD_IX | -----------------------------------------------------------
  • 335. ----------------------------------------------------------| Id | Operation | Name | ----------------------------------------------------------| 0 | SELECT STATEMENT | | | * 1 | HASH JOIN | | |2 | NESTED LOOPS | | |3 | NESTED LOOPS | | |4 | STATISTICS COLLECTOR | | | * 5 | TABLE ACCESS FULL | PARENT | |- * 6 | INDEX RANGE SCAN | CHILD_IX | |7 | TABLE ACCESS BY INDEX ROWID | CHILD | | 8 | TABLE ACCESS BY INDEX ROWID BATCHED| CHILD | | * 9 | INDEX RANGE SCAN | CHILD_IX | -----------------------------------------------------------
  • 336. ----------------------------------------------------------| Id | Operation | Name | ----------------------------------------------------------| 0 | SELECT STATEMENT | | | * 1 | HASH JOIN | | |2 | NESTED LOOPS | | |3 | NESTED LOOPS | | |4 | STATISTICS COLLECTOR | | | * 5 | TABLE ACCESS FULL | PARENT | |- * 6 | INDEX RANGE SCAN | CHILD_IX | |7 | TABLE ACCESS BY INDEX ROWID | CHILD | | 8 | TABLE ACCESS BY INDEX ROWID BATCHED| CHILD | | * 9 | INDEX RANGE SCAN | CHILD_IX | -----------------------------------------------------------
  • 337. SQL> select * 2 from table( 3 dbms_xplan.display_cursor( 4 null,null,'ALLSTATS LAST')); --------------------------------------------------------| Id | Operation | Name | --------------------------------------------------------| 0 | SELECT STATEMENT | | |* 1 | HASH JOIN | | |* 2 | TABLE ACCESS FULL | PARENT | | 3 | TABLE ACCESS BY INDEX ROWID BATCHED| CHILD | |* 4 | INDEX RANGE SCAN | CHILD_IX | --------------------------------------------------------Note ----- this is an adaptive plan 327
  • 339. tools will (hopefully) catch up 329
  • 341. have been there "forever" 331
  • 344. SQL> create table T 2 ( x int, 3 y int); Table created. SQL> create index IX on T (x+0); Index created. SQL> alter table T set unused column Y; Table altered. 334
  • 345. SQL> 2 3 4 select from where order column_name, data_default USER_TAB_COLS table_name = 'T' by column_id; COLUMN_NAME DATA_DEFAULT ------------------------------ ---------------X SYS_NC00003$ "X"+0 SYS_C00002_14020720:50:28$ 335
  • 346. now exposed to us 336
  • 347. SQL> create table T ( c1 int, c2 int, c3 int ); SQL> desc T Name Null? ---------------------------- -------C1 C2 C3 Type ------NUMBER(38) NUMBER(38) NUMBER(38) SQL> alter table T modify c1 invisible; SQL> desc T Name Null? ---------------------------- -------C2 C3 Type ------NUMBER(38) NUMBER(38) 337
  • 349. SQL> alter table T modify c1 visible; SQL> desc T Name Null? ---------------------------- -------C2 C3 C1 Type ------NUMBER(38) NUMBER(38) NUMBER(38) 339
  • 351. SQL> 2 3 4 5 6 7 create or replace procedure P is begin insert into T (c1,c2,c3) values (1,10,100); end; / Procedure created. SQL> exec P PL/SQL procedure successfully completed. SQL> alter table T modify c1 invisible; Table altered. SQL> alter table T modify c1 visible; Table altered. 341
  • 352. SQL> exec P PL/SQL procedure successfully completed. SQL> select * from T; C2 C3 C1 ---------- ---------- ---------10 100 1 1 10 100 SQL> desc T Name Null? ------------------- -------C2 C3 C1 Type -------------------NUMBER(38) NUMBER(38) NUMBER(38) 342
  • 353. SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 create or replace procedure FIX_COLS(p_tab varchar2, p_col_list varchar2) is l_col_list varchar2(1000) := p_col_list||','; type clist is table of varchar2(30) index by pls_integer; c clist; l_col varchar2(30); l_id int; begin while instr(l_col_list,',') > 1 loop c(c.count+1) := substr(l_col_list,1,instr(l_col_list,',')-1); l_col_list := substr(l_col_list,instr(l_col_list,',')+1); dbms_output.put_line(c(c.count)); end loop; for i in 1 .. c.count loop loop select column_name into l_col from user_tab_columns where table_name = p_tab and column_id = i; exit when l_col = c(i); execute immediate 'alter table '||p_tab||' modify '||l_col||' invisible'; execute immediate 'alter table '||p_tab||' modify '||l_col||' visible'; end loop; end loop; end; / 343
  • 354. SQL> exec FIX_COLS('T','C1,C2,C3'); PL/SQL procedure successfully completed. SQL> desc T Name Null? ---------------------------- -------C1 C2 C3 Type ------NUMBER(38) NUMBER(38) NUMBER(38) 344
  • 355. so what's the appeal ? 345
  • 357. SQL> create table T ( c1 int, c2 int ) ; Table created. SQL> 2 3 4 5 6 7 8 9 create or replace procedure APP1 is begin insert into T select object_id, data_object_id from all_objects where rownum < 10; end; / Procedure created. SQL> exec APP1; PL/SQL procedure successfully completed. 347
  • 359. SQL> alter table T add c3 int; Table altered. SQL> 2 3 4 5 6 7 8 9 10 11 create or replace procedure APP2 is begin for i in ( select c1,c2,c3 from T ) loop dbms_output.put_line(i.c1); dbms_output.put_line(i.c2); dbms_output.put_line(i.c3); end loop; end; / Procedure created. 349
  • 360. SQL> exec APP2; 28 28 15 15 29 29 25 25 54 PL/SQL procedure successfully completed. 350
  • 361. 351
  • 362.
  • 363. SQL> exec APP1 BEGIN APP1; END; * ERROR at line 1: ORA-06550: line 1, column 7: PLS-00905: object SCOTT.APP1 is invalid ORA-06550: line 1, column 7: PL/SQL: Statement ignored 353
  • 364. SQL> alter table T modify c3 invisible; Table altered. SQL> exec APP2; 28 28 15 15 29 29 25 25 54 PL/SQL procedure successfully completed. SQL> exec APP1; PL/SQL procedure successfully completed. 354
  • 366. SQL> create table T ( c1 int, c2 int invisible); Table created. SQL> desc T Name Null? Type ------------------------- -------- -----------------C1 NUMBER(38) SQL> set colinvisible ON SQL> desc T Name Null? ------------------------- -------C1 C2 (INVISIBLE) Type ----------NUMBER(38) NUMBER(38) 356
  • 367. 357
  • 368. SQL> alter table T add "C3 (INVISIBLE)" int; Table altered. 358
  • 369. SQL> alter table T add "C3 (INVISIBLE)" int; Table altered. SQL> desc T Name Null? ------------------------- -------C1 C3 (INVISIBLE) C2 (INVISIBLE) Type -----------NUMBER(38) NUMBER(38) NUMBER(38) 358
  • 370. and a whole lot more features we didnt get to today ... 359
  • 372. there's a lot in 12c 397
  • 373. lots not covered today 398
  • 374. 399