Mar11 11g Developers 7 Short

358
NOTE itty bitty fonts in this presentation SQL> exec sample_font Can you read this ? 1

Transcript of Mar11 11g Developers 7 Short

Page 1: Mar11 11g Developers 7 Short

NOTE

itty bitty fonts in this

presentation

SQL> exec sample_font

Can you read this ?

1

Page 2: Mar11 11g Developers 7 Short

Connor McDonald

OracleDBA

co

.uk

2

Page 3: Mar11 11g Developers 7 Short

3

Page 4: Mar11 11g Developers 7 Short

bio slide

4

Page 5: Mar11 11g Developers 7 Short

5

Page 6: Mar11 11g Developers 7 Short

6

Page 7: Mar11 11g Developers 7 Short

7

Page 8: Mar11 11g Developers 7 Short

"why bother?"

8

Page 9: Mar11 11g Developers 7 Short

2008 2009 2010 2011 2012 2013 2014 2016 2017

11g 11.1.0.7 11.2

management

visibility

11g

desupported

11.1.0.6

Page 10: Mar11 11g Developers 7 Short

"why bother?"

(part 2)

10

Page 11: Mar11 11g Developers 7 Short

don’t reinvent

Page 12: Mar11 11g Developers 7 Short
Page 13: Mar11 11g Developers 7 Short

13

there's a lot in 11g !

Page 14: Mar11 11g Developers 7 Short

14

some cool things....

Page 15: Mar11 11g Developers 7 Short

15

some not so cool things....

Page 16: Mar11 11g Developers 7 Short

16

g1

g2

g3

Page 17: Mar11 11g Developers 7 Short

17

"11g is now production"

Page 18: Mar11 11g Developers 7 Short

18

Page 19: Mar11 11g Developers 7 Short

19

11g ≠

Page 20: Mar11 11g Developers 7 Short

20

Page 21: Mar11 11g Developers 7 Short

21

cool-ness barometer

Page 22: Mar11 11g Developers 7 Short

22

first impressions

Page 23: Mar11 11g Developers 7 Short

23

Page 24: Mar11 11g Developers 7 Short

24

ORA-01017: invalid username/password; logon denied

Page 25: Mar11 11g Developers 7 Short

25

ORA-28000: the account is locked

Page 26: Mar11 11g Developers 7 Short

26

case sensitive passwords

Page 27: Mar11 11g Developers 7 Short

27

default profile tightened

Page 28: Mar11 11g Developers 7 Short

28

password complexity

Page 29: Mar11 11g Developers 7 Short

29

be patient

Page 30: Mar11 11g Developers 7 Short

30

Page 31: Mar11 11g Developers 7 Short

31

snippets

Page 32: Mar11 11g Developers 7 Short

32

snippets #1:

sqlplus BLOBS

Page 33: Mar11 11g Developers 7 Short

33

10g and below

Page 34: Mar11 11g Developers 7 Short

34

SQL> select PASSPORT_PHOTO

2 from PERSON

3 where surname = 'MCDONALD'

4 /

SP2-0678: Column type can not be displayed by SQL*Plus

Page 35: Mar11 11g Developers 7 Short

35

SQL> select PASSPORT_PHOTO

2 from PERSON

3 where surname = 'MCDONALD'

4 /

MUGSHOT_BLOB

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

D0CF11E0A1B11AE1000000000000000000000000000000003E000

02300000001000000FEFFFFFF0000000020000000

null versus empty_blob()

Page 36: Mar11 11g Developers 7 Short

36

snippets #2:

sqlplus error logging

Page 37: Mar11 11g Developers 7 Short

37

SQL> set errorlogging on

Page 38: Mar11 11g Developers 7 Short

38

SQL> set errorlogging on

SQL> desc SPERRORLOG

Name Type

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

USERNAME VARCHAR2(256)

TIMESTAMP TIMESTAMP(6)

SCRIPT VARCHAR2(1024)

IDENTIFIER VARCHAR2(256)

MESSAGE CLOB

STATEMENT CLOB

Page 39: Mar11 11g Developers 7 Short

39

SQL> select * from THE_WRONG_NAME;

select * from THE_WRONG_NAME

*

ERROR at line 1:

ORA-00942: table or view does not exist

SQL> desc THE_WRONG_NAME;

ERROR:

ORA-04043: object THE_WRONG_NAME does not exist

SQL> grant execute on P to NOT_A_USER;

grant execute on P to NOT_A_USER

*

ERROR at line 1:

ORA-01917: user or role 'NOT_A_USER' does not exist

Page 40: Mar11 11g Developers 7 Short

40

SQL> select timestamp, message, statement

2 from SPERRORLOG;

TIMESTAMP

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

MESSAGE

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

STATEMENT

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

01-APR-08 02.29.58.000000 PM

ORA-00942: table or view does not exist

select * from THE_WRONG_NAME

01-APR-08 02.29.58.000000 PM

ORA-04043: object THE_WRONG_NAME does not exist

desc THE_WRONG_NAME;

01-APR-08 02.30.04.000000 PM

ORA-01917: user or role "NOT_A_USER" does not exist

grant execute on P to NOT_A_USER

Page 41: Mar11 11g Developers 7 Short

41

installation scripts

SQL> set errorlogging on

SQL> @create_all_objects

works on 10g too…

Page 42: Mar11 11g Developers 7 Short

42

snippets #3:

sqlplus transaction safety

Page 43: Mar11 11g Developers 7 Short

43

Page 44: Mar11 11g Developers 7 Short

44

SQL> set exitcommit

Page 45: Mar11 11g Developers 7 Short

45

snippets #4:

dbms_utility.get_sql_hash

Page 46: Mar11 11g Developers 7 Short

46

SQL> select hash_value

2 from v$sql

3 where sql_text = 'SELECT 99 FROM DUAL';

HASH_VALUE

----------

835694897

Page 47: Mar11 11g Developers 7 Short

47

SQL> declare

2 h1 raw(16);

3 h2 number;

4 n int;

5 begin

6 n :=

7 dbms_utility.get_sql_hash(

8 'SELECT 99 FROM DUAL' ,h1,h2);

9 dbms_output.put_line(h1);

10 end;

11 /

F1D44D227DC0C4E0C719280B31B1CF3131B1CF31

= 835694897

||chr(0)

Page 48: Mar11 11g Developers 7 Short

48

snippets #5:

listagg

Page 49: Mar11 11g Developers 7 Short

classical problem

49

Page 50: Mar11 11g Developers 7 Short

SQL> select deptno, ename

2 from emp

3 order by 1,2;

DEPTNO ENAME

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

10 CLARK

10 KING

10 MILLER

20 ADAMS

20 FORD

20 JONES

20 SCOTT

20 SMITH

30 ALLEN

30 BLAKE

30 JAMES

30 MARTIN

30 TURNER

30 WARD

50

Page 51: Mar11 11g Developers 7 Short

DEPTNO MEMBERS

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

10 CLARK,KING,MILLER

20 SMITH,JONES,SCOTT,ADAMS,FORD

30 ALLEN,WARD,MARTIN,BLAKE,TURNER,JAMES

51

Page 52: Mar11 11g Developers 7 Short

SQL> select deptno , rtrim(ename,',') enames

2 from ( select deptno,ename,rn

3 from emp

4 model

5 partition by (deptno)

6 dimension by (

7 row_number() over

8 (partition by deptno order by ename) rn

9 )

10 measures (cast(ename as varchar2(40)) ename)

11 rules

12 ( ename[any]

13 order by rn desc = ename[cv()]||','||ename[cv()+1])

14 )

15 where rn = 1

16 order by deptno;

DEPTNO ENAMES

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

10 CLARK,KING,MILLER

20 ADAMS,FORD,JONES,SCOTT,SMITH

30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD

52- Rob Van Wijk

Page 53: Mar11 11g Developers 7 Short

SQL> select deptno,

2 substr(max(sys_connect_by_path(ename, ',')), 2) members

3 from (select deptno, ename,

4 row_number ()

5 over (partition by deptno order by empno) rn

6 from emp)

7 start with rn = 1

8 connect by prior rn = rn - 1

9 and prior deptno = deptno

10 group by deptno

11 /

DEPTNO MEMBERS

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

30 ALLEN,WARD,MARTIN,BLAKE,TURNER,JAMES

20 SMITH,JONES,SCOTT,ADAMS,FORD

10 CLARK,KING,MILLER

53- Anon

Page 54: Mar11 11g Developers 7 Short

SQL> select deptno,

2 xmltransform

3 ( sys_xmlagg

4 ( sys_xmlgen(ename)

5 ),

6 xmltype

7 (

8 '<?xml version="1.0"?><xsl:stylesheet version="1.0"

9 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

10 <xsl:template match="/">

11 <xsl:for-each select="/ROWSET/ENAME">

12 <xsl:value-of select="text()"/>;</xsl:for-each>

13 </xsl:template>

14 </xsl:stylesheet>'

15 )

16 ).getstringval() members

17 from emp

18 group by deptno;

DEPTNO MEMBERS

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

10 CLARK;MILLER;KING;

20 SMITH;FORD;ADAMS;SCOTT;JONES;

30 ALLEN;JAMES;TURNER;BLAKE;MARTIN;WARD;

54- Laurent Schneider

Page 55: Mar11 11g Developers 7 Short

SQL> create or replace type string_agg_type as object

2 (

3 total varchar2(4000),

4

5 static function

6 ODCIAggregateInitialize(sctx IN OUT string_agg_type )

7 return number,

8

9 member function

10 ODCIAggregateIterate(self IN OUT string_agg_type ,

11 value IN varchar2 )

12 return number,

13

14 member function

15 ODCIAggregateTerminate(self IN string_agg_type,

16 returnValue OUT varchar2,

17 flags IN number)

18 return number,

19

20 member function

21 ODCIAggregateMerge(self IN OUT string_agg_type,

22 ctx2 IN string_agg_type)

23 return number

24 );

