#
# This script belongs to create_index_during_execution.plsql, go there
# for a little more information.
#
use warnings;
use strict;
# https://github.com/ReneNyffenegger/OracleTool
use lib 'C:\github\OracleTool';
use OracleTool qw(connect_db);
my $connection_string = shift;
my $dbh = connect_db($connection_string);
# $dbh->do("declare s number; begin s:=sys.dbms_pipe.create_pipe('index_during_exec'); end;");
my $sth = $dbh -> prepare (qq{
declare
s integer;
begin
s := sys.dbms_pipe.receive_message('index_during_exec');
if s = 0 then
dbms_pipe.unpack_message(:msg);
end if;
end;
});
my $msg = ' ' x 200;
$sth -> bind_param_inout(':msg', \$msg, 200, {TYPE=>DBI::SQL_VARCHAR});
$sth -> execute;
print "Msg recevied: $msg\n";
if ($msg eq 'create index now') {
$dbh -> do ('create index tq84_1000000_ix on tq84_1000000(text)');
print "Index built\n";
}
$dbh -> rollback;
--
-- This file and the perl script create_index_during_execution.pl is
-- used to demonstrated that an index can be built while a PL/SQL
-- package accesses a table on which the index should be used.
--
-- First, the table tq84_1000000 is createed and filled with 1000000
-- records. Then the package tq84_1000000 iterates 51 times and
-- selects a specific record from the table. After 4 or so selects
-- it writes into a pipe that the index should now be built. This
-- is the perl script's part: it waits for the message on the pipe
-- and as soon as the message arrives, it creates the index.
--
-- While the plsql package iterates and selects from the table,
-- it prints (dbms_output) how long it took to select for each
-- statement. These times should go down dramatically as soon
-- as the index is built.
--
-- Start the perl script first, then run this file in SQL*Plus.
--
create table tq84_1000000 (
num number,
text varchar2(1000)
);
begin
for i in 1 .. 1000000 loop
insert into tq84_1000000 values (
i,
to_char(date '-4712-01-01' + i-1, 'jsp')
);
end loop;
end;
/
commit;
-- select count(*) from tq84_1000000;
-- select * from tq84_1000000 where num = 555555;
create package tq84_index_during_exec as
procedure main;
end tq84_index_during_exec;
/
create package body tq84_index_during_exec as
procedure main is
v_num number;
v_start_time number;
begin
for i in 0 .. 50 loop
v_start_time := dbms_utility.get_time;
select num into v_num
from tq84_1000000
where text = 'five hundred fifty-five thousand five hundred fifty-five';
dbms_output.put_line('select took: ' || (dbms_utility.get_time - v_start_time) / 100 || ' secs');
if i = 3 then
declare
status number;
begin
sys.dbms_pipe.pack_message('create index now');
status := sys.dbms_pipe.send_message('index_during_exec');
end;
end if;
end loop;
end main;
end tq84_index_during_exec;
/
show errors
set timing on
exec tq84_index_during_exec.main
set timing off
drop package tq84_index_during_exec;
--drop index tq84_1000000_ix;
drop table tq84_1000000 purge;
drop table tq84_c purge;
drop table tq84_p purge;
create table tq84_p (
col_ix_1 varchar2(10) not null,
col_ix_2 varchar2(10) null,
col_data varchar2(10),
--
constraint tq84_p_ix unique (col_ix_1, col_ix_2)
);
create table tq84_c (
id number,
col_fk_1 not null,
col_fk_2 null,
-- ---------------------------------------------------------------------------------------
-- Foreign keys can be created to unique indexes (instead of primary keys):
--
constraint tq84_fk foreign key (col_fk_1, col_fk_2) references tq84_p (col_ix_1, col_ix_2)
-- ---------------------------------------------------------------------------------------
);
desc tq84_c;
-- Name Null Typ
-- -------- -------- ------------
-- ID NUMBER
-- COL_FK_1 NOT NULL VARCHAR2(10)
-- COL_FK_2 VARCHAR2(10)
--
insert into tq84_p values ('foo' , 'bar', 'baz' );
insert into tq84_p values ('null', null, 'null' );
insert into tq84_p values ('null', 'null', '''null''');
select * from tq84_p;
insert into tq84_c values (1, 'foo' , 'bar');
insert into tq84_c values (2, 'null', 'null');
insert into tq84_c values (3, 'null', null);
-- ----------------------------------------------------------------
-- This record cannot be inserted because the values 'bla', 'bla'
-- don't exist in the parent table:
--
insert into tq84_c values (4, 'bla' , 'bla');
-- ----------------------------------------------------------------
-- However, this record CAN be inserted because null values are
-- not checked:
--
insert into tq84_c values (5, 'bla' , null);
create table tq84_table (
id number,
txt varchar2(10),
dt date
);
create index tq84_global_partitioned_index on tq84_table (dt)
global partition by range(dt) (
partition tq84_ix_2010 values less than ( date '2011-01-01' ),
partition tq84_ix_2011 values less than ( date '2012-01-01' ),
partition tq84_ix_2012 values less than ( date '2013-01-01' ),
partition tq84_ix_9999 values less than ( maxvalue )
);
select
index_name,
index_type,
partitioned
from
user_indexes
where
table_name = 'TQ84_TABLE';
--
select
partition_name
from
user_ind_partitions
where
index_name = 'TQ84_GLOBAL_PARTITIONED_INDEX';
drop table tq84_table purge;
--
-- The name of an index is in a different namespace thant
-- the table. So, the following two statements
-- cause no error:
--
create table tq84_foo (a number, b number);
create index tq84_foo on tq84_foo(a);
drop table tq84_partial_index_table purge;
create table tq84_partial_index_table (
id number primary key,
part varchar2( 3) not null check (part in ('foo', 'bar', 'baz')),
col_1 varchar2(10) not null,
col_2 varchar2(10)
)
partition by list (part) (
partition tq84_partial_index_part_foo values ('foo') indexing on,
partition tq84_partial_index_part_bar values ('bar') indexing off,
partition tq84_partial_index_part_baz values ('baz') indexing on
);
create index tq84_ix_partial_index
on tq84_partial_index_table(col_1)
INDEXING PARTIAL local
;
insert into tq84_partial_index_table values (1, 'foo', 'abc', 'def');
insert into tq84_partial_index_table values (2, 'bar', 'ghi', 'jkl');
insert into tq84_partial_index_table values (3, 'baz', 'mno', 'pqr');
select
partition_name,
status
from
user_ind_partitions
where
index_name = 'TQ84_IX_PARTIAL_INDEX';
create table tq84_dimension (
id number primary key,
flag_1 varchar2(2) not null,
flag_2 varchar2(2) not null,
col_1 varchar2(20),
col_2 varchar2(20),
col_3 varchar2(50)
)
clustering
by linear order (
flag_1,
flag_2
);
create table tq84_fact (
id number primary key,
dimension_id not null references tq84_dimension,
fact_1 varchar2(50),
fact_2 varchar2(50),
fact_3 varchar2(50)
)
clustering
tq84_fact join tq84_dimension on (tq84_fact.dimension_id = tq84_dimension.id)
by linear order (
tq84_dimension.col_1,
tq84_dimension.col_2,
tq84_fact.fact_1,
tq84_fact.fact_2
);
select
table_name,
clustering_type,
on_load,
on_datamovement,
with_zonemap
from
user_clustering_tables
where
table_name like 'TQ84_%';
drop table tq84_fact purge;
drop table tq84_dimension purge;
set timing on
drop table tq84_stage purge;
drop table tq84_clustering;
create table tq84_stage as
select
c flag,
lpad('x', 1000, 'x') data_1,
lpad('x', 1000, 'y') data_2
from (
select
chr(ascii('m') + 2.7 * dbms_random.normal) c
from
dual
connect by level < 100000
)
where
c between 'a' and 'z';
commit;
create table tq84_clustering (
flag varchar2( 1) not null,
data_1 varchar2(1000) not null,
data_2 varchar2(1000) not null
)
clustering by linear order(flag)
yes on load
yes on data movement
;
insert /*+ append clustering */ into tq84_clustering
select * from tq84_stage;
commit;
select
tab,
--max_block_no,
--min_block_no,
max_block_no - min_block_no diff_block_no,
cnt_dist_block_no,
max_rel_fno,
min_rel_fno
from (
select
'stage' as tab,
min ( dbms_rowid.rowid_relative_fno (rowid)) min_rel_fno,
max ( dbms_rowid.rowid_relative_fno (rowid)) max_rel_fno,
min ( dbms_rowid.rowid_block_number (rowid)) min_block_no,
max ( dbms_rowid.rowid_block_number (rowid)) max_block_no,
count(distinct dbms_rowid.rowid_block_number (rowid)) cnt_dist_block_no
from
tq84_stage
where
flag = 'g'
union all
select
'clustering' as tab,
min ( dbms_rowid.rowid_relative_fno (rowid)) min_rel_fno,
max ( dbms_rowid.rowid_relative_fno (rowid)) max_rel_fno,
min ( dbms_rowid.rowid_block_number (rowid)) min_block_no,
max ( dbms_rowid.rowid_block_number (rowid)) max_block_no,
count(distinct dbms_rowid.rowid_block_number (rowid)) cnt_dist_block_no
from
tq84_clustering
where
flag = 'g'
);
create table tq84_clustering (
id number primary key,
flag_1 varchar2(2) not null,
flag_2 varchar2(2) not null,
col_1 varchar2(20),
col_2 varchar2(20),
col_3 varchar2(50)
)
clustering
by linear order (
flag_1,
flag_2
);
select * from user_tables where clustering = 'YES';
drop table tq84_clustering;
create table tq84_identity (
id number generated as identity,
txt varchar2(10)
);
insert into tq84_identity (txt) values ('one' );
insert into tq84_identity (txt) values ('two' );
insert into tq84_identity (txt) values ('three');
insert into tq84_identity (txt) values ('four' );
insert into tq84_identity (txt) values ('five' );
declare
id_generated number;
begin
insert into tq84_identity (txt) values ('six' ) returning id into id_generated;
dbms_output.put_line('id_generated: ' || id_generated);
-- id_generated: 6
end;
/
select * from tq84_identity;
--
-- ID TXT
-- ---------- ----------
-- 1 one
-- 2 two
-- 3 three
-- 4 four
-- 5 five
-- 6 six
drop table tq84_identity purge;
create table tq84_ilm_policy (
id number primary key,
col_1 varchar2(10),
col_2 varchar2(10)
)
ilm add policy row store compress advanced segment after 3 days of no modification
;
-- Alternatively, with alter table:
--
-- alter table tq84_ilm_policy
-- ilm add policy row store compress advanced segment after 3 days of no modification;
create type tq84_some_type as object (
a number,
b number
);
/
create type tq84_some_table as table of tq84_some_type;
/
create or replace type tq84_some_type force as object (
a varchar2(10),
b number
);
/
select status from user_objects where object_name = 'TQ84_SOME_TABLE';
declare
a tq84_some_table := tq84_some_table();
begin
a.extend;
a(a.count) := tq84_some_type('foo', 1);
end;
/
select status from user_objects where object_name = 'TQ84_SOME_TABLE';
drop type tq84_some_table;
drop type tq84_some_type;
--
-- Compare /SQL/delete/subquery.sql
--
create table tq84_table_1 (
id number primary key, -- Note: without primary key, all columns in the view would become non-updatable.
txt varchar2(10)
);
create table tq84_table_2 (
id number,
txt varchar2(10)
);
create view tq84_updatable_join_view as
select
t1.id id_1,
t2.id id_2,
t1.txt txt_1,
t2.txt txt_2
from
tq84_table_1 t1 join
tq84_table_2 t2 on t1.id = t2.id;
select
column_name,
updatable
from
user_updatable_columns
where
table_name = 'TQ84_UPDATABLE_JOIN_VIEW';
drop view tq84_updatable_join_view;
drop table tq84_table_2 purge;
drop table tq84_table_1 purge;
--
-- 2019-09-03: use user_all_dba_cdb_view.sql
--
column obj format a30
with u as ( select substr(object_name, 6) obj, object_name from dba_objects where owner = 'SYS' and object_name like 'USER\_%' escape '\'),
a as ( select substr(object_name, 5) obj, object_name from dba_objects where owner = 'SYS' and object_name like 'ALL\_%' escape '\'),
d as ( select substr(object_name, 5) obj, object_name from dba_objects where owner = 'SYS' and object_name like 'DBA\_%' escape '\'),
c as ( select substr(object_name, 5) obj, object_name from dba_objects where owner = 'SYS' and object_name like 'CDB\_%' escape '\'),
o as ( select obj from u union
select obj from a union
select obj from d union
select obj from c)
select
nvl2(u.obj, 'USER', '-'),
nvl2(a.obj, 'ALL' , '-'),
nvl2(d.obj, 'DBA' , '-'),
nvl2(d.obj, 'CDB' , '-'),
o.obj
from
o left join
u on o.obj = u.obj left join
a on o.obj = a.obj left join
d on o.obj = d.obj left join
c on o.obj = c.obj
order by
o.obj;
@spool user_all_dba_names.html
select '<table>' from dual;
with u as ( select substr(object_name, 6) obj, object_name from dba_objects where owner = 'SYS' and object_name like 'USER\_%' escape '\'), -- '
a as ( select substr(object_name, 5) obj, object_name from dba_objects where owner = 'SYS' and object_name like 'ALL\_%' escape '\'), -- '
d as ( select substr(object_name, 5) obj, object_name from dba_objects where owner = 'SYS' and object_name like 'DBA\_%' escape '\'), -- '
o as ( select obj from u union
select obj from a union
select obj from d)
select
'<tr>' ||
'<td>Todo:</td>' ||
'<td>' || nvl2(u.obj, '<a href="' || rpad(lower(o.obj || '"'), 26) || '>user_' || rpad(lower(o.obj), 25) || '</a>', rpad(' ', 70)) || '</td>' ||
'<td>' || nvl2(a.obj, '<a href="' || rpad(lower(o.obj || '"'), 26) || '>all_' || rpad(lower(o.obj), 25) || '</a>', rpad(' ', 70)) || '</td>' ||
'<td>' || nvl2(d.obj, '<a href="' || rpad(lower(o.obj || '"'), 26) || '>dba_' || rpad(lower(o.obj), 25) || '</a>', rpad(' ', 70)) || '</td>' ||
'</tr>'
from
o left join
u on o.obj = u.obj left join
a on o.obj = a.obj left join
d on o.obj = d.obj
order by
o.obj;
select '<table>' from dual;
@spool off
Installed - data-dictionary - col - comments - example-01.sql
create table tq84_col_comments (
col_nm number,
col_vc varchar2(10),
col_dt date
);
comment on column tq84_col_comments.col_nm is 'Column with numbers';
comment on column tq84_col_comments.col_vc is 'Column with varchars';
comment on column tq84_col_comments.col_dt is 'Column with dates';
select
column_name,
substrb(comments, 1, 50) comments
from
user_col_comments
where
table_name = 'TQ84_COL_COMMENTS';
-- COLUMN_NAME COMMENTS
-- ------------------------------ --------------------------------------------------
-- COL_NM Column with numbers
-- COL_VC Column with varchars
-- COL_DT Column with dates
drop table tq84_col_comments purge;
create type tq84_coll_obj as object (
dummy number
);
/
create type tq84_coll_tab as table of tq84_coll_obj;
/
create type tq84_coll_var as varying array (1000) of tq84_coll_obj;
/
create type tq84_coll_var_nn as varying array (1000) of tq84_coll_obj not null;
/
select
type_name,
coll_type,
elem_type_name,
--elem_type_owner
nulls_stored
from
user_coll_types
where
type_name like 'TQ84_COLL%';
drop type tq84_coll_var_nn;
drop type tq84_coll_var;
drop type tq84_coll_tab;
drop type tq84_coll_obj;
select /*+ parallel(16) */
logon__.os_user,
logon__.db_user,
logon__.extended_timestamp,
logoff_.extended_timestamp,
logoff_.statement_type, -- LOGOFF, LOGOFF BY CLEANUP
logon__.session_id
from
dba_common_audit_trail logon__ left join
dba_common_audit_trail logoff_ on logon__.session_id = logoff_.session_id and
logoff_.statement_type like 'LOGOFF%'
where
logon__.os_user = 'rnyffenegger' and
logon__.statement_type = 'LOGON'
order by
logon__.extended_timestamp desc;
select /*+ parallel(16) */
-- audit_type,
-- session_id,
-- proxy_sessionid,
-- statementid,
-- entryid,
extended_timestamp,
-- global_uid,
db_user,
priv_used, -- System privilege used to execute the action
sql_text,
client_id,
-- econtext_id,
-- ext_name,
os_user,
userhost,
-- os_process,
-- terminal,
instance_number,
object_schema,
object_name,
-- policy_name,
-- new_owner,
-- new_name,
-- action,
statement_type,
audit_option,
-- transactionid,
returncode,
-- scn,
comment_text,
sql_bind,
obj_privilege, -- Object privileges granted or revoked by a grant or revoke stmt.
sys_privilege, -- System privileges granted or revoked by a grant or revoke stmt.
admin_option,
os_privilege,
grantee,
ses_actions,
-- logoff_time,
-- logoff_lread, -- Number of logical reads for the session
-- logoff_pread, -- Number of physical reads for the session
-- logoff_lwrite, -- Number of logical writes for the session
-- logoff_dlock, -- Number of deadlocks detected during the session
-- session_cpu, -- Amount of CPU time used by the Oracle session
-- obj_edition_name,
dbid
from
dba_common_audit_trail
where
os_user = 'rnyffenegger'
order by
extended_timestamp desc;
select
owner,
name,
type,
mode_held,
mode_requested,
session_id
from
dba_ddl_locks
order by
case mode_requested
when 'Exclusive' then 1
when 'Share' then 2
when 'None' then 3
else 4 end,
owner,
name
;
select
alt "alter" ,
aud "audit" ,
com "comment" ,
del "delete" ,
gra "grant" ,
ind "index" ,
ins "insert" ,
loc "lock" ,
ren "rename" ,
sel "select" ,
upd "update" ,
--ref -- Obsolete
exe "execute" ,
fbk "flashback",
rea "read"
from
all_def_audit_opts
;
--
-- Show privileges on directories
--
select
dir.directory_name dir_name,
prv.grantee grantee,
max(case when prv.privilege = 'READ' then 'r' end) r,
max(case when prv.privilege = 'WRITE' then 'w' end) w,
max(case when prv.privilege = 'EXECUTE' then 'e' end) e,
dir.directory_path dir_path
from
dba_directories dir left join
dba_tab_privs prv on dir.directory_name = prv.table_name
group by
dir.directory_name,
dir.directory_path,
prv.grantee
order by
dir.directory_name,
prv.grantee;
select
to_char(obj.created, 'yyyy-mm-dd') obj_created,
--err.message_number,
err.name,
err.type,
err.line,
substr(err.text, 1, 100) err_text,
src.text
from
dba_errors err join
dba_objects obj on err.owner = obj.owner and
err.name = obj.object_name and
err.type = obj.object_type left join
dba_source src on err.owner = src.owner and
err.name = src.name and
err.type = src.type and
err.line = src.line
where
err.text not in ('PL/SQL: SQL Statement ignored', 'PL/SQL Statement ignored')
order by
obj.created
;
select
name,
detected_usages,
currently_used,
description,
first_usage_date,
last_usage_date
from
dba_feature_usage_statistics
where
version = '11.2.0.3.0';
select
ses.sid,
ses.serial#,
ses.username,
ses.osuser,
ses.status,
ses.program,
ses.logon_time,
ses.event,
lck.lock_type,
lck.mode_held,
lck.mode_requested,
lck.lock_id1,
lck.lock_id2,
lck.last_convert,
lck.blocking_others
from
dba_lock lck left join
v$session ses on lck.session_id = ses.sid
where
ses.osuser = 'rnyffenegger'
order by
ses.username,
ses.osuser;
Installed - data-dictionary - role - tab_privs - show-privs-for-specific-role.sql
select
owner,
table_name,
column_name,
privilege,
grantable
from
role_tab_privs
where
role = 'R_DEVELOP'
order by
owner,
table_name,
column_name nulls last,
privilege;
select
num_db_reports,
num_em_reports,
first_db_report_time,
last_db_report_time,
first_em_report_time,
last_em_report_time
from
dba_sql_monitor_usage
order by
first_db_report_time;
select
lower(name)
from
stmt_audit_option_map
order by
name;
--
-- administer any sql tuning set
-- administer database trigger
-- administer key management
-- administer resource manager
-- administer sql management object
-- administer sql tuning set
-- advisor
-- all statements
-- alter any assembly
-- alter any cluster
-- alter any cube
-- alter any cube build process
-- alter any cube dimension
-- alter any dimension
-- alter any edition
-- alter any evaluation context
-- alter any index
-- alter any indextype
-- alter any library
-- alter any materialized view
-- alter any measure folder
-- alter any mining model
-- alter any operator
-- alter any outline
-- alter any procedure
-- alter any role
-- alter any rule
-- alter any rule set
-- alter any sequence
-- alter any sql profile
-- alter any sql translation profile
-- alter any table
-- alter any trigger
-- alter any type
-- alter database
-- alter database link
-- alter java class
-- alter java resource
-- alter java source
-- alter mining model
-- alter profile
-- alter public database link
-- alter resource cost
-- alter rollback segment
-- alter sequence
-- alter session
-- alter sql translation profile
-- alter system
-- alter table
-- alter tablespace
-- alter user
-- analyze any
-- analyze any dictionary
-- audit any
-- backup any table
-- become user
-- change notification
-- cluster
-- comment any mining model
-- comment any table
-- comment edition
-- comment mining model
-- comment table
-- context
-- create any assembly
-- create any cluster
-- create any context
-- create any credential
-- create any cube
-- create any cube build process
-- create any cube dimension
-- create any dimension
-- create any directory
-- create any edition
-- create any evaluation context
-- create any index
-- create any indextype
-- create any job
-- create any library
-- create any materialized view
-- create any measure folder
-- create any mining model
-- create any operator
-- create any outline
-- create any procedure
-- create any rule
-- create any rule set
-- create any sequence
-- create any sql profile
-- create any sql translation profile
-- create any synonym
-- create any table
-- create any trigger
-- create any type
-- create any view
-- create assembly
-- create cluster
-- create credential
-- create cube
-- create cube build process
-- create cube dimension
-- create database link
-- create dimension
-- create evaluation context
-- create external job
-- create indextype
-- create java class
-- create java resource
-- create java source
-- create job
-- create library
-- create materialized view
-- create measure folder
-- create mining model
-- create operator
-- create pluggable database
-- create procedure
-- create profile
-- create public database link
-- create public synonym
-- create role
-- create rollback segment
-- create rule
-- create rule set
-- create sequence
-- create session
-- create sql translation profile
-- create synonym
-- create table
-- create tablespace
-- create trigger
-- create type
-- create user
-- create view
-- database link
-- debug any procedure
-- debug connect session
-- debug procedure
-- delete any cube dimension
-- delete any measure folder
-- delete any table
-- delete table
-- dequeue any queue
-- dimension
-- directory
-- direct_path load
-- direct_path unload
-- drop any assembly
-- drop any cluster
-- drop any context
-- drop any cube
-- drop any cube build process
-- drop any cube dimension
-- drop any dimension
-- drop any directory
-- drop any edition
-- drop any evaluation context
-- drop any index
-- drop any indextype
-- drop any library
-- drop any materialized view
-- drop any measure folder
-- drop any mining model
-- drop any operator
-- drop any outline
-- drop any procedure
-- drop any role
-- drop any rule
-- drop any rule set
-- drop any sequence
-- drop any sql profile
-- drop any sql translation profile
-- drop any synonym
-- drop any table
-- drop any trigger
-- drop any type
-- drop any view
-- drop java class
-- drop java resource
-- drop java source
-- drop profile
-- drop public database link
-- drop public synonym
-- drop rollback segment
-- drop sql translation profile
-- drop tablespace
-- drop user
-- em express connect
-- enqueue any queue
-- execute any assembly
-- execute any class
-- execute any evaluation context
-- execute any indextype
-- execute any library
-- execute any operator
-- execute any procedure
-- execute any program
-- execute any rule
-- execute any rule set
-- execute any type
-- execute assembly
-- execute library
-- execute procedure
-- exempt access policy
-- exempt ddl redaction policy
-- exempt dml redaction policy
-- exempt identity policy
-- exempt redaction policy
-- export full database
-- flashback any table
-- flashback archive administer
-- force any transaction
-- force transaction
-- global query rewrite
-- grant any object privilege
-- grant any privilege
-- grant any role
-- grant directory
-- grant edition
-- grant mining model
-- grant procedure
-- grant sequence
-- grant sql translation profile
-- grant table
-- grant type
-- grant user
-- import full database
-- index
-- inherit any privileges
-- inherit privileges
-- insert any cube dimension
-- insert any measure folder
-- insert any table
-- insert table
-- keep date time
-- keep sysguid
-- lock any table
-- lock table
-- logmining
-- manage any file group
-- manage any queue
-- manage file group
-- manage scheduler
-- manage tablespace
-- materialized view
-- merge any view
-- mining model
-- network
-- not exists
-- on commit refresh
-- outline
-- pluggable database
-- procedure
-- profile
-- public database link
-- public synonym
-- purge dba_recyclebin
-- query rewrite
-- read any file group
-- read any table
-- redefine any table
-- restricted session
-- resumable
-- role
-- rollback segment
-- select any cube
-- select any cube build process
-- select any cube dimension
-- select any dictionary
-- select any measure folder
-- select any mining model
-- select any sequence
-- select any table
-- select any transaction
-- select mining model
-- select sequence
-- select table
-- sequence
-- set container
-- sql translation profile
-- synonym
-- sysbackup
-- sysdba
-- sysdg
-- syskm
-- sysoper
-- system audit
-- system grant
-- table
-- tablespace
-- translate any sql
-- translate sql
-- trigger
-- type
-- under any table
-- under any type
-- under any view
-- unlimited tablespace
-- update any cube
-- update any cube build process
-- update any cube dimension
-- update any table
-- update table
-- use any sql translation profile
-- use edition
-- use sql translation profile
-- user
-- view
select
owner,
table_name,
column_name,
sync_capture_version,
sync_capture_reason,
apply_version,
apply_reason
from
dba_streams_columns
order by
owner,
table_name,
column_name;
select
owner,
summary_name,
--position_in_select,
container_column,
agg_function,
distinctflag,
measure
from
dba_summary_aggregates
order by
owner,
summary_name,
position_in_select;
--
-- Find the name of a table given two of its attribute/column names.
--
create table tq84_foo (
col_abc number,
col_cde number,
col_efg number,
col_hij number
);
create table tq84_bar (
col_abc number,
col_hij number,
col_klm date
);
create table tq84_baz (
col_abc number,
col_hij number,
col_nop date
);
select
a.owner,
a.table_name
--a.column_name,
--b.column_name
from
all_tab_columns a join
all_tab_columns b on a.owner = b.owner and
a.table_name = b.table_name
where
a.column_name = 'COL_ABC' and
b.column_name = 'COL_KLM';
drop table tq84_baz purge;
drop table tq84_bar purge;
drop table tq84_foo purge;
select
table_owner,
table_name,
column_name,
column_list,
column_usage,
trigger_owner,
trigger_name
from
dba_trigger_cols
order by
table_owner,
table_name,
column_name;
Installed - data-dictionary - type - attrs - example-01.sql
create type tq84_obj as object (
foo varchar2(10),
bar number,
baz date,
member procedure proc
);
/
column attr_name format a10
column attr_type_name format a10
select
attr_name,
attr_type_mod,
attr_type_name,
length
from
user_type_attrs
where
type_name = 'TQ84_OBJ'
order by
attr_no;
--
-- ATTR_NAME ATTR_TY ATTR_TYPE_ LENGTH
-- ---------- ------- ---------- ----------
-- FOO VARCHAR2 10
-- BAR NUMBER
-- BAZ DATE
drop type tq84_obj;
Installed - data-dictionary - type - methods - example-01.sql
create type tq84_obj as object (
dummy date,
member procedure proc_1,
static procedure proc_2,
member function func_1 return number,
final member function func_2 return varchar2
);
/
create type body tq84_obj as
member procedure proc_1 is begin null; end proc_1;
static procedure proc_2 is begin null; end proc_2;
member function func_1 return number is begin return null; end func_1;
final member function func_2 return varchar2 is begin return null; end func_2;
end;
/
show errors;
column method_name format a10
select
method_name,
method_type,
parameters,
final,
instantiable
from
user_type_methods
where
type_name = 'TQ84_OBJ'
order by
method_no;
--
-- METHOD_NAM METHOD PARAMETERS FIN INS
-- ---------- ------ ---------- --- ---
-- PROC_1 PUBLIC 1 NO YES
-- PROC_2 PUBLIC 0 NO YES
-- FUNC_1 PUBLIC 1 NO YES
-- FUNC_2 PUBLIC 1 YES YES
drop type tq84_obj;
create type tq84_obj as object (
attr_1 varchar2(10),
attr_2 number,
attr_3 date,
member procedure member_proc_1,
member procedure member_proc_2,
static procedure static_proc_1,
static procedure static_proc_2
) not final;
/
create type body tq84_obj as
member procedure member_proc_1 is begin null; end member_proc_1;
member procedure member_proc_2 is begin null; end member_proc_2;
static procedure static_proc_1 is begin null; end static_proc_1;
static procedure static_proc_2 is begin null; end static_proc_2;
end;
/
show errors
create type tq84_obj_under_obj under tq84_obj (
attr_4 varchar2(10),
overriding member procedure member_proc_2
);
/
show errors;
create type body tq84_obj_under_obj as
overriding member procedcure member_proc_2 is begin null; end member_proc_2;
end;
/
column type_name format a20
column supertype_name format a20
select
type_name,
attributes,
methods,
final,
supertype_name,
incomplete
from
user_types
where
type_name like 'TQ84_OBJ%';
--
-- TYPE_NAME ATTRIBUTES METHODS FIN SUPERTYPE_NAME INC
-- -------------------- ---------- ---------- --- -------------------- ---
-- TQ84_OBJ 3 4 NO NO
-- TQ84_OBJ_UNDER_OBJ 4 5 YES TQ84_OBJ NO
drop type tq84_obj_under_obj;
drop type tq84_obj;
prompt
prompt Initially, AUD$ and FGA_LOG$ both are in the
prompt system tablespace:
prompt
select
table_name,
tablespace_name
from
dba_tables
where
table_name in ('AUD$', 'FGA_LOG$');
prompt
prompt Create dedicated tablespace for fga_log$
prompt
create tablespace
FGA_LOG_TS
datafile 'C:\ORACLE\DBMANUAL_FILES\FGA_LOG.DBF'
size 1M
extent management local autoallocate
segment space management auto
;
prompt
prompt Move audit trail FGA_LOG$ to new tablespace
prompt
connect sys as sysdba
begin
dbms_audit_mgmt.set_audit_trail_location(
audit_trail_type => dbms_audit_mgmt.audit_trail_fga_std,
audit_trail_location_value => 'FGA_LOG_TS'
);
end;
/
--
-- Archives a portion of fga_log$ into fga_log_archive
-- and then purges the archived portion from fga_log$.
--
-- The idea is to call this script repeatedly.
--
-- Init needs to have been called once.
--
insert into rene.fga_log_archive
select
sessionid,
--dbuid,
osuid,
oshst,
clientid,
--extid,
obj$schema,
obj$name,
policyname,
--scn,
sqltext,
--lsqltext,
--sqlbind,
--comment$text,
--plhol,
stmt_type,
ntimestamp#,
--proxy$sid,
--user$guid,
--instance#,
--process#,
--xid,
--auditid,
statement,
--entryid,
--dbid,
--lsqlbind,
obj$edition
from
sys.fga_log$;
begin
sys.dbms_audit_mgmt.set_last_archive_timestamp(
audit_trail_type => sys.dbms_audit_mgmt.audit_trail_fga_std,
last_archive_time => systimestamp
);
sys.dbms_audit_mgmt.clean_audit_trail(
audit_trail_type => sys.dbms_audit_mgmt.audit_trail_fga_std,
use_last_arch_timestamp => true
);
end;
/
--
-- With bug 9164488, it is possible to use clean_audit_trail with
-- the following workaround. No idea if it is endorsed by Oracle.
--
-- See http://dba.stackexchange.com/questions/33250/archiving-fga-log-sys-dbms-audit-mgmt-clean-audit-trail-doesnt-delete-anythin
--
begin
sys.dbms_audit_mgmt.create_purge_job (
audit_trail_type => sys.dbms_audit_mgmt.audit_trail_fga_std,
audit_trail_purge_interval => 999,
audit_trail_purge_name =>'Purge_Test',
use_last_arch_timestamp => true
);
end;
/
declare
v varchar2(100);
begin
for c in (
select 'type_operations' n from dual union all
select 'type_rejected_records' n from dual union all
select 'type_dimension_compile' n from dual union all
select 'type_build' n from dual
) loop
execute immediate 'begin :v := dbms_cube_log.default_name(dbms_cube_log.' || c.n || '); end;' using out v;
dbms_output.put_line(rpad(c.n || ': ', 26) || v);
end loop;
end;
/
-- type_operations: CUBE_OPERATIONS_LOG
-- type_rejected_records: CUBE_REJECTED_RECORDS
-- type_dimension_compile: CUBE_DIMENSION_COMPILE
-- type_build: CUBE_BUILD_LOG
prompt
prompt The "blue" session
prompt ==================
prompt
variable lockhandle varchar2(100)
variable x_mode number
exec :x_mode := dbms_lock.x_mode
exec dbms_lock.allocate_unique('tq84-lock', :lockhandle)
exec dbms_output.put_line ('lockhandle ' || :lockhandle || ' allocated');
select case dbms_lock.request(:lockhandle, :x_mode)
when 0 then 'Success'
when 1 then 'Timeout'
when 2 then 'Deadlock'
when 3 then 'Parameter error'
when 4 then 'Already own lock'
when 5 then 'Illegal lock handle' end from dual;
prompt Go now to the green session and press enter
prompt then press enter here to commit the blue session
accept x prompt " "
commit;
prompt commit issued.
prompt The green session should still be blocked.
prompt Press enter here to terminate the blue
prompt session. This should unblock the green
prompt session.
accept x prompt " "
exit;
prompt
prompt The "green" session
prompt ===================
prompt
prompt the Blue session has allocated a lock
prompt press enter to try to allocate the same lock
accept x prompt "in the green session as well."
prompt
variable lockhandle varchar2(100)
variable x_mode number
exec :x_mode := dbms_lock.x_mode
exec dbms_lock.allocate_unique('tq84-lock', :lockhandle)
exec dbms_output.put_line ('lockhandle ' || :lockhandle || ' allocated');
select case dbms_lock.request(:lockhandle, :x_mode)
when 0 then 'Success'
when 1 then 'Timeout'
when 2 then 'Deadlock'
when 3 then 'Parameter error'
when 4 then 'Already own lock'
when 5 then 'Illegal lock handle' end from dual;
exit;
declare
lock_handle_stop varchar2(100);
lock_handle_running varchar2(100);
success number;
dummy number;
begin
-- We indicate that we're running
dbms_lock.allocate_unique('running', lock_handle_running);
success := dbms_lock.request(lock_handle_running, dbms_lock.s_mode, 0);
dbms_lock.allocate_unique('stop-iteration', lock_handle_stop);
loop
-- We try to allocate a shared lock on lock_handle_stop.
--
--
-- If another session already holds the lock exclusively,
-- request will return 1 (that is: timeout).
--
-- We wait 0 seconds, so that we immediatly can
-- exit the loop.
success := dbms_lock.request(lock_handle_stop, dbms_lock.s_mode, 0.1);
-- We also release the lock immediatly, so that we give
-- another session the chance to lock it exclusively:
dummy := dbms_lock.release(lock_handle_stop);
if success = 1 then -- timeout has occured
exit;
end if;
-- Wait for 5 to 10 seconds
--
-- This would be the "critical part".
dbms_lock.sleep(dbms_random.value(5,10));
end loop;
-- We're not really running anymore, so
-- we release the according lock, so that
-- the "green session" can enslock on this ure we're
-- not running anymore by successfully
-- requesting an exclusive lock
dummy := dbms_lock.release(lock_handle_running);
end;
/
exit
prompt
prompt press enter to stop the blue sessions
accept x prompt " "
declare
lock_handle_stop varchar2(100);
lock_handle_running varchar2(100);
success number;
dummy number;
begin
dbms_lock.allocate_unique('running' , lock_handle_running);
dbms_lock.allocate_unique('stop-iteration', lock_handle_stop );
-- We try to request an exclusive lock.
-- As soon as we got it, we know that the other jobs are not
-- in the "critical part"
--
-- We try 60 seconds only
success := dbms_lock.request(lock_handle_stop, dbms_lock.x_mode, 60);
if success = 1 then
dbms_output.put_line('Timeout, could not stop other jobs');
else
success := dbms_lock.request(lock_handle_stop, dbms_lock.x_mode, 60);
-- Now that we have exclusively gotten the running lock (which means that
-- the "critical part" can only be left, but not entered anymore, we
-- also want the running lock exclusively which we get as soon as all
--"blue" jobs have indicated they're leaving the processing.
success := dbms_lock.request(lock_handle_running, dbms_lock.x_mode, 60);
dbms_output.put_line('Other jobs should now be terminated, success: ' || success);
end if;
dummy := dbms_lock.release(lock_handle_stop);
end;
/
exit
@set connection_string=rene/rene
@rem --------------------------------
@rem start four sessions
@start session_blue.bat
@start session_blue.bat
@start session_blue.bat
@start session_blue.bat
@rem --------------------------------
@rem start another session to stop the
@rem executions of the other four
@rem sessions:
@start session_green.bat
create table tq84_t (
id number,
col_1 varchar2(20),
col_2 date,
--
constraint tq84_t_cpk primary key (id)
);
create unique index tq84_t_ix1 on tq84_t(col_1);
create index tq84_t_ix2 on tq84_t(col_2);
create table tq84_def (id number primary key, def clob);
create sequence tq84_seq;
declare
def varchar2(32000);
begin
def := dbms_metadata.get_ddl('TABLE', 'TQ84_T');
insert into tq84_def values (tq84_seq.nextval, def);
for ix in (select index_name from user_indexes where table_name = 'TQ84_T') loop
def := dbms_metadata.get_ddl('INDEX', ix.index_name);
insert into tq84_def values (tq84_seq.nextval, def);
end loop;
end;
/
select def from tq84_def order by id;
drop sequence tq84_seq;
drop table tq84_def purge;
drop table tq84_t purge;
select
owner,
model_name,
mining_function,
algorithm,
creation_date,
build_duration,
model_size,
comments
from
dba_mining_models
order by
owner,
model_name;
declare
v varchar2(100);
begin
dbms_output.new_line;
for c in (
select 'dbms_stats.add_global_prefs' n from dual union all
select 'dbms_stats.auto_cascade' n from dual union all
select 'dbms_stats.auto_degree' n from dual union all
select 'dbms_stats.auto_invalidate' n from dual union all
select 'dbms_stats.auto_sample_size' n from dual union all
select 'dbms_stats.purge_all' n from dual union all
select 'dbms_stats.reclaim_synopsis' n from dual
) loop
begin
execute immediate q'!
declare
function tc (b boolean ) return varchar2 is begin if b is null then return 'null'; elsif b then return 'true'; else return 'false'; end if; end;
function tc (c varchar2) return varchar2 is begin return c; end;
begin :1 := tc(!' || c.n || '); end;' using out v;
dbms_output.put_line(rpad(c.n, 27) || ': ' || v);
exception when others then
dbms_output.put_line(c.n || ': ' || sqlerrm);
end;
end loop;
dbms_output.new_line;
end;
/
drop table tq84_tab_stat purge;
create table tq84_tab_stat (
pk number primary key,
nm number,
vc varchar2(20),
dt date
);
declare
rec tq84_tab_stat%rowtype;
begin
for i in 0 .. 999 loop
rec.pk := i + 100000;
rec.nm := case
when i < 300 then 5
when i < 500 then 7
when i < 600 then 3.141
when i < 700 then null
else i/3 end;
rec.vc := case
when i < 400 then 'foo bar baz'
when i < 700 then 'ab cdefgh ijklmno'
when i < 800 then 'zgraggen'
when i < 900 then dbms_random.string('x', 10)
else null end;
rec.dt := case
when i < 200 then date '2010-08-13'
when i < 300 then to_date ('2015-05-20 13:56:07', 'yyyy-mm-dd hh24:mi:ss')
when i < 800 then date '2016-01-01' + 1127/500 * i
else null end;
insert into tq84_tab_stat values rec;
end loop;
end;
/
commit;
exec dbms_stats.gather_table_stats(user, 'tq84_tab_stat', method_opt => 'for all columns size 10');
column column_name format a4
column data_type format a20
select
h.column_name,
h.endpoint_number,
--endpoint_number - lag(endpoint_number) over (order by ) x,
--substrb(h.endpoint_actual_value, 1, 50),
case c.data_type
when 'NUMBER' then to_char(h.endpoint_value)
when 'DATE' then to_char(to_date(to_char(h.endpoint_value, 'FM99999999') || '.' || to_char(86400 * mod(h.endpoint_value, 1), 'FM99999'), 'J.sssss'))
when 'VARCHAR2' then chr(to_number(substr(to_char(h.endpoint_value, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'), 2, 2), 'XX')) ||
chr(to_number(substr(to_char(h.endpoint_value, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'), 4, 2), 'XX')) ||
chr(to_number(substr(to_char(h.endpoint_value, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'), 6, 2), 'XX')) ||
chr(to_number(substr(to_char(h.endpoint_value, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'), 8, 2), 'XX')) ||
chr(to_number(substr(to_char(h.endpoint_value, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'),10, 2), 'XX')) ||
chr(to_number(substr(to_char(h.endpoint_value, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'),12, 2), 'XX'))
end
from
user_tab_histograms h join
user_tab_columns c on h.table_name = c.table_name and
h.column_name = c.column_name
where
h.table_name = 'TQ84_TAB_STAT'
order by
c.column_id,
h.endpoint_number;
select
column_name,
num_distinct,
--low_value,
--high_value,
density,
num_nulls,
num_buckets,
sample_size,
global_stats,
user_stats,
histogram
from
user_tab_col_statistics
where
table_name = 'TQ84_TAB_STAT';
select
p.name,
substr(dbms_stats.get_prefs(upper(p.name)), 1, 30) val
from (
select 'autostats_target' name from dual union all
select 'cascade' name from dual union all
select 'concurrent' name from dual union all
select 'degree' name from dual union all
select 'estimate_percent' name from dual union all
select 'method_opt' name from dual union all
select 'no_invalidate' name from dual union all
select 'granularity' name from dual union all
select 'publish' name from dual union all
select 'incremental' name from dual union all
select 'incremental_staleness' name from dual union all
select 'incremental_level' name from dual union all
select 'stale_percent' name from dual union all
select 'global_temp_table_stats' name from dual union all
--select 'table_cached_blockes' name from dual union all
select 'options' name from dual
) p;
--
-- Most of the procedures in dbms_stats commit the current transaction,
-- perform the operation, and then commit again.
--
drop table tq84_tab_stat_trx purge;
create table tq84_tab_stat_trx (
col number
);
insert into tq84_tab_stat_trx values (1);
commit;
insert into tq84_tab_stat_trx values (2);
exec dbms_stats.gather_table_stats(user, 'tq84_tab_stat_trx', method_opt => 'for all columns size 10');
select
num_distinct
from
user_tab_col_statistics
where
table_name = 'TQ84_TAB_STAT_TRX' and
column_name = 'COL';
rollback;
select * from tq84_tab_stat_trx;
select * from tq84_xa;
declare
ret_txt varchar2(100);
begin
-- Note: tmresume rather than tmnoflags
ret_txt := tq84_xa_result_to_string( sys.dbms_xa.xa_start(dbms_xa_xid(42), dbms_xa.tmresume) );
if ret_txt != 'OK' then
dbms_output.put_line('Error opening transaction branch: ' || ret_txt);
return;
end if;
insert into tq84_xa values ('This is session two');
-- Note tmsuccess rather than tmsuspend
ret_txt := tq84_xa_result_to_string( sys.dbms_xa.xa_end(dbms_xa_xid(42), dbms_xa.tmsuccess) );
if ret_txt != 'OK' then
dbms_output.put_line('Error: ' || ret_txt);
return;
end if;
end;
/
select * from tq84_xa;
@drop_if_exists tq84_xa
create table tq84_xa (
txt varchar2(40)
);
@drop_if_exists tq84_xa_result_to_string
create function tq84_xa_result_to_string(res number) return varchar2 as
begin
return
case res
when sys.dbms_xa.xa_ok then 'OK'
when sys.dbms_xa.xa_rbbase then 'XA_RBBASE: Inclusive lower bound of the rollback codes'
when sys.dbms_xa.xa_rbrollback then 'XA_RBROLLBACK: Rollback was caused by an unspecified reason'
when sys.dbms_xa.xa_rbcommfail then 'XA_RBCOMMFAIL: Rollback was caused by a communication failure'
when sys.dbms_xa.xa_rbdeadlock then 'XA_RBDEADLOCK: Deadlock was detected'
when sys.dbms_xa.xa_rbintegrity then 'XA_RBINTEGRITY: Condition that violates the integrity of the resources was detected'
when sys.dbms_xa.xa_rbother then 'XA_RBOTHER: Resource manager rolled back the transaction for an unlisted reason'
when sys.dbms_xa.xa_rbproto then 'XA_RBPROTO: Protocol error occurred in the resource manager'
when sys.dbms_xa.xa_rbtimeout then 'XA_RBTIMEOUT: Transaction branch took long'
when sys.dbms_xa.xa_rbtransient then 'XA_RBTRANSIENT: May retry the transaction branch'
when sys.dbms_xa.xa_rbend then 'XA_RBEND: Inclusive upper bound of the rollback codes'
when sys.dbms_xa.xa_nomigrate then 'XA_NOMIGRATE: Transaction branch may have been heuristically completed'
when sys.dbms_xa.xa_heurhaz then 'XA_HEURHAZ: Transaction branch may have been heuristically completed'
when sys.dbms_xa.xa_heurcom then 'XA_HEURCOM: Transaction branch has been heuristically committed'
when sys.dbms_xa.xa_heurrb then 'XA_HEURRB: Transaction branch has been heuristically rolled back'
when sys.dbms_xa.xa_heurmix then 'XA_HEURMIX: Some of the transaction branches have been heuristically committed, others rolled back'
when sys.dbms_xa.xa_retry then 'XA_RETRY: Routine returned with no effect and may be re-issued'
when sys.dbms_xa.xa_rdonly then 'XA_RDONLY: Transaction was read-only and has been committed'
when sys.dbms_xa.xa_ok then 'XA_OK: Normal execution'
when sys.dbms_xa.xaer_async then 'XAER_ASYNC: Asynchronous operation already outstanding'
when sys.dbms_xa.xaer_rmerr then 'XAER_RMERR: Resource manager error occurred in the transaction branch'
when sys.dbms_xa.xaer_nota then 'XAER_NOTA: XID is not valid'
when sys.dbms_xa.xaer_inval then 'XAER_INVAL: Invalid arguments were given'
when sys.dbms_xa.xaer_proto then 'XAER_PROTO: Routine invoked in an improper context'
when sys.dbms_xa.xaer_rmfail then 'XAER_RMFAIL: Resource manager unavailable'
when sys.dbms_xa.xaer_dupid then 'XAER_DUPID: XID already exists'
when sys.dbms_xa.xaer_outside then 'XAER_OUTSIDE: Resource manager doing work outside global transaction'
else '?'
end;
end tq84_xa_result_to_string;
/
create or replace package tq84_base_functionality
---------------------------
ACCESSIBLE BY (tq84_pkg_ok)
---------------------------
is
procedure p;
end tq84_base_functionality;
/
create or replace package body tq84_base_functionality as
procedure p is begin
dbms_output.put_line('tq84_base_functionality.p was called');
end p;
end tq84_base_functionality;
/
create or replace package tq84_pkg_ok as
procedure p;
end tq84_pkg_ok;
/
create or replace package tq84_pkg_not_ok as
procedure p;
end tq84_pkg_not_ok;
/
create or replace package body tq84_pkg_ok as
procedure p is begin
tq84_base_functionality.p;
end p;
end tq84_pkg_ok;
/
create or replace package body tq84_pkg_not_ok as
procedure p is begin
null;
-- tq84_base_functionality.p;
-- PLS-00904: insufficient privilege to access object TQ84_BASE_FUNCTIONALITY
end p;
end tq84_pkg_not_ok;
/
drop package tq84_base_functionality;
drop package tq84_pkg_ok;
drop package tq84_pkg_not_ok;
-- where is an error caught that originates from with
-- a declare block?
declare -- Outer Block {
o varchar2(10) := 'outer';
begin
declare -- Inner Block {
i varchar2(1) := 'inner'; -- Oh oh...
begin
dbms_output.put_line('not reached');
exception when others then
-- The exception is NOT caught here!
dbms_output.put_line('Inner exception: ' || sqlerrm);
end; -- }
exception when others then
dbms_output.put_line('Outer exception: ' || sqlerrm);
end; -- }
/
declare
procedure p (a in varchar2) is
procedure p (a in varchar2) is
begin
dbms_output.put_line('inner: ' || a);
end p;
begin
p('outer: ' || a);
end p;
begin
p('foo');
end;
/
create type tq84_bulk_collect_tab as table of varchar2(100);
/
create table tq84_bulk_collect_table (
col1 number,
col2 varchar2(100)
);
insert into tq84_bulk_collect_table values (1, 'one');
insert into tq84_bulk_collect_table values (2, 'two');
insert into tq84_bulk_collect_table values (3, 'three');
declare
b tq84_bulk_collect_tab;
begin
select col2 bulk collect into b
from tq84_bulk_collect_table
where col1 > 100; -- No records match!
dbms_output.put_line ('b.count: ' || b.count);
exception when no_data_found then
-- Not reached:
dbms_output.put_line ('no_data_found');
end;
/
drop table tq84_bulk_collect_table purge;
drop type tq84_bulk_collect_tab;
-- Tables {
create table tq84_a (
id number primary key,
txt varchar2(10)
);
create table tq84_b (
id number primary key,
id_a references tq84_a,
txt varchar2(10)
);
create table tq84_c (
id number primary key,
id_b references tq84_b,
txt varchar2(10)
);
-- }
-- Inserts {
insert into tq84_a values ( 1, 'one');
insert into tq84_b values ( 11, 1, 'A');
insert into tq84_c values (111, 11, '(');
insert into tq84_c values (112, 11, ')');
insert into tq84_b values ( 12, 1, 'B');
insert into tq84_c values (121, 12, '!');
insert into tq84_c values (122, 12, '?');
insert into tq84_c values (123, 12, '.');
insert into tq84_c values (124, 12, ',');
insert into tq84_b values ( 13, 1, 'C');
insert into tq84_a values ( 2, 'two');
insert into tq84_a values ( 3, 'two');
insert into tq84_b values ( 31, 3, 'Y');
insert into tq84_b values ( 32, 3, 'Z');
-- }
-- Types {
create type tq84_c_o as object (
id number,
txt varchar2(10)
);
/
create type tq84_c_t as table of tq84_c_o;
/
create type tq84_b_o as object (
id number,
txt varchar2(10),
c tq84_c_t
);
/
create type tq84_b_t as table of tq84_b_o;
/
create type tq84_a_o as object (
id number,
txt varchar2(10),
b tq84_b_t
);
/
create type tq84_a_t as table of tq84_a_o;
/
-- }
declare
complete_tree tq84_a_t;
begin
select tq84_a_o (
a.id,
a.txt,
-----
cast ( collect (tq84_b_o ( b.id, b.txt, null ) ) as tq84_b_t )
) bulk collect into complete_tree
from
tq84_a a join
tq84_b b on a.id = b.id_a
group by
a.id,
a.txt;
dbms_output.new_line;
for a in 1 .. complete_tree.count loop
dbms_output.put_line('Id: ' || complete_tree(a).id || ', txt: ' || complete_tree(a).txt);
for b in 1 .. complete_tree(a).b.count loop
dbms_output.put_line(' Id: ' || complete_tree(a).b(b).id || ', txt: ' || complete_tree(a).b(b).txt);
-- ? if complete_tree(a).b(b).c is not null then
-- ? for c in 1 .. complete_tree(a).b(b).c.count loop
-- ?
-- ? dbms_output.put_line(' Id: ' || complete_tree(a).b(b).c(c).id || ', txt: ' || complete_tree(a).b(b).c(c).txt);
-- ?
-- ? end loop;
-- ? dbms_output.new_line;
-- ? end if;
end loop;
dbms_output.new_line;
end loop;
--
-- select tq84_outer (o.i,
-- o.j,
-- cast(collect( tq84_inner(i.n, i.t) order by i.n) as tq84_inner_t)
-- )
-- bulk collect into t
-- from tq84_o o join
-- tq84_i i on o.i = i.i
-- group by o.i, o.j;
--
-- --
--
---- does not work select tq84_outer__ (o.i, -- {
---- does not work o.j,
---- does not work cast(collect( tq84_inner__(i.n, i.t) order by i.n) as tq84_inner_t__)
---- does not work )
---- does not work bulk collect into t
---- does not work from tq84_o o join
---- does not work tq84_i i on o.i = i.i
---- does not work group by o.i, o.j; -- }
--
-- --
--
-- dbms_output.put_line('Cnt: ' || t.count);
--
-- dbms_output.put_line('Cnt (2): ' || t(2).inner_.count);
--
-- dbms_output.put_line(t(3).inner_(2).t);
--
-- ----------------------------------------------------
--
-- for r in (
-- select i, j from table(t)
-- ) loop -- {
--
-- dbms_output.put_line('i: ' || r.i || ', j: ' || r.j);
--
-- end loop; -- }
--
-- ----------------------------------------------------
--
-- dbms_output.new_line;
--
-- ----------------------------------------------------
--
-- for r in (
-- select
-- outer_.i,
-- outer_.j,
-- inner_.n,
-- inner_.t
-- from
-- table(t) outer_,
-- table(outer_.inner_) inner_
-- ) loop -- {
--
-- dbms_output.put_line('i: ' || r.i || ', j: ' || r.j || ', n: ' || r.n || ', t: ' || r.t);
--
-- end loop; -- }
--
-- ----------------------------------------------------
--
end;
/
drop type tq84_a_t force;
drop type tq84_a_o force;
drop type tq84_b_t force;
drop type tq84_b_o force;
drop type tq84_c_t force;
drop type tq84_c_o force;
drop table tq84_c purge;
drop table tq84_b purge;
drop table tq84_a purge;
create type tq84_inner as object (
n number,
t varchar2(10)
);
/
create type tq84_inner_t as table of tq84_inner;
/
create type tq84_outer as object (
i number,
j varchar2(10),
inner_ tq84_inner_t
);
/
create type tq84_outer_t as table of tq84_outer;
/
create table tq84_o (
i number primary key,
j varchar2(10)
);
create table tq84_i (
i references tq84_o,
n number,
t varchar2(10)
);
-- Inserts {
insert into tq84_o values (1, 'one');
insert into tq84_o values (2, 'two');
insert into tq84_o values (3, 'three');
insert into tq84_o values (4, 'four');
insert into tq84_i values (1, 1, 'apple');
insert into tq84_i values (1, 2, 'pear');
insert into tq84_i values (1, 3, 'lemon');
insert into tq84_i values (1, 4, 'grape');
insert into tq84_i values (2, 1, 'car');
insert into tq84_i values (2, 2, 'bike');
insert into tq84_i values (3, 1, 'foo');
insert into tq84_i values (3, 2, 'bar');
insert into tq84_i values (3, 3, 'baz');
-- }
declare
t tq84_outer_t;
-- does not work type tq84_inner__ is record ( -- {
-- does not work n number,
-- does not work t varchar2(10)
-- does not work );
-- does not work
-- does not work type tq84_inner_t__ is table of tq84_inner__;
-- does not work
-- does not work type tq84_outer__ is record (
-- does not work i number,
-- does not work j varchar2(10),
-- does not work inner_ tq84_inner_t
-- does not work );
-- does not work
-- does not work type tq84_outer_t__ is table of tq84_outer__;
-- does not work
-- does not work t__ tq84_outer_t__; -- }
begin
select tq84_outer (o.i,
o.j,
cast(collect( tq84_inner(i.n, i.t) order by i.n) as tq84_inner_t)
)
bulk collect into t
from tq84_o o join
tq84_i i on o.i = i.i
group by o.i, o.j;
--
-- does not work select tq84_outer__ (o.i, -- {
-- does not work o.j,
-- does not work cast(collect( tq84_inner__(i.n, i.t) order by i.n) as tq84_inner_t__)
-- does not work )
-- does not work bulk collect into t
-- does not work from tq84_o o join
-- does not work tq84_i i on o.i = i.i
-- does not work group by o.i, o.j; -- }
--
dbms_output.put_line('Cnt: ' || t.count);
dbms_output.put_line('Cnt (2): ' || t(2).inner_.count);
dbms_output.put_line(t(3).inner_(2).t);
----------------------------------------------------
for r in (
select i, j from table(t)
) loop -- {
dbms_output.put_line('i: ' || r.i || ', j: ' || r.j);
end loop; -- }
----------------------------------------------------
dbms_output.new_line;
----------------------------------------------------
for r in (
select
outer_.i,
outer_.j,
inner_.n,
inner_.t
from
table(t) outer_,
table(outer_.inner_) inner_
) loop -- {
dbms_output.put_line('i: ' || r.i || ', j: ' || r.j || ', n: ' || r.n || ', t: ' || r.t);
end loop; -- }
----------------------------------------------------
end;
/
drop table tq84_i purge;
drop table tq84_o purge;
drop type tq84_outer_t;
drop type tq84_outer;
drop type tq84_inner_t;
drop type tq84_inner force;
create or replace package tq84_case as
procedure d;
end tq84_case;
/
create or replace package body tq84_case as
procedure d as
a number := 4;
b number := 3;
begin
case a when 1 then output.print('a = 1'); -- Line 9
when 2 then output.print('a = 2');
when 3 then output.print('a = 3');
when 4 then case b
when 1 then output.print('b = 1');
when 2 then output.print('b = 2');
end case;
end case;
end d;
end tq84_case;
/
-- Which line is reported as having an error?
exec tq84_case.d
declare
type r is record (
nm number,
vc varchar2(20)
);
type t is table of r index by varchar2(10);
v t;
procedure out_1 (key_ in varchar2) is -- {
begin
dbms_output.put_line(key_ || ': ' || v(key_).nm || ' - ' || v(key_).vc);
exception
when no_data_found then
dbms_output.put_line('No entry found for ' || key_);
when others then
raise;
end out_1; -- }
procedure out_2 (key_ in varchar2) is -- {
begin
if v.exists(key_) then
dbms_output.put_line(key_ || ': ' || v(key_).nm || ' - ' || v(key_).vc);
else
dbms_output.put_line('No entry found for ' || key_);
end if;
end out_2; -- }
begin
v('foo').nm := 42; v('foo').vc := 'forty-two';
v('bar').nm := 11; v('bar').vc := 'eleven';
dbms_output.new_line;
out_1('foo');
out_1('bar');
out_1('baz');
dbms_output.new_line;
out_2('foo');
out_2('bar');
out_2('baz');
dbms_output.new_line;
end;
/
declare
type r is record (
nm number,
vc varchar2(20)
);
type t is table of r index by varchar2(10);
v t;
key_ varchar2(10);
begin
v('foo').nm := 42; v('foo').vc := 'forty-two';
v('bar').nm := 11; v('bar').vc := 'eleven';
v('baz').nm := 20; v('baz').vc := 'twenty';
key_ := v.first;
while key_ is not null loop
dbms_output.put_line(key_ || ': ' || v(key_).nm || ' - ' || v(key_).vc);
key_ := v.next(key_);
end loop;
end;
/
create type tq84_number_tab as table of number;
/
declare
numbers tq84_number_tab := tq84_number_tab(1, 2, 3, 4, 5);
begin
-- count is evaluated once, at the beginning
-- of the loop.
for i in 1 .. numbers.count loop
dbms_output.put_line(numbers(i));
numbers.extend;
numbers(numbers.count) := numbers.count;
exit when i > 100;
end loop;
end;
/
drop type tq84_number_tab;
create type tq84_obj as object (
a number,
b varchar2(10)
);
/
create type tq84_obj_t as table of tq84_obj;
/
create table tq84_table (
id number,
obj_t tq84_obj_t
)
nested table obj_t store as tq84_table_t;
insert into tq84_table values (1, tq84_obj_t(tq84_obj(1, 'one' ), tq84_obj(2, 'two' ) ));
insert into tq84_table values (2, tq84_obj_t(tq84_obj(1, 'eins'), tq84_obj(2, 'zwei'), tq84_obj(3, 'drei')));
select
t.id,
cardinality(t.obj_t)
from
tq84_table t;
drop table tq84_table;
drop type tq84_obj_t;
drop type tq84_obj;
create type tq84_obj as object (
a number,
b varchar2(10)
);
/
create type tq84_obj_t as table of tq84_obj;
/
create table tq84_table (
id number,
obj_t_1 tq84_obj_t,
obj_t_2 tq84_obj_t
)
nested table obj_t_1 store as tq84_table_t_1,
nested table obj_t_2 store as tq84_table_t_2;
insert into tq84_table values (1,
tq84_obj_t(tq84_obj(1, 'one' ), tq84_obj(2, 'two' ) ),
tq84_obj_t(tq84_obj(1, 'eins'), tq84_obj(2, 'zwei'), tq84_obj(3, 'drei'))
);
insert into tq84_table values (1,
tq84_obj_t(tq84_obj(42, 'foo' )),
tq84_obj_t( ))
);
insert into tq84_table values (1,
tq84_obj_t(tq84_obj(98, 'X' )),
tq84_obj_t(tq84_obj(99, 'Y' ))
);
select t.id, u.a, u.b, v.a, v.b from
tq84_table t,
table(t.obj_t_1) u,
table(t.obj_t_2) v;
drop table tq84_table;
drop type tq84_obj_t;
drop type tq84_obj;
create type tq84_obj as object (
a number,
b varchar2(10)
);
/
create type tq84_obj_t as table of tq84_obj;
/
create table tq84_table (
id number,
obj_t tq84_obj_t
)
nested table obj_t store as tq84_table_t;
insert into tq84_table values (1, tq84_obj_t(tq84_obj(1, 'one' ), tq84_obj(2, 'two' ) ));
insert into tq84_table values (2, tq84_obj_t(tq84_obj(1, 'eins'), tq84_obj(2, 'zwei'), tq84_obj(3, 'drei')));
select * from the (select obj_t from tq84_table where rownum = 1);
select
t.id,
u.a,
u.b
from
tq84_table t,
the (select obj_t from tq84_table u where u.id = t.id) u
--the (select obj_t from t) u -- <== Does not return a record!
;
drop table tq84_table;
drop type tq84_obj_t;
drop type tq84_obj;
create type tq84_obj as object (
a number,
b varchar2(10)
);
/
create type tq84_obj_t as table of tq84_obj;
/
create table tq84_table (
id number,
obj_t_1 tq84_obj_t,
obj_t_2 tq84_obj_t
)
nested table obj_t_1 store as tq84_table_t_1,
nested table obj_t_2 store as tq84_table_t_2;
insert into tq84_table values (1,
tq84_obj_t(tq84_obj(1, 'one' ), tq84_obj(2, 'two' ) ),
tq84_obj_t(tq84_obj(1, 'eins'), tq84_obj(2, 'zwei'), tq84_obj(3, 'drei'))
);
insert into tq84_table values (2,
tq84_obj_t(tq84_obj(42, 'foo' )),
tq84_obj_t( ))
);
insert into tq84_table values (3,
tq84_obj_t(tq84_obj(98, 'X' )),
tq84_obj_t(tq84_obj(99, 'Y' ))
);
select t.id, u.a, u.b, v.a, v.b from
tq84_table t,
the(select t.obj_t_1 from tq84_table u where u.id = t.id) u,
the(select t.obj_t_2 from tq84_table v where v.id = t.id) v;
drop table tq84_table;
drop type tq84_obj_t;
drop type tq84_obj;
create table tq84_member_of (
id number primary key,
txt varchar2(10)
);
insert into tq84_member_of values (1, 'one' );
insert into tq84_member_of values (2, 'two' );
insert into tq84_member_of values (3, 'three');
insert into tq84_member_of values (4, 'four' );
create type tq84_number_tab as table of number;
/
select * from tq84_member_of
where id member of tq84_number_tab( 2, 4, 6);
drop type tq84_number_tab;
drop table tq84_member_of;
create table tq84_cursor_attr_test (
a number
);
begin
insert into tq84_cursor_attr_test select rownum from all_objects where rownum <= 10;
dbms_output.put_line('rowcount: ' || sql%rowcount);
insert into tq84_cursor_attr_test select * from tq84_cursor_attr_test;
dbms_output.put_line('rowcount: ' || sql%rowcount);
insert into tq84_cursor_attr_test select * from tq84_cursor_attr_test;
dbms_output.put_line('rowcount: ' || sql%rowcount);
insert into tq84_cursor_attr_test select * from tq84_cursor_attr_test;
dbms_output.put_line('rowcount: ' || sql%rowcount);
delete from tq84_cursor_attr_test where a = 5;
if sql%found then
dbms_output.put_line(sql%rowcount || ' rows where deleted');
else
dbms_output.put_line('no rows were deleted');
end if;
delete from tq84_cursor_attr_test where a = 5;
if sql%notfound then
dbms_output.put_line('no rows were deleted');
else
dbms_output.put_line(sql%rowcount || ' rows where deleted');
end if;
delete from tq84_cursor_attr_test where a=2;
delete from tq84_cursor_attr_test where a=3;
dbms_output.put_line('sql%rowcount before commit: ' || sql%rowcount);
commit;
dbms_output.put_line('sql%rowcount after commit: ' || sql%rowcount);
end;
/
drop table tq84_cursor_attr_test purge;
drop table tq84_cursor;
create table tq84_cursor (
a number,
b varchar2(10)
);
insert into tq84_cursor values (1, 'one' );
insert into tq84_cursor values (2, 'two' );
insert into tq84_cursor values (3, 'three');
insert into tq84_cursor values (4, 'four' );
declare
cursor cur(a_ number) is
select * from tq84_cursor
where a > a_;
begin
for rec in cur(2) loop
dbms_output.put_line('a: ' || rec.a || ', b: ' || rec.b);
end loop;
end;
/
create table tq84_open_close_cursor (
a number,
b varchar2(20)
);
insert into tq84_open_close_cursor values (1, 'one');
insert into tq84_open_close_cursor values (2, 'two');
insert into tq84_open_close_cursor values (3, 'three');
insert into tq84_open_close_cursor values (3, 'one plus two');
declare -- {
procedure open_close_cur(p_sel in number) is -- {
text varchar2(20);
cursor cur(sel in number) is
select b
from tq84_open_close_cursor
where a = sel;
begin
dbms_output.put_line('p_sel: ' || p_sel);
open cur(p_sel);
dbms_output.put_line(' cursor opened');
fetch cur into text;
dbms_output.put_line(' feched');
if cur%found then
dbms_output.put_line(' found, text = ' || text);
end if;
close cur;
dbms_output.put_line(' cursor closed');
dbms_output.new_line;
end open_close_cur; -- }
begin
open_close_cur( 1);
open_close_cur( 3);
open_close_cur(99);
end; -- }
/
drop table tq84_open_close_cursor purge;
create table tq84_rowcount (a number);
insert into tq84_rowcount values ( 42);
insert into tq84_rowcount values ( 12);
insert into tq84_rowcount values (1000);
declare
cursor c is select * from tq84_rowcount;
begin
for r in c loop
dbms_output.put_line(to_char(r.a, '9999') || ' ' || c%rowcount);
end loop;
end;
/
drop table tq84_rowcount purge;
drop table tq84_cursor;
create table tq84_cursor (
a number,
b varchar2(10)
);
insert into tq84_cursor values (1, 'one' );
insert into tq84_cursor values (2, 'two' );
insert into tq84_cursor values (3, 'three');
insert into tq84_cursor values (4, 'four' );
declare
cursor cur(a_ number) is
select * from tq84_cursor
where a > a_;
rec cur%rowtype;
begin
open cur(1);
fetch cur into rec;
while cur%found loop
dbms_output.put_line('a: ' || rec.a || ', b: ' || rec.b);
fetch cur into rec;
end loop;
close cur;
end;
/
create or replace package body tq84_catcher as
procedure go is
begin
tq84_thrower_1.go;
exception
when tq84_thrower_2.exc then
--
-- Note, tq84_thrower_2.exc is caught, altough, technically,
-- tq84_thrower_1.exc is thrown. This is because
-- both exception share the same errcode (-20777)
--
dbms_output.put_line('caught tq84_thrower_2.exc, sqlerrm: ' || sqlerrm);
when others then
dbms_output.put_line('caught other, sqlerrm: ' || sqlerrm);
end go;
end tq84_catcher;
/
create or replace package body tq84_thrower_1 as
procedure go is begin
raise_application_error(-20777, 'Package is tq84_thrower_1');
end go;
end tq84_thrower_1;
/
create or replace package body tq84_thrower_2 as
procedure go is begin
raise_application_error(-20777, 'Package is tq84_thrower_2');
end go;
end tq84_thrower_2;
/
create table tq84_for_all (
col_1 number primary key,
col_2 varchar2(10)
);
create or replace package tq84_for_all_pkg as
procedure run_without;
procedure run_with;
end tq84_for_all_pkg;
/
create or replace package body tq84_for_all_pkg as
procedure run_without is -- {
t0 number;
t1 number;
begin
t0 := dbms_utility.get_time;
for i in 1 .. 100000 loop
insert into tq84_for_all values(i, 'foo ' || i);
end loop;
t1 := dbms_utility.get_time;
dbms_output.put_line('Without: ' || ((t1-t0) / 100) || ' seconds');
end run_without; -- }
procedure run_with is -- {
type vals_t is table of tq84_for_all%rowtype index by pls_integer;
vals vals_t;
t0 number;
t1 number;
begin
t0 := dbms_utility.get_time;
for i in 1 .. 100000 loop
vals(i).col_1 := i + 100000;
vals(i).col_2 := 'foo ' || i;
end loop;
forall i in 1 .. 10000 insert into tq84_for_all values vals(i); -- (vals(i).col_1, vals(i).col_2);
t1 := dbms_utility.get_time;
dbms_output.put_line('With : ' || ((t1-t0) / 100) || ' seconds');
end run_with; -- }
end tq84_for_all_pkg;
/
show errors;
exec tq84_for_all_pkg.run_without
exec tq84_for_all_pkg.run_with
drop table tq84_for_all purge;
drop package tq84_for_all_pkg;
begin
for i in 1 .. 5 loop
dbms_output.put_line('i: ' || i || ' ');
for j in 1 .. 5 loop
dbms_output.put_line(' j: ' || j);
continue when i+j > 7;
dbms_output.put_line('*');
end loop;
end loop;
dbms_output.put_line('x');
end;
/
--
-- An SQL Select statement as a string.
--
-- Looping over its result set.
--
create table tq84_loop_ex (
n number,
v varchar2(10)
);
insert into tq84_loop_ex values (1, 'one' );
insert into tq84_loop_ex values (2, 'two' );
insert into tq84_loop_ex values (3, 'three');
declare
type cur_t is ref cursor;
cur cur_t;
rec tq84_loop_ex%rowtype;
stmt varchar2(100) := 'select n, v from tq84_loop_ex';
begin
open cur for stmt;
loop
fetch cur into rec;
exit when cur%notfound;
dbms_output.put_line(rec.n || ', ' || rec.v);
end loop;
close cur;
end;
/
drop table tq84_loop_ex purge;
create or replace package tq84_pkg as -- {
procedure p;
end tq84_pkg; -- }
/
create or replace package body tq84_pkg as -- {
procedure p is
begin
$if $$tq84_flg $then
dbms_output.put_line('$$tq84_flg is true');
$else
dbms_output.put_line('$$tq84_flg is not true');
$end
end p;
end tq84_pkg; -- }
/
exec tq84_pkg.p
-- $$tq84_flg is not true
alter package tq84_pkg compile plsql_ccflags='tq84_flg:true';
exec tq84_pkg.p
-- $$tq84_flg is true
drop package tq84_pkg;
create table tq84_between (
val varchar2(10) not null,
dt_1 date not null,
dt_2 date not null
);
alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss';
insert into tq84_between values ('one', '18.07.2010 15:30:19', '20.08.2010 16:20:18');
insert into tq84_between values ('two', '20.08.2010 16:20:18', '05.09.2016 07:51:32');
select * from tq84_between where '04.02.2009 08:08:08' between dt_1 and dt_2;
select * from tq84_between where '19.08.2010 22:23:24' between dt_1 and dt_2;
select * from tq84_between where '20.08.2010 16:20:18' between dt_1 and dt_2;
drop table tq84_between purge;
create type tq84_obj as object (
a number,
b varchar2(10)
);
/
create type tq84_obj_t as table of tq84_obj;
/
create table tq84_tab (
id varchar2(10),
val tq84_obj_t
)
nested table val store as tq84_tab_val;
insert into tq84_tab values ('1-3', tq84_obj_t(tq84_obj(1, 'one' ), tq84_obj(2, 'two' ), tq84_obj(3, 'three') ));
insert into tq84_tab values ('2-5', tq84_obj_t(tq84_obj(2, 'two' ), tq84_obj(3, 'three'), tq84_obj(4, 'four' ), tq84_obj(5, 'five' )));
insert into tq84_tab values ('4' , tq84_obj_t(tq84_obj(4, 'four') ));
insert into tq84_tab values ('n/a', tq84_obj_t( ));
break on what skip 1
select
a.id || ' except ' || b.id what,
t.*
from
tq84_tab a,
tq84_tab b,
table(a.val multiset except b.val) t
where
a.id = '1-3' and b.id = '2-5' or
a.id = '2-5' and b.id = '4' or
a.id = '4' and b.id = 'n/a';
--
-- WHAT A B
-- ---------------------------- ---------- ----------
-- 1-3 except 2-5 1 one
--
-- 2-5 except 4 2 two
-- 3 three
-- 5 five
--
-- 4 except n/a 4 four
drop table tq84_tab;
drop type tq84_obj_t;
drop type tq84_obj;
create type tq84_obj as object (
a number,
b varchar2(10)
);
/
create type tq84_obj_t as table of tq84_obj;
/
create table tq84_tab (
id varchar2(10),
val tq84_obj_t
)
nested table val store as tq84_tab_val;
insert into tq84_tab values ('1-3', tq84_obj_t(tq84_obj(1, 'one' ), tq84_obj(2, 'two' ), tq84_obj(3, 'three') ));
insert into tq84_tab values ('2-5', tq84_obj_t(tq84_obj(2, 'two' ), tq84_obj(3, 'three'), tq84_obj(4, 'four' ), tq84_obj(5, 'five' )));
insert into tq84_tab values ('4' , tq84_obj_t(tq84_obj(4, 'four') ));
insert into tq84_tab values ('n/a', tq84_obj_t( ));
break on what skip 1
select
a.id || ' /\ ' || b.id what,
t.*
from
tq84_tab a,
tq84_tab b,
table(a.val multiset intersect b.val) t
where
a.id = '1-3' and b.id = '2-5' or
a.id = '2-5' and b.id = '4' or
a.id = '4' and b.id = 'n/a';
--
-- WHAT A B
-- ------------------------ ---------- ----------
-- 1-3 /\ 2-5 2 two
-- 3 three
--
-- 2-5 /\ 4 4 four
drop table tq84_tab;
drop type tq84_obj_t;
drop type tq84_obj;
create type tq84_obj as object (
a number,
b varchar2(10)
);
/
create type tq84_obj_t as table of tq84_obj;
/
create table tq84_tab (
id varchar2(10),
val tq84_obj_t
)
nested table val store as tq84_tab_val;
insert into tq84_tab values ('1-3', tq84_obj_t(tq84_obj(1, 'one' ), tq84_obj(2, 'two' ), tq84_obj(3, 'three') ));
insert into tq84_tab values ('2-5', tq84_obj_t(tq84_obj(2, 'two' ), tq84_obj(3, 'three'), tq84_obj(4, 'four' ), tq84_obj(5, 'five' )));
insert into tq84_tab values ('4' , tq84_obj_t(tq84_obj(4, 'four') ));
insert into tq84_tab values ('n/a', tq84_obj_t( ));
break on what skip 1
select
a.id || ' \/ ' || b.id what,
t.*
from
tq84_tab a,
tq84_tab b,
table(a.val multiset union b.val) t
where
a.id = '1-3' and b.id = '2-5' or
a.id = '2-5' and b.id = '4' or
a.id = '4' and b.id = 'n/a';
--
-- WHAT A B
-- ------------------------ ---------- ----------
-- 1-3 \/ 2-5 1 one
-- 2 two
-- 3 three
-- 2 two
-- 3 three
-- 4 four
-- 5 five
--
-- 2-5 \/ 4 2 two
-- 3 three
-- 4 four
-- 5 five
-- 4 four
--
-- 4 \/ n/a 4 four
drop table tq84_tab;
drop type tq84_obj_t;
drop type tq84_obj;
declare
result varchar2(100);
str varchar2( 10);
n number;
begin
str :='foo';
n := 4; -- repeat 4 times
result := rpad(str, n*length(str), str);
dbms_output.put_line('result: ' || result);
end;
/
create table tq84_with_function (
id number,
txt varchar2(10)
);
insert into tq84_with_function values (1, 'one');
insert into tq84_with_function values (2, 'two');
with function dup (txt in varchar2) return varchar2 as
begin
return txt || '-' || txt;
end dup;
select
id,
substr(dup(txt), 1, 40) dup
from
tq84_with_function
/
drop table tq84_with_function;
create table tq84_table (
id number,
txt varchar2(10)
);
begin
for r in 1 .. 10000 loop
insert into tq84_table values (r, dbms_random.string('a', 10));
end loop;
end;
/
-- select 10 (= 0.1 percent of 10000) records:
select * from tq84_table
order by txt
fetch first 0.1 percent rows only;
drop table tq84_table purge;
--
-- http://stackoverflow.com/a/21315483/180275
--
create table tq84_sum_data_by_week (
chrg_dt date,
wrk_hr number
);
insert into tq84_sum_data_by_week values (date '2014-01-01', 4);
insert into tq84_sum_data_by_week values (date '2014-01-02', 8);
insert into tq84_sum_data_by_week values (date '2014-01-15', 7);
with fridays as (
select
date '2014-01-03' + (level-1) * 7 date_
from dual
connect by level <= 3
)
select
fridays.date_,
sum(sum(weeks.wrk_hr)) over (order by fridays.date_) total_hrs
from
fridays left outer join
tq84_sum_data_by_week weeks
on fridays.date_ = next_day(weeks.chrg_dt, 'fridays')
group by
fridays.date_;
drop table tq84_sum_data_by_week purge;
--
-- tq84_x contains values (for examples: loans) that are valid
-- within a specific time frame (from_ until to_).
create table tq84_x(
from_ date,
to_ date,
val_ number
);
insert into tq84_x values (date '2015-11-06', date '2015-12-03', 10);
insert into tq84_x values (date '2015-11-18', date '2015-11-27', 40);
insert into tq84_x values (date '2015-11-20', date '2015-12-09', 100);
--
-- The task is now to find the cumulative value when it changes:
with x as (
select from_ dt, val_ from tq84_x union all
select to_ dt, -val_ from tq84_x
)
select
dt,
sum(val_) over (order by dt) cumulative_val_at_dt
from
x;
-- DT CUMULATIVE_VAL_AT_DT
-- ------------------- --------------------
-- 06.11.2015 00:00:00 10
-- 18.11.2015 00:00:00 50
-- 20.11.2015 00:00:00 150
-- 27.11.2015 00:00:00 110
-- 03.12.2015 00:00:00 100
-- 09.12.2015 00:00:00 0
drop table tq84_x purge;
alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss';
create table tq84_calendar (
dt_begin date not null,
dt_end date not null,
what varchar2(20),
--
check (dt_begin < dt_end)
);
insert into tq84_calendar
with entries as (
select '08:00' start_, '08:30' end_, 'Meeting 1' what from dual union all
select '09:00' start_, '10:00' end_, 'Meeting 2' what from dual union all
select '10:30' start_, '11:00' end_, 'Meeting 3' what from dual union all
select '11:00' start_, '11:30' end_, 'Meeting 4' what from dual union all
select '12:00' start_, '13:30' end_, 'Lunch' what from dual union all
select '15:00' start_, '16:00' end_, 'Meeting 5' what from dual union all
select '16:30' start_, '17:00' end_, 'Meeting 6' what from dual
)
select
'2010-10-10 ' || start_ || ':00',
'2010-10-10 ' || end_ || ':00',
what
from
entries;
select
to_char(free_begin, 'hh24:mi') free_begin,
to_char(free_end , 'hh24:mi') free_end
from (
select
max (dt_end ) over (order by dt_begin) free_begin,
lead(dt_begin) over (order by dt_begin) free_end
from
tq84_calendar
)
where free_begin < free_end;
--
-- FREE_ FREE_
-- ----- -----
-- 08:30 09:00
-- 10:00 10:30
-- 11:30 12:00
-- 13:30 15:00
-- 16:00 16:30
drop table tq84_calendar;
--
-- Demonstration: how to find «duplicate newest entries».
--
create table tq84_t (
id varchar2(10),
tm date,
val number
);
-- Find each record where an id's newest tm occurs
-- more than once.
insert into tq84_t values ('foo', date '2000-05-09', 10);
insert into tq84_t values ('foo', date '2004-11-28', 12);
insert into tq84_t values ('foo', date '2012-07-15', 14);
insert into tq84_t values ('bar', date '2001-05-09', 9);
insert into tq84_t values ('bar', date '2003-02-04', 17);
insert into tq84_t values ('bar', date '2011-06-12', 16) /* We want this and the next record, because */;
insert into tq84_t values ('bar', date '2011-06-12', 19) /* 2011-06-12 occurs twice and is most recent for 'bar' */ ;
insert into tq84_t values ('baz', date '2002-08-23', 21);
insert into tq84_t values ('baz', date '2005-05-19', 25) /* We don't want this record. 2005-05-19 occurs twice for 'baz' */;
insert into tq84_t values ('baz', date '2005-05-19', 23) /* but 2013-01-30 is newer */;
insert into tq84_t values ('baz', date '2013-01-30', 13);
select * from (
select
id,
tm,
count(*) over (partition by id, tm ) cnt,
dense_rank() over (partition by id order by tm desc) dr,
val
from
tq84_t
)
where
cnt > 1 and
dr = 1;
drop table tq84_t purge;
create table tq84_analytical_group_by (
item varchar2(10),
val number
);
insert into tq84_analytical_group_by values ('abc', 10);
insert into tq84_analytical_group_by values ('abc', 15);
insert into tq84_analytical_group_by values ('abc', 20);
insert into tq84_analytical_group_by values ('DEF', 7);
insert into tq84_analytical_group_by values ('DEF', 12);
insert into tq84_analytical_group_by values ('123', 7);
insert into tq84_analytical_group_by values ('123', 8);
insert into tq84_analytical_group_by values ('123', 14);
select
item,
sum(val),
sum(sum(val)) over () val_total,
max(sum(val)) over () val_max
from
tq84_analytical_group_by
group by
item;
drop table tq84_analytical_group_by;
create table tq84_percent (
num number
);
insert into tq84_percent values ( 1);
insert into tq84_percent values ( 4);
insert into tq84_percent values ( 2);
insert into tq84_percent values ( 9);
insert into tq84_percent values ( 9);
insert into tq84_percent values (10);
select
num,
percent_rank() over (order by num) pct_rnk,
( rank() over (order by num) - 1) / (count(*) over () -1) pct_rnk_calc
from
tq84_percent
order by
num;
-- NUM PCT_RNK PCT_RNK_CALC
-- ---------- ---------- ------------
-- 1 0 0
-- 2 .2 .2
-- 4 .4 .4
-- 9 .6 .6
-- 9 .6 .6
-- 10 1 1
select
percent_rank( 0 ) within group (order by num) pct_rnk__0,
percent_rank( 0.9) within group (order by num) pct_rnk__0_9,
percent_rank( 1.0) within group (order by num) pct_rnk__1_0,
percent_rank( 1.1) within group (order by num) pct_rnk__1_1,
percent_rank( 2 ) within group (order by num) pct_rnk__2,
percent_rank( 3 ) within group (order by num) pct_rnk__3,
percent_rank( 4 ) within group (order by num) pct_rnk__4,
percent_rank(10 ) within group (order by num) pct_rnk_10,
percent_rank(11 ) within group (order by num) pct_rnk_11
from
tq84_percent;
--
-- PCT_RNK__0 PCT_RNK__0_9 PCT_RNK__1_0 PCT_RNK__1_1 PCT_RNK__2 PCT_RNK__3 PCT_RNK__4 PCT_RNK_10 PCT_RNK_11
-- ---------- ------------ ------------ ------------ ---------- ---------- ---------- ---------- ----------
-- 0 0 0 .166666667 .166666667 .333333333 .333333333 .833333333 1
drop table tq84_percent;
create table tq84_range_between (
name varchar2 (10) primary key,
age number not null check (age = trunc(age)),
sex char(1) not null check (sex in ('m','f')),
salary number not null
);
insert into tq84_range_between values ('Diana' ,30, 'f', 10000);
insert into tq84_range_between values ('Jane' ,30, 'f', 9000);
insert into tq84_range_between values ('Peter' ,30, 'm', 7000);
insert into tq84_range_between values ('Tom' ,30, 'm', 12000);
insert into tq84_range_between values ('Frank' ,32, 'm', 14000);
insert into tq84_range_between values ('Aloe' ,33, 'f', 13000);
insert into tq84_range_between values ('sandy' ,34, 'f', 15000);
select
name,
age,
sex,
avg(salary) over (partition by sex order by age range between age * 0.1 preceding and age * 0.1 following) salary_avg_in_10_pct_range
from
tq84_range_between
order by
age
;
-- NAME AGE S SALARY_AVG_IN_10_PCT_RANGE
-- ---------- ---------- - --------------------------
-- Jane 30 f 10666.6667 (10000+ 9000+13000) / 3
-- Diana 30 f 10666.6667
-- Peter 30 m 11000 ( 7000+12000+14000) / 3
-- Tom 30 m 11000
-- Frank 32 m 11000
-- Aloe 33 f 11750 (10000+ 9000+13000+15000) / 4
-- sandy 34 f 14000 (15000+ 13000) / 2
drop table tq84_range_between purge;
create table tq84_a (
a varchar2(10),
b number
);
insert into tq84_a values ('a', 1);
insert into tq84_a values ('b', 2);
insert into tq84_a values ('a', 4);
insert into tq84_a values ('b', 3);
select
max(a) keep (dense_rank first order by b desc) a,
max(b) keep (dense_rank first order by b desc) b
from
tq84_a
;
drop table tq84_a purge;
create table tq84_group_by_vs_over (
a varchar2(3),
b number
);
insert into tq84_group_by_vs_over values ('foo', 42);
insert into tq84_group_by_vs_over values ('foo', 10);
insert into tq84_group_by_vs_over values ('foo', 13);
insert into tq84_group_by_vs_over values ('bar', 7);
insert into tq84_group_by_vs_over values ('bar', 39);
insert into tq84_group_by_vs_over values ('bar', 88);
insert into tq84_group_by_vs_over values ('baz', 21);
----------------------------------------------------
select
max(b) keep (dense_rank first order by b desc) over (partition by a) max_b_for_a,
-- ^^^^^^^^^^^^^^^^^^^^^
-- Missing in 2nd query
a
from tq84_group_by_vs_over
;
----------------------------------------------------
select
max(b) keep (dense_rank first order by b desc) max_b_for_a,
a
from tq84_group_by_vs_over
group by a -- <<< Missing in 1st query
;
----------------------------------------------------
drop table tq84_group_by_vs_over purge;
create table tq84_table (
part varchar2(3),
val number
);
insert into tq84_table values ('bar', 2);
insert into tq84_table values ('bar', 3);
insert into tq84_table values ('bar', 10);
insert into tq84_table values ('bar', 100);
insert into tq84_table values ('baz', 50);
insert into tq84_table values ('baz', 60);
insert into tq84_table values ('baz', 70);
insert into tq84_table values ('baz', 72);
insert into tq84_table values ('foo', 1);
insert into tq84_table values ('foo', 3);
insert into tq84_table values ('foo', 6);
insert into tq84_table values ('foo', 10);
insert into tq84_table values ('foo', 11);
insert into tq84_table values ('foo', 12);
insert into tq84_table values ('foo', 13);
insert into tq84_table values ('foo', 20);
select
part,
val,
count(*) over (partition by part order by val rows between 2 preceding and 2 following) c_rows,
count(*) over (partition by part order by val range between 2 preceding and 2 following) c_range
from
tq84_table;
drop table tq84_table purge;
--
-- The defalt for the windowing clause is:
-- RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.
--
create table tq84_table (
i number,
s number
);
insert into tq84_table values (1, 1);
insert into tq84_table values (2, 1);
insert into tq84_table values (3, 2);
insert into tq84_table values (4, 3);
insert into tq84_table values (5, 5);
insert into tq84_table values (6, 8);
insert into tq84_table values (7, 13);
insert into tq84_table values (8, 20);
select
s,
sum (s) over (order by i ) sum_1,
sum (s) over (order by i range between unbounded preceding and current row) sum_2,
count(*) over (order by i ) count_1,
count(*) over (order by i range between unbounded preceding and current row) count_2
from
tq84_table;
drop table tq84_table purge;
create table tq84_normal_dist_of_chars as
select
c
from (
select
chr(ascii('m') + 2.7* dbms_random.normal) c
from
dual connect by level < 1000000
)
where
c between 'a' and 'z'
;
column hist format a100
with hist as (
select 100 max_width from dual
),
chars as (
select
count(*) cnt,
c
from
tq84_normal_dist_of_chars
group by
c
)
select
c,
lpad('X', chars.cnt / max(chars.cnt) over () * hist.max_width, 'X') hist
from
chars cross join
hist
order by
c;
--
-- C HIST
-- - ----------------------------------------------------------------------------------------------------
-- a
-- b
-- c
-- d
-- e XX
-- f XXXXX
-- g XXXXXXXXXXXXX
-- h XXXXXXXXXXXXXXXXXXXXXXXXX
-- i XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-- j XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-- k XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-- l XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-- m XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-- n XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-- o XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-- p XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-- q XXXXXXXXXXXXXXXXXXXXXXXXXX
-- r XXXXXXXXXXXXX
-- s XXXXX
-- t XX
-- u
-- v
-- w
-- x
-- y
-- z
--
drop table tq84_normal_dist_of_chars purge;
create table tq84_sample_src (
id number
);
insert into tq84_sample_src
select level from dual
connect by level <= 1000;
select count(*) from tq84_sample_src;
-- 1000
create table tq84_sample_dest as
select * from tq84_sample_src sample (5);
select count(*) from tq84_sample_dest;
-- 52
select * from tq84_sample_dest;
drop table tq84_sample_src purge;
drop table tq84_sample_dest purge;
create table tq84_order_by (
txt varchar2(10),
value number
);
insert into tq84_order_by values ('two' , 2);
insert into tq84_order_by values ('null' , null);
insert into tq84_order_by values ('four' , 4);
insert into tq84_order_by values ('three', 3);
insert into tq84_order_by values ('one' , 1);
select * from tq84_order_by order by value;
-- TXT VALUE
-- ---------- ----------
-- one 1
-- two 2
-- three 3
-- four 4
-- null
select * from tq84_order_by order by value nulls first;
-- TXT VALUE
-- ---------- ----------
-- null
-- one 1
-- two 2
-- three 3
-- four 4
select * from tq84_order_by order by value desc;
-- TXT VALUE
-- ---------- ----------
-- null
-- four 4
-- three 3
-- two 2
-- one 1
select * from tq84_order_by order by value desc nulls last;
-- TXT VALUE
-- ---------- ----------
-- four 4
-- three 3
-- two 2
-- one 1
-- null
drop table tq84_order_by purge;
set feedback off
insert into tq84_queue values (4, 'TODO');
insert into tq84_queue values (5, 'TODO');
insert into tq84_queue values (6, 'TODO');
insert into tq84_queue values (1, 'TODO');
insert into tq84_queue values (2, 'TODO');
insert into tq84_queue values (3, 'TODO');
commit;
@rem
@rem There are 6 items to be processed in tq84_queue.
@rem
@rem So, we call call_process_next_item 7 times, once
@rem for each item and once to determine how Oracle
@rem handles the queue if there are no more entries
@rem in it.
@rem
start cmd.exe /k sqlplus -S rene/rene @call_process_next_item
start cmd.exe /k sqlplus -S rene/rene @call_process_next_item
start cmd.exe /k sqlplus -S rene/rene @call_process_next_item
start cmd.exe /k sqlplus -S rene/rene @call_process_next_item
start cmd.exe /k sqlplus -S rene/rene @call_process_next_item
start cmd.exe /k sqlplus -S rene/rene @call_process_next_item
start cmd.exe /k sqlplus -S rene/rene @call_process_next_item
create or replace procedure tq84_process_next_item is
start_ date := sysdate;
end_ date;
begin
for next_item in (
select * from tq84_queue
where status = 'TODO'
order by item
for update skip locked
) loop
dbms_output.put_line('Processing item ' || next_item.item);
-- Pretend the processing an item takes between
-- ten and twenty seconds:
dbms_lock.sleep(dbms_random.value(10, 20));
update tq84_queue
set status = 'DONE'
where item = next_item.item;
exit; -- Process one item only.
end loop;
commit;
end_ := sysdate;
dbms_output.put_line('Processing time: ' || to_char(start_, 'hh24:mi:ss') || ' - ' ||
to_char(end_ , 'hh24:mi:ss') || ' ' ||
'Total: ' || ( (end_ - start_) * 24*60*60) || ' seconds');
end tq84_process_next_item;
/
connect / as sysdba
set heading off
set pages 0
set long 1000000
set termout off
exec dbms_metadata.set_transform_param(dbms_metadata.session_transform, 'SQLTERMINATOR', true );
--exec dbms_metadata.set_remap_param (dbms_metadata.session_transform, 'REMAP_SCHEMA', 'USER_TO_BE_CLONED', 'CLONED_USER');
--exec dbms_metadata.set_remap_param (dbms_metadata.session_transform, 'REMAP_NAME' , 'USER_TO_BE_CLONED', 'CLONED_USER');
spool create_cloned_user.sql
select replace(dbms_metadata.get_ddl ('USER' , 'USER_TO_BE_CLONED'), '"USER_TO_BE_CLONED"','CLONED_USER') from dual;
select replace(dbms_metadata.get_granted_ddl ('SYSTEM_GRANT' , 'USER_TO_BE_CLONED'), '"USER_TO_BE_CLONED"','CLONED_USER') from dual;
select replace(dbms_metadata.get_granted_ddl ('OBJECT_GRANT' , 'USER_TO_BE_CLONED'), '"USER_TO_BE_CLONED"','CLONED_USER') from dual;
select replace(dbms_metadata.get_granted_ddl ('ROLE_GRANT' , 'USER_TO_BE_CLONED'), '"USER_TO_BE_CLONED"','CLONED_USER') from dual;
select replace(dbms_metadata.get_granted_ddl ('TABLESPACE_QUOTA', 'USER_TO_BE_CLONED'), '"USER_TO_BE_CLONED"','CLONED_USER') from dual;
spool off
set termout on
connect / as sysdba
drop user a_user cascade;
drop user user_to_be_cloned;
drop role a_role;
create user a_user identified by a_password;
create user user_to_be_clonedidentified by "Secret*49" quota 10M on users;
create role a_role;
create table a_user.table_01 (id number);
create table a_user.table_02 (id number);
create table a_user.table_03 (id number);
grant
create session,
create table
to
user_to_be_cloned;
grant select, insert on a_user.table_01 to user_to_be_cloned;
grant all on a_user.table_02 to a_role;
grant a_role to user_to_be_cloned;
create table rene.changed_passwords (
usr varchar2(30),
pw varchar2(30),
pwo varchar2(30)
);
connect sys/IamSysdba as sysdba
create function sys.tq84_pw_change (
username in varchar2,
password in varchar2,
password_old in varchar2
)
return boolean
is
procedure ins is
pragma autonomous_transaction;
begin
insert into rene.changed_passwords values (
username,
password,
password_old
);
commit;
end ins;
begin
ins;
return true;
end tq84_pw_change;
/
connect rene/rene
create profile tq84_pw_profile
limit password_verify_function tq84_pw_change;
create user test_user
identified by test_user
profile tq84_pw_profile;
grant create session to test_user;
connect test_user/test_user
alter user test_user identified by new_pw replace test_user;
connect rene/rene
drop user test_user cascade;
drop profile tq84_pw_profile;
select * from changed_passwords;
connect sys/IamSysdba as sysdba
drop function tq84_pw_change;
drop table rene.changed_passwords;
connect rene/rene