25 /55- Tom Kyte

Page 56: Mar11 11g Developers 7 Short

56

Page 57: Mar11 11g Developers 7 Short

SQL> select deptno,

2 listagg( ename, ',')

3 within group (order by empno) members

4 from emp

5 group by deptno;

DEPTNO MEMBERS

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

10 CLARK,KING,MILLER

20 SMITH,JONES,SCOTT,ADAMS,FORD

30 ALLEN,WARD,MARTIN,BLAKE,TURNER,JAMES

57

Page 58: Mar11 11g Developers 7 Short

Feature:

real time sql monitoring

58

Page 59: Mar11 11g Developers 7 Short

59

Page 60: Mar11 11g Developers 7 Short

60

select e.department_id, sum(salary)

from emp e,

job_hist j

where e.employee_id = j.employee_id

and extract(year from e.hire_date) > 1985

and j.end_date > j.start_date + 1

and j.start_date >= e.hire_date

group by e.department_id

Page 61: Mar11 11g Developers 7 Short

61

v$sql_plan

Page 62: Mar11 11g Developers 7 Short

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

| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)|

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

| 0 | SELECT STATEMENT | | 36M| 2742M| | 10998 (48)|

| 1 | HASH GROUP BY | | 36M| 2742M| | 10998 (48)|

|* 2 | HASH JOIN | | 36M| 2742M| 3728K| 9137 (37)|

|* 3 | TABLE ACCESS FULL| JOB_HIST | 88761 | 2687K| | 147 (3)|

|* 4 | TABLE ACCESS FULL| EMP | 877K| 40M| | 3028 (2)|

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

62

Page 63: Mar11 11g Developers 7 Short

63

Page 64: Mar11 11g Developers 7 Short

SQL> select

2 DBMS_SQLTUNE.REPORT_SQL_MONITOR(

3 sql_id=>'d3ncuxj7629bf',

4 report_level=>'ALL',

5 type=>'HTML') as report

6 from dual;

64

Page 65: Mar11 11g Developers 7 Short
Page 66: Mar11 11g Developers 7 Short
Page 67: Mar11 11g Developers 7 Short
Page 68: Mar11 11g Developers 7 Short

68

11.2.0.2

Page 69: Mar11 11g Developers 7 Short

SQL> select

2 DBMS_SQLTUNE.REPORT_SQL_DETAIL(

3 sql_id=>'d3ncuxj7629bf',

4 report_level=>'ALL',

5 type=>'ACTIVE') as report

6 from dual;

69

Page 70: Mar11 11g Developers 7 Short

70

Page 71: Mar11 11g Developers 7 Short

71

Feature:

statistics enhancements

71

Page 72: Mar11 11g Developers 7 Short

72

Page 73: Mar11 11g Developers 7 Short

73

Page 74: Mar11 11g Developers 7 Short

74

cardinality is everything

74

Page 75: Mar11 11g Developers 7 Short

75

same with Oracle

75

Page 76: Mar11 11g Developers 7 Short

76

some real(ish) data

76

Page 77: Mar11 11g Developers 7 Short

77

SQL> desc VEHICLE

Name Null? Type

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

ID NUMBER

MAKE VARCHAR2(6)

MODEL VARCHAR2(6)

SQL> select count(*)

2 from VEHICLE;

COUNT(*)

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

2,157,079

77

Page 78: Mar11 11g Developers 7 Short

78

default stats not enough

78

Page 79: Mar11 11g Developers 7 Short

79

SQL> select count(*)

2 from VEHICLE

3 where MAKE = 'HOLDEN';

COUNT(*)

----------

415387

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

| Id | Operation | Name | Rows | Bytes | Cost |

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

| 0 | SELECT STATEMENT | | 1 | 7 | 138|

| 1 | SORT AGGREGATE | | 1 | 7 | |

|* 2 | INDEX RANGE SCAN| MAKE_IX | 55310 | 378K| 138|

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

79

Page 80: Mar11 11g Developers 7 Short

80

histogram

80

Page 81: Mar11 11g Developers 7 Short

81

SQL> begin

2 dbms_stats.gather_table_stats(user,'VEHICLE',

3 method_opt=>'for all columns size 1,'||

4 'for columns MAKE size 254,'||

5 'for columns MODEL size 254');

6 end;

7 /

PL/SQL procedure successfully completed.

81

Page 82: Mar11 11g Developers 7 Short

82

SQL> select count(*)

2 from VEHICLE

3 where MAKE = 'HOLDEN';

COUNT(*)

----------

415387

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

| Id | Operation | Name | Rows | Bytes | Cost |

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

| 0 | SELECT STATEMENT | | 1 | 7 | 1024|

| 1 | SORT AGGREGATE | | 1 | 7 | |

|* 2 | INDEX RANGE SCAN| MAKE_IX | 418K| 2859K| 1024|

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

82

Page 83: Mar11 11g Developers 7 Short

83

make AND model

83

Page 84: Mar11 11g Developers 7 Short

84

SQL> select count(*)

2 from VEHICLE

3 where MAKE = 'HOLDEN'

4 and MODEL = 'COMMODORE';

COUNT(*)

----------

214468

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

| Id | Operation | Name | Rows | Bytes |

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

| 0 | SELECT STATEMENT | | 1 | 14 |

| 1 | SORT AGGREGATE | | 1 | 14 |

| 2 | BITMAP CONVERSION COUNT | | 39527 | 540K|

| 3 | BITMAP AND | | | |

| 4 | BITMAP CONVERSION FROM ROWIDS| | | |

|* 5 | INDEX RANGE SCAN | MODEL_IX | | |

| 6 | BITMAP CONVERSION FROM ROWIDS| | | |

|* 7 | INDEX RANGE SCAN | MAKE_IX | | |

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

84

50% holdens are commodores

Page 85: Mar11 11g Developers 7 Short

85

two things

85

Page 86: Mar11 11g Developers 7 Short

86

Page 87: Mar11 11g Developers 7 Short

8787

Page 88: Mar11 11g Developers 7 Short

88

no correlation

10g and before

88

Page 89: Mar11 11g Developers 7 Short

89

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

| Id | Operation | Rows | Bytes |

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

| 0 | SELECT STATEMENT | 1 | 14 |

| 1 | SORT AGGREGATE | 1 | 14 |

| 2 | BITMAP CONVERSION COUNT | 39527 | 540K|

89

Page 90: Mar11 11g Developers 7 Short

90

SQL> select count(*) from VEHICLE where model = 'COMMODORE';

COUNT(*)

----------

214468

SQL> select count(*) from VEHICLE where make = 'HOLDEN';

COUNT(*)

----------

415387

SQL> select (214468/2157079)*

2 (415387/2157079)*

3 2157079 EST_ROWS from dual;

EST_ROWS

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

41299.9334 ≈ 39527

Prob(xy)=Prob(x)*Prob(y)

90

Page 91: Mar11 11g Developers 7 Short

91

SQL> select

2 DBMS_STATS.CREATE_EXTENDED_STATS(

3 user, 'VEHICLE','(MAKE,MODEL)') tag

4 from dual;

TAG

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

SYS_STU8QPK2S$PEWHARK2CP3#1F#G

SQL> select COLUMN_NAME,NUM_DISTINCT

2 from user_tab_cols

3 where table_name = 'VEHICLE'

COLUMN_NAME NUM_DISTINCT

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

ID 2157079

MAKE 39

MODEL 292

SYS_STU8QPK2S$PEWHARK2CP3#1F#G

91

Page 92: Mar11 11g Developers 7 Short

92

SQL> begin

2 dbms_stats.gather_table_stats(user,'VEHICLE',

3 method_opt=>

4 'for columns SYS_STU8QPK2S$PEWHARK2CP3#1F#G size 254');

5 end;

6 /

PL/SQL procedure successfully completed.

SQL> begin

2 dbms_stats.gather_table_stats(user,'VEHICLE',

3 method_opt=>

4 'for columns (make,model) size 254');

5 end;

6 /

PL/SQL procedure successfully completed.

92

Page 93: Mar11 11g Developers 7 Short

93

SQL> select count(*)

2 from VEHICLE

3 where MAKE = 'HOLDEN'

4 and MODEL = 'COMMODORE';

COUNT(*)

----------

214468

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

| Id | Operation | Name | Rows | Bytes | Cost |

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

| 0 | SELECT STATEMENT | | 1 | 14 | 1956|

| 1 | SORT AGGREGATE | | 1 | 14 | |

|* 2 | TABLE ACCESS FULL| VEHICLE | 220K| 3018K| 1956|

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

93

Page 94: Mar11 11g Developers 7 Short

9494

actual versus estimate

Page 95: Mar11 11g Developers 7 Short

95

SQL> select /*+ GATHER_PLAN_STATISTICS */ count(*)

2 from VEHICLE

3 where MAKE = 'HOLDEN'

4 and MODEL = 'COMMODORE';

COUNT(*)

----------

214468

SQL> SELECT *

2 FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(

3 NULL, NULL, 'ALLSTATS LAST'));

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

| Id | Operation | Name | Starts | E-Rows | A-Rows |

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

| 1 | SORT AGGREGATE | | 1 | 1 | 1 |

|* 2 | TABLE ACCESS FULL| VEHICLE | 1 | 220K| 214K|

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

95

Page 96: Mar11 11g Developers 7 Short

96

its just another column

96

Page 97: Mar11 11g Developers 7 Short

97

SQL> select "SYS_STU8QPK2S$PEWHARK2CP3#1F#G"

2 from vehicle

3 where rownum < 10;

SYS_STU8QPK2S$PEWHARK2CP3#1F#G

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

1.2706E+19

1.8075E+19

7.9949E+18

1.1730E+19

6.7142E+18

1.1730E+19

1.0779E+19

5.4051E+18

7.3555E+18

97

Page 98: Mar11 11g Developers 7 Short

98

forget ...

98

Page 99: Mar11 11g Developers 7 Short

99

SQL> SELECT extension_name, extension

2 FROM USER_STAT_EXTENSIONS

3 WHERE table_name = 'VEHICLE';

EXTENSION_NAME EXTENSION

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

SYS_STU8QPK2S$PEWHARK2CP3#1F#G ("MAKE","MODEL")

99

Page 100: Mar11 11g Developers 7 Short

100

SQL> select SYS_OP_COMBINED_HASH(make,model) hashval,

2 "SYS_STU8QPK2S$PEWHARK2CP3#1F#G" colval

3 from VEHICLE

4 where rownum < 10;

HASHVAL COLVAL

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

1.2706E+19 1.2706E+19

1.8075E+19 1.8075E+19

7.9949E+18 7.9949E+18

1.1730E+19 1.1730E+19

6.7142E+18 6.7142E+18

1.1730E+19 1.1730E+19

1.0779E+19 1.0779E+19

5.4051E+18 5.4051E+18

7.3555E+18 7.3555E+18

100

Page 101: Mar11 11g Developers 7 Short

101

PARSING IN CURSOR #28

alter table "SH"."VEHICLE" add

(SYS_STU8QPK2S$PEWHARK2CP3#1F#G

as (SYS_OP_COMBINED_HASH(MAKE,MODEL))

virtual BY USER for statistics);

END OF STMT

101

Page 102: Mar11 11g Developers 7 Short

102

virtual column

102

Page 103: Mar11 11g Developers 7 Short

103103

SYS_OP_COMBINED_HASH

Page 104: Mar11 11g Developers 7 Short

104

hash means equality

104

Page 105: Mar11 11g Developers 7 Short

105

SQL> select count(*)

2 from VEHICLE

3 where MAKE in ('FORD','HOLDEN')

4 and MODEL = 'COMMODORE';

COUNT(*)

----------

214468

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

| Id | Operation | Name | Rows | Bytes | Cost

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

| 0 | SELECT STATEMENT | | 1 | 14 | 1921

| 1 | SORT AGGREGATE | | 1 | 14 |

|* 2 | VIEW | index$_join$_001 | 77818 | 1063K| 1921

|* 3 | HASH JOIN | | | |

|* 4 | INDEX RANGE SCAN | MODEL_IX | 77818 | 1063K| 502

| 5 | INLIST ITERATOR | | | |

|* 6 | INDEX RANGE SCAN| MAKE_IX | 77818 | 1063K| 2086

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

105

Page 106: Mar11 11g Developers 7 Short

106

can we solve this ?

106

Page 107: Mar11 11g Developers 7 Short

107

two enhancements

107

Page 108: Mar11 11g Developers 7 Short

108

adaptive cursor sharing

11.1

108

Page 109: Mar11 11g Developers 7 Short

109

11.2

109

Page 110: Mar11 11g Developers 7 Short

much

110

much

better

Page 111: Mar11 11g Developers 7 Short

111

Page 112: Mar11 11g Developers 7 Short

112112

recall

Page 113: Mar11 11g Developers 7 Short

113113

cardinality

Page 114: Mar11 11g Developers 7 Short

114114

actual versus estimate

Page 115: Mar11 11g Developers 7 Short

115115

employ someone....

Page 116: Mar11 11g Developers 7 Short

116

SQL> select /*+ GATHER_PLAN_STATISTICS */ count(*)

2 from VEHICLE

3 where MAKE = 'HOLDEN'

4 and MODEL = 'COMMODORE';

COUNT(*)

----------

214468

SQL> SELECT *

2 FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(

3 NULL, NULL, 'ALLSTATS LAST'));

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

| Id | Operation | Name | Starts | E-Rows | A-Rows |

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

| 1 | SORT AGGREGATE | | 1 | 1 | 1 |

|* 2 | TABLE ACCESS FULL| VEHICLE | 1 | 220K| 214K|

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

116

"ok"

Page 117: Mar11 11g Developers 7 Short

117117

Page 118: Mar11 11g Developers 7 Short

118118

but just maybe ....

Page 119: Mar11 11g Developers 7 Short

119119

... someone already is

Page 120: Mar11 11g Developers 7 Short

SQL> create table EMP as

2 select rownum empno,

3 mod(rownum,10) jobid,

4 mod(rownum,10)*1000 salary,

5 mod(rownum,50)+1 deptno

6 from dual

7 connect by rownum < 100000;

SQL> create table DEPT as

2 select rownum deptno,

3 'dept'||rownum dname

4 from dual

5 connect by rownum <= 100;

120

100,000 rows

100 rows

Page 121: Mar11 11g Developers 7 Short

SQL> exec dbms_stats.gather_table_stats(user,'EMP');

SQL> exec dbms_stats.gather_table_stats(user,'DEPT');

SQL> create index EMP_IX on EMP ( deptno );

SQL> create index DEPT_IX on DEPT ( deptno );

121

Page 122: Mar11 11g Developers 7 Short

SQL> select e.empno, d.dname

2 from emp e, dept d

3 where d.deptno = e.deptno

4 and e.jobid = 1

5 and e.salary > 5000;

no rows selected

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

| Id | Operation | Name | Rows | Bytes |

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

| 0 | SELECT STATEMENT | | | |

| 1 | MERGE JOIN | | 4444 | 104K |

| 2 | TABLE ACCESS BY INDEX ROWID| DEPT | 100 | 1000 |

| 3 | INDEX FULL SCAN | DEPT_IX | 100 | |

|* 4 | SORT JOIN | | 4444 | 62216 |

|* 5 | TABLE ACCESS FULL | EMP | 4444 | 62216 |

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

122

4 and e.jobid = 1

5 and e.salary > 5000;

hard to

optimize

Page 123: Mar11 11g Developers 7 Short

re-run the query

123

Page 124: Mar11 11g Developers 7 Short

124

no anythingchanges to

Page 125: Mar11 11g Developers 7 Short

SQL> select e.empno, d.dname

2 from emp e, dept d

3 where d.deptno = e.deptno

4 and e.jobid = 1

5 and e.salary > 5000;

no rows selected

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

| Id | Operation | Name | Rows | Bytes |

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

| 0 | SELECT STATEMENT | | | |

|* 1 | HASH JOIN | | 89 | 2136 |

| 2 | TABLE ACCESS FULL| DEPT | 1 | 10 |

|* 3 | TABLE ACCESS FULL| EMP | 4444 | 62216 |

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

125

Page 126: Mar11 11g Developers 7 Short

11.2

126

Page 127: Mar11 11g Developers 7 Short

the optimizer knows what "hard" is

127

Page 128: Mar11 11g Developers 7 Short

cardinality feedback loop

128

Page 129: Mar11 11g Developers 7 Short

its not continuous learning

129

Page 130: Mar11 11g Developers 7 Short

several restrictions

130

Page 131: Mar11 11g Developers 7 Short

SQL tuning advisor fallback

131

Page 132: Mar11 11g Developers 7 Short

132

Feature:

result cache

Page 133: Mar11 11g Developers 7 Short

133

Page 134: Mar11 11g Developers 7 Short

134

SQL> create table MY_TMP as

2 select ....

Table created.

SQL> select ...

2 from ...

3 where COL in ( select COL from MY_TMP )

4 and ...

Page 135: Mar11 11g Developers 7 Short

135

cache the results of queries

Page 136: Mar11 11g Developers 7 Short

136

hard...

GTT,

plsql table,

materialised view

single session,

expiry issues,

staleness

Page 137: Mar11 11g Developers 7 Short

137

SQL> SELECT name, value

2 FROM v$parameter

3 WHERE name LIKE 'result_cache%';

NAME VALUE

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

result_cache_mode MANUAL

result_cache_max_size 1081344

result_cache_max_result 5

result_cache_remote_expiration 0

memory

%

Page 138: Mar11 11g Developers 7 Short

138

SQL> set autotrace traceonly stat

SQL> set timing on

SQL> select owner, count(*)

2 from T

3 group by owner

4 /

29 rows selected.

Elapsed: 00:00:03.98

Statistics

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

0 recursive calls

1 db block gets

32192 consistent gets

32184 physical reads

96 redo size

[snip]

Page 139: Mar11 11g Developers 7 Short

139

SQL> /

29 rows selected.

Elapsed: 00:00:03.80

Statistics

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

0 recursive calls

1 db block gets

32192 consistent gets

32184 physical reads

96 redo size

[snip]

Page 140: Mar11 11g Developers 7 Short

140

SQL> set autotrace traceonly stat

SQL> set timing on

SQL> select /*+ RESULT_CACHE */ owner, count(*)

2 from T

3 group by owner

4 /

29 rows selected.

Elapsed: 00:00:03.80

Statistics

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

0 recursive calls

1 db block gets

32192 consistent gets

32184 physical reads

96 redo size

[snip]

Page 141: Mar11 11g Developers 7 Short

141

SQL> set autotrace traceonly stat

SQL> set timing on

SQL> select /*+ RESULT_CACHE */ owner, count(*)

2 from T

3 group by owner

4 /

29 rows selected.

Elapsed: 00:00:00.04 !!!!!!!!!!!!

Statistics

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

0 recursive calls

0 db block gets

0 consistent gets

0 physical reads

0 redo size

[snip]

Page 142: Mar11 11g Developers 7 Short

142

cross session

Page 143: Mar11 11g Developers 7 Short

143

SQL> select /*+ RESULT_CACHE */ owner, count(*)

2 from T

3 group by owner

4 /

29 rows selected.

Elapsed: 00:00:00.04

SQL> select /*+ RESULT_CACHE */ owner, count(*)

2 from T

3 group by owner

4 /

29 rows selected.

Elapsed: 00:00:03.80

session 2

session 1

Page 144: Mar11 11g Developers 7 Short

144

automatic expiry

Page 145: Mar11 11g Developers 7 Short

145

SQL> set timing on

SQL> select /*+ RESULT_CACHE */ owner, count(*)

2 from T

3 group by owner

4 /

29 rows selected.

Elapsed: 00:00:00.05

SQL> delete from T where rownum = 1;

1 row deleted.

SQL> select /*+ RESULT_CACHE */ owner, count(*)

2 from T

3 group by owner

4 /

Elapsed: 00:00:03.91

active txn

Page 146: Mar11 11g Developers 7 Short

146

SQL> commit;

Commit complete.

SQL> select /*+ RESULT_CACHE */ owner, count(*)

2 from T

3 group by owner

4 /

Elapsed: 00:00:03.91

SQL> select /*+ RESULT_CACHE */ owner, count(*)

2 from T

3 group by owner

4 /

Elapsed: 00:00:00.04

reinstantiate cache

voila!

Page 147: Mar11 11g Developers 7 Short

147

11.2

Page 148: Mar11 11g Developers 7 Short

148

part of table definition

Page 149: Mar11 11g Developers 7 Short

149

alter table T result_cache (mode force);

Page 150: Mar11 11g Developers 7 Short

150

dependencies

Page 151: Mar11 11g Developers 7 Short

151

v$result_cache_objects

v$result_cache_dependency

Page 152: Mar11 11g Developers 7 Short

152

SQL> select

2 r.name,

3 listagg(o.name,' ') within group ( order by o.name ) as obj

4 from v$result_cache_objects r,

5 v$result_cache_dependency d,

6 sys.obj$ o

7 where r.type = 'Result'

8 and r.id =d.result_id

9 and d.object_no=o.obj#

10 group by r.name;

NAME OBJ

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

select /*+ RESULT_CACHE */ owner, count(*) T

from T

group by owner

select /*+ RESULT_CACHE */ owner, count(*) T1 T

from T, T1

group by owner

Page 153: Mar11 11g Developers 7 Short

153

plsql too

Page 154: Mar11 11g Developers 7 Short

154

SQL> desc COUNTRY_SALES

Name Null? Type

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

CTRY NOT NULL VARCHAR2(10)

CRNCY NOT NULL VARCHAR2(3)

AMOUNT NUMBER

PRODUCT VARCHAR2(20)

TXN_DATE DATE

QUANTITY NUMBER(3)

"summarise the sales in $AUD"

Page 155: Mar11 11g Developers 7 Short

155

currency conversion function

Page 156: Mar11 11g Developers 7 Short

156

SOA

slower... obscure...

...awfully complicated

Page 157: Mar11 11g Developers 7 Short

157

SQL> create or replace

2 function CURRENCY_CONVERT(code varchar2) return number is

3 l_service sys.utl_dbws.service;

4 l_call sys.utl_dbws.call;

5 l_result sys.anydata;

6

7 l_wsdl varchar2(100);

8 l_ns varchar2(100);

[snip]

15 begin

16 l_ns := 'http://www.webservicex.net/currencyconvertor.asmx';

17 l_wsdl := 'http://www.webservicex.net/currencyconvertor.asmx?wsdl';

[snip]

28

29 l_result := SYS.UTL_DBWS.INVOKE (

30 call_handle => l_call,

31 input_params => l_input_params);

[snip]

46 return sys.anydata.accessnumber(l_result);

47 end;

48 /

Function created.

Page 158: Mar11 11g Developers 7 Short

158

SQL> select sum(CURRENCY_CONVERT(crncy)*amount) tot

2 from COUNTRY_SALES

3 /

TOT

----------

4799.62

Elapsed: 00:00:45.36

Page 159: Mar11 11g Developers 7 Short

159

Page 160: Mar11 11g Developers 7 Short

160

SQL> create or replace

2 function CURRENCY_CONVERT(code varchar2) return number RESULT_CACHE is

3 l_service sys.utl_dbws.service;

4 l_call sys.utl_dbws.call;

5 l_result sys.anydata;

6

7 l_wsdl varchar2(100);

8 l_ns varchar2(100);

[snip]

15 begin

16 l_ns := 'http://www.webservicex.net/currencyconvertor.asmx';

17 l_wsdl := 'http://www.webservicex.net/currencyconvertor.asmx?wsdl';

[snip]

28

29 l_result := SYS.UTL_DBWS.invoke (

30 call_handle => l_call,

31 input_params => l_input_params);

[snip]

46 return sys.anydata.accessnumber(l_result);

47 end;

48 /

Function created.

Page 161: Mar11 11g Developers 7 Short

161

SQL> select sum(CURRENCY_CONVERT(crncy)*amount) tot

2 from COUNTRY_SALES

3 where rownum < 100

4 /

TOT

----------

4799.62

Elapsed: 00:00:15.78

SQL> /

TOT

----------

4799.62

Elapsed: 00:00:00.02

inter-row

cache benefit

all values

cached

Page 162: Mar11 11g Developers 7 Short

162

explain plan

Page 163: Mar11 11g Developers 7 Short

163

SQL> select /*+ RESULT_CACHE */ owner, max(object_id)

2 from T

3 group by owner

4 /

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

| Id | Operation | Name | Rows | Bytes |

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

| 0 | SELECT STATEMENT | | 19 | 171 |

| 1 | RESULT CACHE | b82qdu5m139yr3fbna1x5r6g2d | | |

| 2 | HASH GROUP BY | | 19 | 171 |

| 3 | TABLE ACCESS FULL| T | 2201K| 18M |

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

indeterminate

Page 164: Mar11 11g Developers 7 Short

164

SQL> select status

2 from v$result_cache_objects

3 where cache_id = 'b82qdu5m139yr3fbna1x5r6g2d';

STATUS

---------

Published

New - Result is still under construction

Published - Result is available for use

Bypass - Result will be bypassed from use

Expired - Result has exceeded expiration time

Invalid - Result is no longer available for use

?

Page 165: Mar11 11g Developers 7 Short

165

two people, same query

select /*+ RESULT_CACHE */ …

select /*+ RESULT_CACHE */ …

Page 166: Mar11 11g Developers 7 Short

166

when in doubt...

...try to break it

Page 167: Mar11 11g Developers 7 Short

167

Page 168: Mar11 11g Developers 7 Short

168

Page 169: Mar11 11g Developers 7 Short

169

Page 170: Mar11 11g Developers 7 Short

170

SQL> create or replace

2 function SLOW(n number) return number

3 deterministic is

4 begin

5 dbms_lock.sleep(1);

6 return n;

7 end;

8 /

Function created.

Page 171: Mar11 11g Developers 7 Short

171

SQL> select /*+ RESULT_CACHE */ owner, slow(object_id)

2 from T

3 where rownum <= 120;

Elapsed: 00:02:01.13

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

| Id | Operation | Name | Rows | Bytes |

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

| 0 | SELECT STATEMENT | | 119 | 1071 |

| 1 | RESULT CACHE | 14tnr7dxmvkp3244d69tw72z4p | | |

|* 2 | COUNT STOPKEY | | | |

| 3 | TABLE ACCESS FULL| T | 119 | 1071 |

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

Page 172: Mar11 11g Developers 7 Short

172

SQL> select /*+ RESULT_CACHE */ owner, slow(object_id)

2 from T

3 where rownum < 120;

[5 seconds later...]

OWNER SLOW(OBJECT_ID)

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

SYS 20

SYS 46

SYS 28

SYS 15

SYS 29

[still executing...]

SQL> select status

2 from v$result_cache_objects

3 where cache_id = '14tnr7dxmvkp3244d69tw72z4p';

STATUS

---------

New

session 2

SQL> select /*+ RESULT_CACHE */ owner, slow(object_id)

2 from T

3 where rownum < 120;

[executing...]

Elapsed: 00:03:03.54 !!!!!!!!!

Page 173: Mar11 11g Developers 7 Short

173

SQL> select sid,

2 decode(lockwait,null,status,'BLOCKED') status

3 from v$session

4 where username = 'CONNOR';

SID STATUS

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

131 ACTIVE

143 BLOCKED

uh oh....

Page 174: Mar11 11g Developers 7 Short

174

PARSING IN CURSOR #5 len=82 dep=0 uid=88 oct=3 lid=88

select /*+ RESULT_CACHE */ owner, slow(data_object_id)

from T

where rownum < 120

END OF STMT

PARSE #5:c=15625,e=28756,p=0,cr=0,cu=0,mis=1,r=0,tim=202781578

EXEC #5:c=0,e=60,p=0,cr=0,cu=0,mis=0,r=0,tim=202781659

WAIT #5: nam='enq: RC - Result Cache: Contention' ela= 10005714

WAIT #5: nam='enq: RC - Result Cache: Contention' ela= 10002485

WAIT #5: nam='enq: RC - Result Cache: Contention' ela= 10002804

WAIT #5: nam='enq: RC - Result Cache: Contention' ela= 10002549

WAIT #5: nam='enq: RC - Result Cache: Contention' ela= 10005258

WAIT #5: nam='enq: RC - Result Cache: Contention' ela= 10002461

WAIT #5: nam='direct path read' ela= 13770 file number=4 ...

WAIT #5: nam='direct path read' ela= 25 file number=4 ...

[etc]

Page 175: Mar11 11g Developers 7 Short

175

better in 11.2

Page 176: Mar11 11g Developers 7 Short

176

PARSING IN CURSOR #5 len=82 dep=0 uid=88 oct=3 lid=88

select /*+ RESULT_CACHE */ owner, slow(data_object_id)

from T

where rownum < 120

END OF STMT

PARSE #5:c=15625,e=28756,p=0,cr=0,cu=0,mis=1,r=0,tim=202781578

EXEC #5:c=0,e=60,p=0,cr=0,cu=0,mis=0,r=0,tim=202781659

WAIT #5: nam='enq: RC - Result Cache: Contention' ela= 10005714

WAIT #5: nam='direct path read' ela= 13770 file number=4 ...

WAIT #5: nam='direct path read' ela= 25 file number=4 ...

...

Page 177: Mar11 11g Developers 7 Short

177

"take care....."

Page 178: Mar11 11g Developers 7 Short

178

Page 179: Mar11 11g Developers 7 Short

179

not too short....

why bother with result cache?

Page 180: Mar11 11g Developers 7 Short

180

not too long....

might lock other people out

Page 181: Mar11 11g Developers 7 Short

181

Feature:

compound triggers

Page 182: Mar11 11g Developers 7 Short

182

example: table audit

Page 183: Mar11 11g Developers 7 Short

183

SQL> desc T

Name Null? Type

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

OWNER NOT NULL VARCHAR2(30)

OBJECT_NAME NOT NULL VARCHAR2(30)

SQL> desc T_AUDIT

Name Null? Type

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

AUDIT_DATE DATE

AUDIT_ACTION CHAR(1)

OWNER NOT NULL VARCHAR2(30)

OBJECT_NAME NOT NULL VARCHAR2(30)

Page 184: Mar11 11g Developers 7 Short

184

SQL> create or replace

2 trigger AUDIT_TRG

3 after insert or update or delete on T

4 for each row

5 declare

6 v_action varchar2(1) := case when updating then 'U'

7 when deleting then 'D' else 'I' end;

8 begin

9 if updating or inserting then

10 insert into T_AUDIT

11 values (sysdate

12 ,v_action

13 ,:new.owner

14 ,:new.object_name);

15 else

16 insert into T_AUDIT

17 values (sysdate

18 ,v_action

19 ,:old.owner

20 ,:old.object_name);

21 end if;

22 end;

23 /

Trigger created.

Page 185: Mar11 11g Developers 7 Short

185

works but slow...

Page 186: Mar11 11g Developers 7 Short

186

SQL> insert into T

2 select owner, object_name

3 from all_objects

4 where rownum <= 10000;

10000 rows created.

insert into T

select owner, object_name

from all_objects

where rownum <= 10000

call count cpu elapsed disk query current rows

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

Parse 1 0.01 0.00 0 0 0 0

Execute 1 3.10 3.05 88 123 10642 10000

Fetch 0 0.00 0.00 0 0 0 0

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

total 2 3.12 3.06 88 123 10642 10000

INSERT INTO T_AUDIT

VALUES (SYSDATE ,:B3 ,:B1 ,:B2 )

call count cpu elapsed disk query current rows

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

Parse 1 0.00 0.00 0 0 0 0

Execute 10000 0.79 0.97 2 109 10845 10000

Fetch 0 0.00 0.00 0 0 0 0

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

total 10001 0.79 0.97 2 109 10845 10000

Page 187: Mar11 11g Developers 7 Short

187

bulk binding

"hard"

Page 188: Mar11 11g Developers 7 Short

188

create or replace

package T_PKG is

type each_row is record ( action varchar2(1),

owner varchar2(30),

object_name varchar2(30)

);

type row_list is table of each_row

index by pls_integer;

g row_list;

end;

/

Page 189: Mar11 11g Developers 7 Short

189

create or replace

trigger AUDIT_TRG1

before insert or update or delete on T

begin

t_pkg.g.delete;

end;

/

Page 190: Mar11 11g Developers 7 Short

190

create or replace

trigger AUDIT_TRG2

after insert or update or delete on T

for each row

begin

if updating or inserting then

t_pkg.g(t_pkg.g.count+1).owner := :new.owner;

t_pkg.g(t_pkg.g.count).object_name := :new.object_name;

else

t_pkg.g(t_pkg.g.count).owner := :old.owner;

t_pkg.g(t_pkg.g.count).object_name := :old.object_name;

end if;

end;

/

Page 191: Mar11 11g Developers 7 Short

191

create or replace

trigger AUDIT_TRG3

after insert or update or delete on T

declare

v_action varchar2(1) :=

case when updating then 'U'

when deleting then 'D'

else 'I' end;

begin

forall i in 1 .. t_pkg.g.count

insert into T_AUDIT

values (

sysdate,

v_action,

t_pkg.g(i).owner,

t_pkg.g(i).object_name);

t_pkg.g.delete;

end;

/

Page 192: Mar11 11g Developers 7 Short

192

SQL> insert into T

2 select owner, object_name

3 from all_objects

4 where rownum <= 10000;

10000 rows created.

insert into T

select owner, object_name

from all_objects

where rownum <= 10000

call count cpu elapsed disk query current rows

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

Parse 1 0.00 0.00 0 33 0 0

Execute 1 0.56 0.58 0 91 10653 10000

Fetch 0 0.00 0.00 0 0 0 0

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

total 2 0.56 0.59 0 124 10653 10000

INSERT INTO T_AUDIT

VALUES

( SYSDATE, :B1 , :B2 , :B3 )

call count cpu elapsed disk query current rows

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

Parse 1 0.00 0.00 0 0 0 0

Execute 1 0.04 0.03 0 90 478 10000

Fetch 0 0.00 0.00 0 0 0 0

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

total 2 0.04 0.03 0 90 478 10000

Page 193: Mar11 11g Developers 7 Short

193

no one did it ....

three triggers

additional package

Page 194: Mar11 11g Developers 7 Short

194

11g compound triggers

Page 195: Mar11 11g Developers 7 Short

195

create or replace

trigger AUDIT_TRG for insert or update or delete on T

compound trigger

before statement is

begin

...

end before statement;

after each row is

begin

...

end after each row;

after statement is

begin

...

end after statement;

end;

/

Page 196: Mar11 11g Developers 7 Short

196

SQL> create or replace

2 trigger AUDIT_TRG for insert or update or delete on T compound trigger

3

4 type each_row is record ( action varchar2(1),5 owner varchar2(30),

6 object_name varchar2(30));7 type row_list is table of each_row index by pls_integer;

8 g row_list;

9 v_action varchar2(1) :=10 case when updating then 'U' when deleting then 'D' else 'I' end;

1112 before statement is

13 begin

14 g.delete;15 end before statement;

1617 after each row is

18 begin

1920 if updating or inserting then

21 g(g.count+1).owner := :new.owner;22 g(g.count).object_name := :new.object_name;

23 else

24 g(g.count).owner := :old.owner;

25 g(g.count).object_name := :old.object_name;

26 end if;

27 end after each row;

28

29 after statement is30 begin

31 forall i in 1 .. g.count32 insert into T_AUDIT

33 values (sysdate,v_action,g(i).owner,g(i).object_name);

34 g.delete;35 end after statement;

3637 end;

38 /

Trigger created.

Page 197: Mar11 11g Developers 7 Short

197

one more thing on triggers...

Page 198: Mar11 11g Developers 7 Short

198

the 107 slides you didn't see

Page 199: Mar11 11g Developers 7 Short

199

SQL> create or replace

2 trigger AUDIT_TRG

3 after insert or update or delete on T

4 for each row

5 declare

6 v_action varchar2(1) :=

7 case when updating then 'U'

8 when deleting then 'D' else 'I' end case;

9 begin

10 if updating or inserting then

11 insert into T_AUDIT

12 values(sysdate,v_action,:new.owner,:new.object_name);

13 else

14 insert into T_AUDIT

15 values(sysdate,v_action,:old.owner,:old.object_name);

16 end if;

17 end;

18 /

Warning: Trigger created with compilation errors.

SQL> sho err

Errors for TRIGGER AUDIT_TRG:

LINE/COL ERROR

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

4/46 PLS-00103: Encountered the symbol "CASE" when expecting one of

the following:

* & = - + ; < / > at in is mod remainder not rem

<an exponent (**)> <> or != or ~= >= <= <> and or like like2

Page 200: Mar11 11g Developers 7 Short

200

SQL> create or replace

2 trigger AUDIT_TRG

3 after insert or update or delete on T

4 for each row

5 declare

6 v_action varchar2(1) :=

7 case when updating then 'U'

8 when deleting then 'D' else 'I' end;

9 begin

10 if updateing or inserting then

11 insert into T_AUDIT

12 values(sysdate,v_action,:new.owner,:new.object_name);

13 else

14 insert into T_AUDIT

15 values(sysdate,v_action,:old.owner,:old.object_name);

16 end if;

17 end;

18 /

Warning: Trigger created with compilation errors.

SQL> sho err

Errors for TRIGGER AUDIT_TRG:

LINE/COL ERROR

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

6/3 PL/SQL: Statement ignored

6/6 PLS-00201: identifier 'UPDATEING' must be declared

Page 201: Mar11 11g Developers 7 Short

201

SQL> create or replace

2 trigger AUDIT_TRG

3 after insert or update or delete on T

4 for each row

5 declare

6 v_action varchar2(1) :=

7 case when updating then 'U'

8 when deleting then 'D' else 'I' end;

9 begin

10 if updating or inserting then

11 insert into TAUDIT

12 values(sysdate,v_action,:new.owner,:new.object_name);

13 else

14 insert into T_AUDIT

15 values(sysdate,v_action,:old.owner,:old.object_name);

16 end if;

17 end;

18 /

Warning: Trigger created with compilation errors.

SQL> sho err

Errors for TRIGGER AUDIT_TRG:

LINE/COL ERROR

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

7/6 PL/SQL: SQL Statement ignored

7/18 PL/SQL: ORA-00942: table or view does not exist

Page 202: Mar11 11g Developers 7 Short

202

SQL> create or replace

2 trigger AUDIT_TRG

3 after insert or update or delete on T

4 for each row

5 declare

6 v_action varchar2(1) :=

7 case when updating then 'U'

8 when deleting then 'D' else 'I' end;

9 begin

10 if updating or inserting then

11 insert into T_AUDIT

12 values(sysdate,v_action,:new.owner,new.object_name);

13 else

14 insert into T_AUDIT

15 values(sysdate,v_action,:old.owner,:old.object_name);

16 end if;

17 end;

18 /

Warning: Trigger created with compilation errors.

SQL> sho err

Errors for TRIGGER AUDIT_TRG:

LINE/COL ERROR

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

10/6 PL/SQL: SQL Statement ignored

11/45 PL/SQL: ORA-00984: column not allowed here

Page 203: Mar11 11g Developers 7 Short

203

etc etc etc

Page 204: Mar11 11g Developers 7 Short

204

Which of the following is the largest ?

Page 205: Mar11 11g Developers 7 Short

205

T

Page 206: Mar11 11g Developers 7 Short

206

SQL> insert into T values ('X','Y');

insert into T values ('X','Y')

*

ERROR at line 1:

ORA-04098: trigger 'CONNOR.AUDIT_TRG' is

invalid and failed re-validation

Page 207: Mar11 11g Developers 7 Short

207

Feature:

11g disabled triggers

Page 208: Mar11 11g Developers 7 Short

208

SQL> create or replace

2 trigger AUDIT_TRG

3 after insert or update or delete on T

4 for each row

5 DISABLE

6 declare

7 v_action varchar2(1) :=

8 case when updating then 'U'

9 when deleting then 'D' else 'I' end;

10 begin

11 if updating or inserting then

12 insert into T_AUDIT

13 values(sysdate,v_action,:new.owner,:new.object_name);

14 else

15 insert into T_AUDIT

16 values(sysdate,v_action,:old.owner,old.object_name);

17 end if;

18 end;

19 /

Warning: Trigger created with compilation errors.

Page 209: Mar11 11g Developers 7 Short

209

SQL> select status from user_triggers

2 where trigger_name = 'AUDIT_TRG';

STATUS

--------

DISABLED

SQL> insert into T values ('X','Y');

1 row created.

Page 210: Mar11 11g Developers 7 Short

210

Feature:

bulk bind just got better

Page 211: Mar11 11g Developers 7 Short

211

SQL> declare

2 type row_list is table of all_objects%rowtype

3 index by pls_integer;

4 g row_list;

5 begin

6 for i in ( select * from all_objects

7 where rownum < 10 ) loop

8 g(g.count+1) := i;

9 end loop;

14 end;

15 /

10

11 forall i in 1 .. g.count

12 insert into T_COMP

13 values ( g(i).owner, g(i).object_name );

values ( g(i).owner, g(i).object_name );

*

ERROR at line 13:

ORA-06550: line 13, column 15:

PLS-00436: implementation restriction: cannot reference

fields of BULK In-BIND table of records

ORA-06550: line 13, column 15:

PLS-00382: expression is of wrong type

ORA-06550: line 13, column 27:

Page 212: Mar11 11g Developers 7 Short

212

11g

Page 213: Mar11 11g Developers 7 Short

213

SQL> declare

2 type row_list is table of all_objects%rowtype

3 index by pls_integer;

4 g row_list;

5 begin

6 for i in ( select * from all_objects

7 where rownum < 10 ) loop

8 g(g.count+1) := i;

9 end loop;

10

11 forall i in 1 .. g.count

12 insert into T

13 values ( g(i).owner, g(i).object_name );

14 end;

15 /

PL/SQL procedure successfully completed.

Page 214: Mar11 11g Developers 7 Short

214

danger:

gratuitous book plug

Page 215: Mar11 11g Developers 7 Short

215

Page 216: Mar11 11g Developers 7 Short

216

Feature:

Dependency tracking

Page 217: Mar11 11g Developers 7 Short

217

10g and below

Page 218: Mar11 11g Developers 7 Short

218

SQL> create table T ( x number, y number );

Table created.

SQL> create or replace

2 view MY_VIEW as

3 select x,y from T;

View created.

Page 219: Mar11 11g Developers 7 Short

219

SQL> alter table T add Z number;

Table altered.

SQL> select status

2 from user_objects

3 where object_name = 'MY_VIEW';

STATUS

-------

INVALID

Page 220: Mar11 11g Developers 7 Short

220

11g

Page 221: Mar11 11g Developers 7 Short

221

SQL> alter table T add Z number;

Table altered.

SQL> select status

2 from user_objects

3 where object_name = 'MY_VIEW';

STATUS

-------

VALID

Page 222: Mar11 11g Developers 7 Short

222

plsql too

Page 223: Mar11 11g Developers 7 Short

223

quick review

Page 224: Mar11 11g Developers 7 Short

224

"always use packages"

Page 225: Mar11 11g Developers 7 Short

225

ALL production code !

Page 226: Mar11 11g Developers 7 Short

226

more secure

Page 227: Mar11 11g Developers 7 Short

227

Page 228: Mar11 11g Developers 7 Short

228

break the invalidation chain

Page 229: Mar11 11g Developers 7 Short

229

proc A proc B proc C proc D

pack A pack B pack C pack D

body A body B body C body D

Page 230: Mar11 11g Developers 7 Short

230

11g

Page 231: Mar11 11g Developers 7 Short

231

change the spec as well !

Page 232: Mar11 11g Developers 7 Short

232

pack A pack B pack C pack D

body A body B body C body D

Page 233: Mar11 11g Developers 7 Short

233

SQL> create or replace

2 package PKG is

3 procedure P1;

4 end;

5 /

Package created.

SQL> create or replace

2 package body PKG is

3 procedure P1 is

4 x number;

5 begin

6 x := 1;

7 end;

8 end;

9 /

Package body created.

SQL> create or replace

2 procedure PRC is

3 begin

4 pkg.p1;

5 end;

6 /

Procedure created.

Page 234: Mar11 11g Developers 7 Short

234

SQL> create or replace

2 package PKG is

3 procedure P1;

4 procedure P2;

5 end;

6 /

Package created.

SQL> create or replace

2 package body PKG is

3 procedure P1 is

4 x number;

5 begin

6 x := 1;

7 end;

8

9 procedure p2 is

10 x number;

11 begin

12 x := myseq.nextval;

13 end;

14 end;

15 /

Package body created.

Page 235: Mar11 11g Developers 7 Short

235

SQL> select status

2 from user_objects

3 where object_name = 'PRC';

STATUS

-------

INVALID

SQL> select status

2 from user_objects

3 where object_name = 'PRC';

STATUS

-------

VALID

10g and below

11g

Page 236: Mar11 11g Developers 7 Short

236

package D

Page 237: Mar11 11g Developers 7 Short

237

the order is important

Page 238: Mar11 11g Developers 7 Short

238

SQL> create or replace

2 package PKG is

3 procedure p1;

4 end;

5 /

Package created.

SQL> create or replace

2 package body PKG is

3 procedure p1 is

4 x number;

5 begin

6 x := 1;

7 end;

8

9 end;

10 /

Package body created.

Page 239: Mar11 11g Developers 7 Short

239

SQL> create or replace

2 package PKG is

3 procedure p2;

4 procedure p1;

5 end;

6 /

Package created.

SQL> create or replace

2 package body PKG is

3 procedure p2 is

4 x number;

5 begin

6 x := myseq.nextval;

7 end;

8

9 procedure p1 is

10 x number;

11 begin

12 x := 1;

13 end;

14

15 end;

16 /

Package body created.

Page 240: Mar11 11g Developers 7 Short

240

moral of the story

Page 241: Mar11 11g Developers 7 Short

241

change package bodies

(as before)

Page 242: Mar11 11g Developers 7 Short

242

add to bottom of specs

Page 243: Mar11 11g Developers 7 Short

243

this is NOT about state

Page 244: Mar11 11g Developers 7 Short

244

SQL> create or replace

2 package PKG is

3 procedure p1;

4 end;

5 /

Package created.

SQL> create or replace

2 package body PKG is

3

4 my_global_var date;

5

6 procedure p1 is

7 x number;

8 begin

9 if my_global_var is null then

10 my_global_var := sysdate;

11 end if;

12 end;

13 end;

14 /

Package body created.

Page 245: Mar11 11g Developers 7 Short

245

SQL> create or replace

2 procedure PRC is

3 begin

4 pkg.p1;

5 end;

6 /

Procedure created.

SQL> exec PRC;

SQL> create or replace

2 package body PKG is

3

4 my_global_var date;

5

6 procedure p1 is

7 x number;

8 begin

9 if my_global_var is null then

10 my_global_var := sysdate;

11 end if;

12 end;

13 end;

14 /

Package body created.

SQL> exec PRC;

BEGIN PRC; END;

*

ERROR at line 1:

ORA-04068: existing state of packages has been discarded

ORA-04061: existing state of package body "PKG" has been invalidated

ORA-04065: not executed, altered or dropped package body "PKG"

ORA-06508: PL/SQL: could not find program unit being called: "PKG"

ORA-06512: at "PRC", line 3

ORA-06512: at line 1

Page 246: Mar11 11g Developers 7 Short

246

keep stateful data separate

minimise global variables

store types separately

Page 247: Mar11 11g Developers 7 Short

247

you may have noticed...

Page 248: Mar11 11g Developers 7 Short

248

SQL> create or replace

2 package body PKG is

3 procedure p2 is

4 x number;

5 begin

6 x := myseq.nextval;

7 end;

8

9 procedure p1 is

10 x number;

11 begin

12 x := 1;

13 end;

14

15 end;

16 /

Package body created.

Page 249: Mar11 11g Developers 7 Short

249

Direct sequence access

Page 250: Mar11 11g Developers 7 Short

250

Page 251: Mar11 11g Developers 7 Short

251

can we reduce the risk further ?

Page 252: Mar11 11g Developers 7 Short
Page 253: Mar11 11g Developers 7 Short

253

SQL> create or replace

2 procedure THE_SINGLE_MOST_IMPORTANT_PROC_IN_MY_APP is

begin

....

Page 254: Mar11 11g Developers 7 Short

254

11.2

Page 255: Mar11 11g Developers 7 Short

255

Page 256: Mar11 11g Developers 7 Short

256

"version control"

Page 257: Mar11 11g Developers 7 Short

257

package PKG is

select COL1, COL2

from MY_VIEW

package PKG(V2) is

select COL1, NEW_COL

from MY_VIEW(V2)

both in active use !

Page 258: Mar11 11g Developers 7 Short

258

editions

Page 259: Mar11 11g Developers 7 Short

259

SQL> desc DBA_EDITIONS

Name Null? Type

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

EDITION_NAME NOT NULL VARCHAR2(30)

PARENT_EDITION_NAME VARCHAR2(30)

USABLE VARCHAR2(3)

Page 260: Mar11 11g Developers 7 Short

260

SQL> select *

2 from DBA_EDITIONS;

EDITION_NAME PARENT_EDITION USABLE

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

ORA$BASE YES

Page 261: Mar11 11g Developers 7 Short

261

PKG1 PKG2 PKG3 PKG4 PKG5PKG2 PKG4

PKG1 PKG3 PKG5

ora$base

version2

Page 262: Mar11 11g Developers 7 Short

262

no space =

probably editionable

Page 263: Mar11 11g Developers 7 Short

263

indexes

Page 264: Mar11 11g Developers 7 Short

264

Invisible indexes

Page 265: Mar11 11g Developers 7 Short

265

tables

Page 266: Mar11 11g Developers 7 Short

266

views

Page 267: Mar11 11g Developers 7 Short

267

SQL> desc MY_TABLE

Name Null? Type

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

V1_COL1 NUMBER

V1_COL2 DATE

V1_COL3 VARCHAR2(10)

V1_ONLY_COL4 VARCHAR2(10)

V2_NEWCOL5 DATE

V2_NEWCOL6 NUMBER

version1

version2

create view V_MY_TABLE as

select V1_COL1 as col1,

V1_COL2 as col2,

V1_COL3 as col3,

V1_ONLY_COL4 as col4,

from MY_TABLE

create view V_MY_TABLE as

select V1_COL1 as col1,

V1_COL2 as col2,

V1_COL3 as col3,

V2_NEWCOL5 as col5,

V2_NEWCOL6 as col6

from MY_TABLE

Page 268: Mar11 11g Developers 7 Short

268

(special) viewseditioning

Page 269: Mar11 11g Developers 7 Short

269

basic example

Page 270: Mar11 11g Developers 7 Short

270

SQL> desc EMP

Name Null? Type

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

EMPNO NOT NULL NUMBER(4)

ENAME VARCHAR2(10)

JOB VARCHAR2(9)

MGR NUMBER(4)

HIREDATE DATE

SAL NUMBER(7,2)

COMM NUMBER(7,2)

DEPTNO NUMBER(2)

Page 271: Mar11 11g Developers 7 Short

271

SQL> create or replace

2 package body EMP_MAINT is

3 procedure hire_emp(p_empno emp.empno%type,

4 p_ename emp.ename%type,

5 p_job emp.job%type,

6 p_sal emp.sal%type,

7 p_deptno emp.deptno%type) is

8 begin

9 insert into EMP

10 (empno,ename,job,sal,deptno)

11 values

12 (p_empno,p_ename,p_job,p_sal,p_deptno);

13 end;

14 end;

15 /

Package body created.

Page 272: Mar11 11g Developers 7 Short

272

version 2

Page 273: Mar11 11g Developers 7 Short

273

SQL> desc EMP

Name Null? Type

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

EMPNO NOT NULL NUMBER(4)

ENAME VARCHAR2(10)

JOB VARCHAR2(9)

MGR NUMBER(4)

HIREDATE DATE

SAL NUMBER(7,2)

COMM NUMBER(7,2)

DEPTNO NUMBER(2)

ETYPE VARCHAR2(10)

TERMINATION_DATE DATE

Contract/Permanent

End of Contract

Page 274: Mar11 11g Developers 7 Short

274

old style

Page 275: Mar11 11g Developers 7 Short

275

SQL> alter table EMP add ETYPE VARCHAR2(1);

Table altered.

SQL> alter table EMP add TERMINATION_DATE DATE;

Table altered.

SQL> update EMP set ETYPE = 'Permanent';

14 rows updated.

SQL> alter table EMP modify ETYPE not null;

Table altered.

SQL> alter table EMP add constraint

2 EMP_CHK01 check ( ETYPE in ('Contract',

'Permanent'));

Table altered.

Page 276: Mar11 11g Developers 7 Short

276

broken application

Page 277: Mar11 11g Developers 7 Short

277

SQL> exec EMP_MAINT.HIRE_EMP(1,'Sue','SALES',10,10)

BEGIN EMP_MAINT.HIRE_EMP(1,'Sue','SALES',10,10); END;

*

ERROR at line 1:

ORA-01400: cannot insert NULL into ("SCOTT"."EMP"."ETYPE")

ORA-06512: at "SCOTT.EMP_MAINT", line 8

ORA-06512: at line 1

Page 278: Mar11 11g Developers 7 Short

278

outage

Page 279: Mar11 11g Developers 7 Short

279

SQL> create or replace

2 package body EMP_MAINT is

3 procedure hire_emp(p_empno emp.empno%type,

4 p_ename emp.ename%type,

5 p_job emp.job%type,

6 p_sal emp.sal%type,

7 p_deptno emp.deptno%type,

8 p_etype emp.etype%type,

9 p_term emp.termination_date%type) is

10 begin

11 insert into EMP

12 (empno,ename,job,sal,deptno,etype,termination_date)

13 values

14 (p_empno,p_ename,p_job,p_sal,p_deptno,p_etype,p_term);

15 end;

16 end;

17 /

Package body created.

Page 280: Mar11 11g Developers 7 Short

280

now with editions

Page 281: Mar11 11g Developers 7 Short

281

step 1

Page 282: Mar11 11g Developers 7 Short

282

enable editions

Page 283: Mar11 11g Developers 7 Short

283

SQL> alter user SCOTT enable editions;

User altered.

Page 284: Mar11 11g Developers 7 Short

284

this is a big deal

Page 285: Mar11 11g Developers 7 Short

285

Enabling editions is retroactive and irreversible.

- 11g2 doc

Page 286: Mar11 11g Developers 7 Short

286

Every editionable-type object that

the user has owned or will own

is an editioned object.

Page 287: Mar11 11g Developers 7 Short

287

step 2

Page 288: Mar11 11g Developers 7 Short

288

abstract your tables

Page 289: Mar11 11g Developers 7 Short

289

SQL> alter table EMP rename to "_EMP";

Table altered.

SQL> create or replace

2 editioning view EMP as

3 select * from "_EMP";

View created.

SQL> exec dbms_utility.compile_schema(user)

PL/SQL procedure successfully completed.

Page 290: Mar11 11g Developers 7 Short

290

obtuse

_EMP

Page 291: Mar11 11g Developers 7 Short

291

SQL> select * from _EMP;

select * from _EMP

*

ERROR at line 1:

ORA-00911: invalid character

Page 292: Mar11 11g Developers 7 Short

292

may mean an outage

Page 293: Mar11 11g Developers 7 Short

293

SQL> alter table "_EMP" add ETYPE VARCHAR2(1);

Table altered.

SQL> alter table "_EMP" add TERMINATION_DATE DATE;

Table altered.

SQL> alter table "_EMP" add constraint

2 EMP_CHK01 check ( ETYPE in ('Contract',

'Permanent'));

Table altered.

SQL> alter table "_EMP" modify ETYPE not null;

Table altered.

Page 294: Mar11 11g Developers 7 Short

294

create an edition

Page 295: Mar11 11g Developers 7 Short

295

SQL> create edition "APP_V2"

as child of ORA$BASE2 /

Edition created.

Page 296: Mar11 11g Developers 7 Short

296

SQL> conn SCOTT/TIGER

Connected.

SQL> alter session set edition = APP_V2;

ERROR:

ORA-38802: edition does not exist

Page 297: Mar11 11g Developers 7 Short

297

SQL> grant USE on edition APP_V2 to SCOTT;

Grant succeeded.

Page 298: Mar11 11g Developers 7 Short

298

SQL> alter session set edition = APP_V2;

SQL> create or replace

2 editioning view EMP as

3 select * from "_EMP"

4 /

View created.

Page 299: Mar11 11g Developers 7 Short

299

SQL> alter session set edition = ORA$BASE;

Session altered.

SQL> desc EMP

Name Null? Type

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

EMPNO NOT NULL NUMBER(4)

ENAME VARCHAR2(10)

JOB VARCHAR2(9)

MGR NUMBER(4)

HIREDATE DATE

SAL NUMBER(7,2)

COMM NUMBER(7,2)

DEPTNO NUMBER(2)

Page 300: Mar11 11g Developers 7 Short

300

SQL> alter session set edition = APP_V2;

Session altered.

SQL> desc EMP

Name Null? Type

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

EMPNO NOT NULL NUMBER(4)

ENAME VARCHAR2(10)

JOB VARCHAR2(9)

MGR NUMBER(4)

HIREDATE DATE

SAL NUMBER(7,2)

COMM NUMBER(7,2)

DEPTNO NUMBER(2)

ETYPE VARCHAR2(10)

TERMINATION_DATE DATE

Page 301: Mar11 11g Developers 7 Short

301

SQL> select sys_context('USERENV',

2 'CURRENT_EDITION_NAME') edt

3 from dual;

EDT

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

APP_V2

Page 302: Mar11 11g Developers 7 Short

302

SQL> create or replace

2 package body EMP_MAINT is

3 procedure hire_emp(p_empno emp.empno%type,

4 p_ename emp.ename%type,

5 p_job emp.job%type,

6 p_sal emp.sal%type,

7 p_deptno emp.deptno%type,

8 p_etype emp.etype%type,

9 p_term emp.termination_date%type) is

10 begin

11 insert into EMP

12 (empno,ename,job,sal,deptno,etype,termination_date)

13 values

14 (p_empno,p_ename,p_job,p_sal,p_deptno,p_etype,p_term);

15 end;

16 end;

17 /

Package body created.

Page 303: Mar11 11g Developers 7 Short

303

SQL> alter session set edition = ORA$BASE;

Session altered.

SQL> begin

2 EMP_MAINT.HIRE_EMP(

3 p_empno =>1,

4 p_ename =>'Sue',

5 p_job =>'SALES',

6 p_sal =>10,

7 p_deptno =>20);

8 end;

9 /

PL/SQL procedure successfully completed.

Page 304: Mar11 11g Developers 7 Short

304

SQL> alter session set edition = APP_V2;

Session altered.

SQL> begin

2 EMP_MAINT.HIRE_EMP(

3 p_empno =>2,

4 p_ename =>'Mike',

5 p_job =>'SALES',

6 p_sal =>10,

7 p_deptno =>20,

8 p_etype =>'Contract'

9 p_term =>'10-JAN-2012');

10 end;

11 /

PL/SQL procedure successfully completed.

Page 305: Mar11 11g Developers 7 Short

305

we're close....

Page 306: Mar11 11g Developers 7 Short

306

ETYPE not null

Page 307: Mar11 11g Developers 7 Short

307

SQL> alter session set edition = APP_V2;

Session altered.

SQL> begin

2 EMP_MAINT.HIRE_EMP(

3 p_empno =>2,

4 p_ename =>'Mike',

5 p_job =>'SALES',

6 p_sal =>10,

7 p_deptno =>20,

8 p_etype =>null

9 p_term =>'10-JAN-2012');

10 end;

11 /

PL/SQL procedure successfully completed.

Page 308: Mar11 11g Developers 7 Short

308

constraints not (natively) editionable

Page 309: Mar11 11g Developers 7 Short

309

SQL> alter table "_EMP" add constraint

2 EMP_CHK02 check (

3 SYS_CONTEXT('USERENV',

4 'CURRENT_EDITION_NAME')

5 = 'ORA$BASE'

6 OR ETYPE is not null

7 );

Table altered.

Page 310: Mar11 11g Developers 7 Short

310

cross edition consistency

APP_V2

"everyone has an ETYPE"

APP_V1 (aka ORA$BASE)

"what is an ETYPE"

Page 311: Mar11 11g Developers 7 Short

311

cross edition triggers

Page 312: Mar11 11g Developers 7 Short

312

SQL> alter session set edition = APP_V2;

Session altered.

SQL> CREATE OR REPLACE TRIGGER emp_v1_to_v2

2 BEFORE INSERT OR UPDATE ON "_EMP"

3 FOR EACH ROW

4 FORWARD CROSSEDITION

5 DISABLE

6 BEGIN

7 :new.etype := nvl(:new.etype,'Permanent');

8 :new.termination_date := null;

9 END;

10 /

Trigger created.

Page 313: Mar11 11g Developers 7 Short

313

SQL> CREATE OR REPLACE TRIGGER emp_v2_to_v1

2 BEFORE INSERT OR UPDATE ON "_EMP"

3 FOR EACH ROW

4 REVERSE CROSSEDITION

5 DISABLE

6 BEGIN

7 ...

8 ...

9 END;

10 /

Trigger created.

Page 314: Mar11 11g Developers 7 Short

314

both in the new edition

"the working edition is sacred"

Page 315: Mar11 11g Developers 7 Short

315

SQL> alter session set edition = APP_V2;

Session altered.

SQL> alter trigger EMP_V1_TO_V2 enable;

Trigger altered.

Page 316: Mar11 11g Developers 7 Short

316

all new / modified data

Page 317: Mar11 11g Developers 7 Short

317

historical data

uncommitted data

Page 318: Mar11 11g Developers 7 Short

318

SQL> alter session set edition = ORA$BASE;

Session altered.

SQL> declare

2 ok boolean;

3 scn number;

4 begin

5 ok :=

6 dbms_utility.wait_on_pending_dml('"_EMP"',10, scn);

7

8 if ok then

9 update EMP set sal=sal;

10 end if;

11 end;

12 /

PL/SQL procedure successfully completed.

Page 319: Mar11 11g Developers 7 Short

319

SQL> select empno, etype from "_EMP";

EMPNO ETYPE

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

1 Contract

2 Contract

7369 Permanent

7499 Permanent

7521 Permanent

7566 Permanent

7654 Permanent

7698 Permanent

7782 Permanent

7788 Permanent

7839 Permanent

7844 Permanent

7876 Permanent

7900 Permanent

7902 Permanent

7934 Permanent

Page 320: Mar11 11g Developers 7 Short

320

or DBMS_SQL

Page 321: Mar11 11g Developers 7 Short

321

or DBMS_PARALLEL_EXECUTE

Page 322: Mar11 11g Developers 7 Short

322

voila !

Page 323: Mar11 11g Developers 7 Short

323

move people over

Page 324: Mar11 11g Developers 7 Short

324

SQL> create or replace

2 trigger DEFAULT_EDITION

3 after logon on database

4 begin

5 execute immediate

6 'alter session set edition = APP_V2';

7 end;

8 /

Page 325: Mar11 11g Developers 7 Short

325

SQL> create or replace

2 trigger DEFAULT_EDITION

3 after logon on database

4 begin

5 dbms_session.set_edition_deferred( 'APP_V2' );

7 end;

8 /

Page 326: Mar11 11g Developers 7 Short

326

better in 11.2.0.2

use services

Page 327: Mar11 11g Developers 7 Short

327

retire old edition

optional

Page 328: Mar11 11g Developers 7 Short

328

how do I get started

Page 329: Mar11 11g Developers 7 Short

329

first.... come clean

Page 330: Mar11 11g Developers 7 Short

330

Page 331: Mar11 11g Developers 7 Short

331

taking ... outagesstop ...

Page 332: Mar11 11g Developers 7 Short

332

before

you

start

Page 333: Mar11 11g Developers 7 Short

333

Page 334: Mar11 11g Developers 7 Short

334

more complicated

than you think....

Page 335: Mar11 11g Developers 7 Short

335

enabling editions

Page 336: Mar11 11g Developers 7 Short

336

probably the whole database

Page 337: Mar11 11g Developers 7 Short

337

cross user consistency

Page 338: Mar11 11g Developers 7 Short

338

SQL> connect / as sysdba

Connected.

sys@db112> alter user TO_BE_EDITIONED enable editions;

alter user TO_BE_EDITIONED enable editions

*

ERROR at line 1:

ORA-38819: user TO_BE_EDITIONED owns one or more

objects whose type is editionable and that have

noneditioned dependent objects

Page 339: Mar11 11g Developers 7 Short

339

select *

from DBA_DEPENDENCIES

where ( OWNER in ( SELECT username

from dba_users

where EDITIONS_ENABLED = 'N' )

OR TYPE NOT IN (

'VIEW','SYNONYM','PROCEDURE','FUNCTION'

,'PACKAGE','NON-EXISTENT','PACKAGE BODY'

,'TRIGGER','TYPE','TYPE BODY'

,'LIBRARY','ASSEMBLY')

)

and REFERENCED_OWNER = 'TO_BE_EDITIONED'

and TYPE IN (

'VIEW','SYNONYM','PROCEDURE','FUNCTION'

,'PACKAGE','NON-EXISTENT','PACKAGE BODY'

,'TRIGGER','TYPE','TYPE BODY'

,'LIBRARY','ASSEMBLY')

and REFERENCED_OWNER != OWNER

Page 340: Mar11 11g Developers 7 Short

340

table = data store

for all versions...

Page 341: Mar11 11g Developers 7 Short

341

online upgrade ...

Page 342: Mar11 11g Developers 7 Short

342

... is not just editions

Page 343: Mar11 11g Developers 7 Short

343

editions

ddl_timeout

invisible indexes

column naming

create index online

fallback

version control

constraints

Page 344: Mar11 11g Developers 7 Short

344

existing processes / scripts

Page 345: Mar11 11g Developers 7 Short

345

drop

Page 346: Mar11 11g Developers 7 Short

346

rename

Page 347: Mar11 11g Developers 7 Short

347

edition v1

edition v2

T1 T2

T2 T1

Page 348: Mar11 11g Developers 7 Short

348

edition v1

edition v2

col1 NUMBER

col1 DATE

_v1

_v2

Page 349: Mar11 11g Developers 7 Short

349

edition v1

edition v2

T1 (PK=col1,col2)

T1 (PK=col1,col3)

Page 350: Mar11 11g Developers 7 Short

350

contexts

database links

queues

VPD

FGA

Page 351: Mar11 11g Developers 7 Short

351

Page 352: Mar11 11g Developers 7 Short

352

wrap up

Page 353: Mar11 11g Developers 7 Short

353

lots of things not covered

Page 354: Mar11 11g Developers 7 Short

354

11g / 11.2 very very nice

Page 355: Mar11 11g Developers 7 Short

355

"Oracle 11g is the greatest

invention in the history of man"

- Anon, 2008

Page 356: Mar11 11g Developers 7 Short
Page 357: Mar11 11g Developers 7 Short

Connor McDonald

OracleDBA

co

.uk

357

Page 358: Mar11 11g Developers 7 Short

358

ORA-00041

www.oracledba.co.uk

“active time limit exceeded - session terminated”