2026-03-12 20:23:15

This commit is contained in:
root
2026-03-12 21:23:47 +01:00
parent eab4b36eca
commit 93039b8489
3332 changed files with 699614 additions and 0 deletions

Binary file not shown.

View File

@@ -0,0 +1,50 @@
// run with:
// java -cp $ORACLE_HOME/jdbc/lib/ojdbc5.jar:. Client_id
import java.sql.*;
import oracle.jdbc.OracleConnection;
import java.util.UUID;
import java.util.Arrays;
public class ArrayBindSelect {
public static void main(String[] args) throws InterruptedException {
try {
// get connection and statement
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
Connection conn = DriverManager.getConnection( "jdbc:oracle:thin:@oel6:1521:LIN112", "system","oracle");
Statement stmt = conn.createStatement();
// set metrics for connection (will be sent to server the next rountrip)
String[] metrics = new String[OracleConnection.END_TO_END_STATE_INDEX_MAX];
metrics[OracleConnection.END_TO_END_MODULE_INDEX]="Array Bind Select";
((OracleConnection)conn).setEndToEndMetrics(metrics,(short)0);
String[] values = new String[1000];
Arrays.fill(values, UUID.randomUUID().toString());
//for (int i=0; i<1000; i++)
// values[i] = UUID.randomUUID().toString();
ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor("ARRAY_OF_PERSONS", conn);
// then obtain an Array filled with the content below
String[] content = { "v4" };
sqlArray = new oracle.sql.ARRAY(arrayDescriptor, (OracleConnection)conn, content);
for(int i=1;i<1000000;i++) {
stmt.setArray(1,values);
ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM dual WHERE dummy IN (?)");
}
Thread.sleep(1000);
}
catch (SQLException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,46 @@
// run with:
// java -cp $ORACLE_HOME/jdbc/lib/ojdbc8.jar:. BatchInsert
// requires:
// CREATE TABLE t(a NUMBER, b VARCHAR2(150));
// results in these metrics (Starts=10) for a single *batch* execution of the SQL (v$sql.executions=1)
//
// INSERT INTO t SELECT :1 , :2 FROM dual
//
// --------------------------------------------------------------------------------------------------------
// | Id | Operation | Name | Starts | E-Rows | Cost (%CPU)| A-Rows | A-Time | Buffers |
// --------------------------------------------------------------------------------------------------------
// | 0 | INSERT STATEMENT | | 10 | | 2 (100)| 0 |00:00:00.01 | 13 |
// | 1 | LOAD TABLE CONVENTIONAL | T | 10 | | | 0 |00:00:00.01 | 13 |
// | 2 | FAST DUAL | | 10 | 1 | 2 (0)| 10 |00:00:00.01 | 0 |
// --------------------------------------------------------------------------------------------------------
import java.sql.*;
import oracle.jdbc.OracleConnection;
public class BatchInsert {
public static void main(String[] args) throws InterruptedException {
try {
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
Connection conn = DriverManager.getConnection( "jdbc:oracle:thin:@linux01:1521:LIN19C", "system","oracle");
String sql = "INSERT INTO t SELECT ?, ? FROM dual";
PreparedStatement stmt = conn.prepareStatement(sql);
for(int i=1; i<=10; i++) {
stmt.setInt(1, i);
stmt.setString(2, new String("blah"));
stmt.addBatch();
}
stmt.executeBatch();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}

47
tpt/demos/Client_id.java Normal file
View File

@@ -0,0 +1,47 @@
// run with:
// java -cp $ORACLE_HOME/jdbc/lib/ojdbc5.jar:. Client_id
//
// Note that Oracle 12c JDBC drivers support JDBC 4.1 with SetClientInfo() method
// In Oracle 12c+ drivers, conn.setEndToEndMetrics() is deprecated in favor of
// conn.setClientInfo()
//
// https://docs.oracle.com/en/database/oracle/oracle-database/19/jjdbc/JDBC-standards-support.html#GUID-1987FAC4-E93A-49A5-9EB4-A78B465E6938
import java.sql.*;
import oracle.jdbc.OracleConnection;
public class Client_id {
public static void main(String[] args) throws InterruptedException {
try {
// get connection and statement
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
Connection conn = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:LIN11G", "system","oracle");
Statement stmt = conn.createStatement();
// set metrics for connection (will be sent to server the next rountrip)
String[] metrics = new String[OracleConnection.END_TO_END_STATE_INDEX_MAX];
metrics[OracleConnection.END_TO_END_CLIENTID_INDEX]="Tanel Poder:123";
((OracleConnection)conn).setEndToEndMetrics(metrics,(short)0);
// run your SQL code. the client identifier attribute is bundled with this roundtrip and automatically sent to server with this request
ResultSet rs = stmt.executeQuery("SELECT sid, username, client_identifier FROM v$session WHERE type='USER' AND status='ACTIVE'");
// print output from v$session. here you should see this java program's session with client identifier set
System.out.printf("\n%4s %20s %30s\n", new Object[] {"SID", "USERNAME", "CLIENT_IDENTIFIER"});
System.out.println("--------------------------------------------------------");
while (rs.next()) {
System.out.printf("%4s %20s %30s\n", new Object[] {Integer.toString(rs.getInt("sid")), rs.getString("username"), rs.getString("client_identifier")} );
}
// Sleeping for 10 seconds. If you query the client_identifier from another session
// you'll see that the last client_identifier still remains set (is not automatically cleared
// upon statement completion)
Thread.sleep(10000);
}
catch (SQLException e) {
e.printStackTrace();
}
}
}

34
tpt/demos/Commit.java Normal file
View File

@@ -0,0 +1,34 @@
// run with:
// java -cp $ORACLE_HOME/jdbc/lib/ojdbc5.jar:. Client_id
import java.sql.*;
import oracle.jdbc.OracleConnection;
public class Commit {
public static void main(String[] args) throws InterruptedException {
try {
// get connection and statement
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
Connection conn = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:LIN11G", "system","oracle");
Statement stmt = conn.createStatement();
// set metrics for connection (will be sent to server the next rountrip)
String[] metrics = new String[OracleConnection.END_TO_END_STATE_INDEX_MAX];
metrics[OracleConnection.END_TO_END_MODULE_INDEX]="Committer";
((OracleConnection)conn).setEndToEndMetrics(metrics,(short)0);
for(int i=1;i<1000000;i++) {
ResultSet rs = stmt.executeQuery("UPDATE t SET a=a+1");
//autocommit takes care of this conn.commit();
}
Thread.sleep(100);
}
catch (SQLException e) {
e.printStackTrace();
}
}
}

34
tpt/demos/Commit2.java Normal file
View File

@@ -0,0 +1,34 @@
// run with:
// java -cp $ORACLE_HOME/jdbc/lib/ojdbc5.jar:. Client_id
import java.sql.*;
import oracle.jdbc.OracleConnection;
public class Commit2 {
public static void main(String[] args) throws InterruptedException {
try {
// get connection and statement
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
Connection conn = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:LIN11G", "system","oracle");
Statement stmt = conn.createStatement();
// set metrics for connection (will be sent to server the next rountrip)
String[] metrics = new String[OracleConnection.END_TO_END_STATE_INDEX_MAX];
metrics[OracleConnection.END_TO_END_MODULE_INDEX]="Committer";
((OracleConnection)conn).setEndToEndMetrics(metrics,(short)0);
for(int i=1;i<1000000;i++) {
ResultSet rs = stmt.executeQuery("UPDATE t SET a=a+1");
//autocommit takes care of this conn.commit();
}
Thread.sleep(1000);
}
catch (SQLException e) {
e.printStackTrace();
}
}
}

BIN
tpt/demos/GetDate.class Normal file

Binary file not shown.

32
tpt/demos/GetDate.java Normal file
View File

@@ -0,0 +1,32 @@
// run with:
// java -cp $ORACLE_HOME/jdbc/lib/ojdbc6.jar:. GetDate
import java.sql.*;
import oracle.jdbc.OracleConnection;
public class GetDate {
public static void main(String[] args) throws InterruptedException {
try {
// get connection and statement
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
Connection conn = DriverManager.getConnection( "jdbc:oracle:thin:@centos7:1521:LIN121", "system","oracle");
Statement stmt = conn.createStatement();
stmt.execute("ALTER SESSION SET time_zone = '-08:00'");
ResultSet rs = stmt.executeQuery("SELECT d FROM t");
// print output from v$session. here you should see this java program's session with client identifier set
System.out.printf("\n%-10s %-10s %-20s\n", "DATE", "TIME", "TIMESTAMP");
System.out.println("-------------------------------------------------");
while (rs.next()) {
System.out.printf("%-10s %-10s %-20s\n", new Object[] {rs.getDate("D").toString(), rs.getTime("D").toString(), rs.getTimestamp("D").toString()} );
}
}
catch (SQLException e) {
e.printStackTrace();
}
}
}

BIN
tpt/demos/JustSleep.class Normal file

Binary file not shown.

30
tpt/demos/JustSleep.java Normal file
View File

@@ -0,0 +1,30 @@
// run with:
// java -cp $ORACLE_HOME/jdbc/lib/ojdbc5.jar:. Client_id
import java.sql.*;
import oracle.jdbc.OracleConnection;
public class JustSleep {
public static void main(String[] args) throws InterruptedException {
try {
// get connection and statement
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
Connection conn = DriverManager.getConnection( "jdbc:oracle:thin:@oel6:1521:LIN112", "system","oracle");
Statement stmt = conn.createStatement();
// set metrics for connection (will be sent to server the next rountrip)
String[] metrics = new String[OracleConnection.END_TO_END_STATE_INDEX_MAX];
metrics[OracleConnection.END_TO_END_CLIENTID_INDEX]="Tanel Poder";
((OracleConnection)conn).setEndToEndMetrics(metrics,(short)0);
// run your SQL code. the client identifier attribute is bundled with this roundtrip and automatically sent to server with this request
ResultSet rs = stmt.executeQuery("BEGIN DBMS_LOCK.SLEEP(9999); END;");
}
catch (SQLException e) {
e.printStackTrace();
}
}
}

BIN
tpt/demos/SelectCount.class Normal file

Binary file not shown.

View File

@@ -0,0 +1,42 @@
// run with:
// java -cp $ORACLE_HOME/jdbc/lib/ojdbc5.jar:. Client_id
import java.sql.*;
import oracle.jdbc.OracleConnection;
public class SelectCount {
public static void main(String[] args) throws InterruptedException {
try {
// get connection and statement
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
Connection conn = DriverManager.getConnection( "jdbc:oracle:thin:@oel6:1521:LIN112", "system","oracle");
Statement stmt = conn.createStatement();
// set metrics for connection (will be sent to server the next rountrip)
String[] metrics = new String[OracleConnection.END_TO_END_STATE_INDEX_MAX];
metrics[OracleConnection.END_TO_END_CLIENTID_INDEX]="Tanel Poder";
((OracleConnection)conn).setEndToEndMetrics(metrics,(short)0);
// run your SQL code. the client identifier attribute is bundled with this roundtrip and automatically sent to server with this request
ResultSet rs = stmt.executeQuery("SELECT COUNT(*) c FROM dba_source");
// print output from v$session. here you should see this java program's session with client identifier set
System.out.printf("\nCOUNT\n");
System.out.println("---------------------------------");
while (rs.next()) {
System.out.printf("%-10s\n", new Object[] {Integer.toString(rs.getInt("C"))} );
}
// Sleeping for 10 seconds. If you query the client_identifier from another session
// you'll see that the last client_identifier still remains set (is not automatically cleared
// upon statement completion)
Thread.sleep(10000);
}
catch (SQLException e) {
e.printStackTrace();
}
}
}

22
tpt/demos/assm_bug.sql Normal file
View File

@@ -0,0 +1,22 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
-- Make sure that the USERS tablespace is ASSM-managed
DROP TABLE t;
CREATE TABLE t(a CHAR(100)) TABLESPACE users;
INSERT INTO t SELECT 'x' FROM dual CONNECT BY LEVEL <= 5000000;
COMMIT;
ALTER SESSION SET plsql_optimize_level = 0;
-- EXEC FOR i IN 1..1000 LOOP INSERT INTO t VALUES ('x'); END LOOP;
PROMPT Deleting all rows from t, do not commit...
DELETE t;
PROMPT Run this in another session, this should be very slow:
PROMPT EXEC FOR i IN 1..1000 LOOP INSERT INTO t VALUES ('x'); END LOOP;;
PROMPT

16
tpt/demos/bad_monitor.sql Normal file
View File

@@ -0,0 +1,16 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
PROMPT THIS SCRIPT WILL CAUSE A LOT OF TORUBLE!!!
PROMPT DON'T RUN IT IN PRODUCTION!!!
PAUSE PRESS ENTER TO CONTINUE OR CTRL+C TO EXIT...
DECLARE
j number;
BEGIN
WHILE true LOOP
select count(*) into j from x$ksmsp;
END LOOP;
END;
/

View File

@@ -0,0 +1,73 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
-- create tablespace assm
-- extent management local uniform size 1m
-- segment space management auto
-- datafile
-- '/abc/db01/oracle/ABC1P/oradata/assm_01.dbf' size 1000m;
create table test_assm
(
n1 number,
v1 varchar2(50),
v2 varchar2(50),
v3 varchar2(50),
v4 varchar2(50),
v5 varchar2(50),
v6 varchar2(50),
v7 varchar2(50),
v8 varchar2(50),
v9 varchar2(50),
v10 varchar2(50)
)
tablespace USERS;
begin
for i in 1..1000000 loop
insert into test_assm values
(i,
'123456789*123456789*123456789*123456789*1234567',
'123456789*123456789*123456789*123456789*1234567',
'123456789*123456789*123456789*123456789*1234567',
'123456789*123456789*123456789*123456789*1234567',
'123456789*123456789*123456789*123456789*1234567',
'123456789*123456789*123456789*123456789*1234567',
'123456789*123456789*123456789*123456789*1234567',
'123456789*123456789*123456789*123456789*1234567',
'123456789*123456789*123456789*123456789*1234567',
'123456789*123456789*123456789*123456789*1234567');
end loop;
end;
/
COMMIT;
ALTER SESSION SET plsql_optimize_level = 0;
begin
for i in 1..1000 loop
insert into test_assm values
(i,
'123456789*123456789*123456789*123456789*1234567',
'123456789*123456789*123456789*123456789*1234567',
'123456789*123456789*123456789*123456789*1234567',
'123456789*123456789*123456789*123456789*1234567',
'123456789*123456789*123456789*123456789*1234567',
'123456789*123456789*123456789*123456789*1234567',
'123456789*123456789*123456789*123456789*1234567',
'123456789*123456789*123456789*123456789*1234567',
'123456789*123456789*123456789*123456789*1234567',
'123456789*123456789*123456789*123456789*1234567');
end loop;
end;
/
PROMPT Deleting all rows from the table, do not commit...
DELETE test_assm;
PROMPT Re-execute script that inserts 1000 rows from a different session - this should be very slow

View File

@@ -0,0 +1,60 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
--------------------------------------------------------------------------------
--
-- File name: demos/bind_peeking.sql
--
-- Purpose: Advanced Oracle Troubleshooting Seminar demo script
--
-- Author: Tanel Poder ( http://www.tanelpoder.com )
--
-- Copyright: (c) 2007-2009 Tanel Poder
--
--------------------------------------------------------------------------------
set echo on
drop table t;
create table t as select * from dba_objects, (select rownum from dual connect by level <= 20);
create index i on t(object_id);
exec dbms_stats.gather_table_stats(user, 'T');
select count(*), min(object_id)
, max(object_id) from t;
pause
var x number
exec :x := 100000
pause
set timing on
select sum(length(object_name)) from t where object_id > :x;
select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
pause
exec :x := 1
select sum(length(object_name)) from t where object_id > :x;
select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
pause
select sum(length(object_name)) from t where object_id > :x;
select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));

46
tpt/demos/buffer_busy.sql Normal file
View File

@@ -0,0 +1,46 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
-- DROP TABLE tbb;
-- DROP SEQUENCE tbb_seq;
--
-- CREATE SEQUENCE tbb_seq NOCACHE;
--
-- CREATE TABLE tbb (
-- id NUMBER PRIMARY KEY
-- , val NUMBER
-- , entry_date DATE
-- );
--
-- CREATE INDEX tbb_entry ON tbb(entry_date);
--
-- INSERT INTO tbb VALUES (0, 123, sysdate);
-- COMMIT;
DECLARE
tmp_id NUMBER;
BEGIN
WHILE TRUE LOOP
SELECT MIN(id) INTO tmp_id FROM tbb;
INSERT INTO tbb VALUES (tbb_seq.NEXTVAL, 123, sysdate);
BEGIN
DELETE FROM tbb WHERE id = tmp_id;
EXCEPTION
WHEN no_data_found THEN NULL;
END;
COMMIT;
END LOOP;
END;
/

47
tpt/demos/bulk_insert.sql Normal file
View File

@@ -0,0 +1,47 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
-- Simple Export
drop table t;
create table t as select * from all_users where 1=0;
-- this type def is created based on data dictionary definition of extracted table when exporting
create or replace type rtype as object ( username varchar2(30), user_id number, created date )
/
create or replace type ttype as table of rtype;
/
-- set nls_date format to some standard format
declare
rows ttype := ttype();
begin
insert into t
select * from table (
ttype (
rtype('a',1,sysdate),
rtype('b',2,sysdate),
rtype('c',3,sysdate),
rtype('d',4,sysdate),
rtype('e',5,sysdate),
rtype('f',6,sysdate),
rtype('g',7,sysdate),
rtype('h',8,sysdate),
rtype('i',9,sysdate),
rtype('j',10,sysdate),
rtype('k',11,sysdate),
rtype('l',12,sysdate),
rtype('m',13,sysdate),
rtype('n',14,sysdate)
)
);
end;
/
select * from t;
drop type ttype;
drop type rtype;
-- can we do completely without creating stored types?

14
tpt/demos/color.sql Normal file
View File

@@ -0,0 +1,14 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
select
color(lpad(' ',20), trunc(mod((r+0)/36,6)), trunc(mod((r+0)/6,6)), trunc(mod((r+0),6)) )
|| color(lpad(' ',20), trunc(mod((r+0)/36,6))+0, trunc(mod((r+0)/6,6))+0, trunc(mod((r+0),6))+0 )
|| color(lpad(' ',20), trunc(mod((r+0)/36,6))+0, trunc(mod((r+0)/6,6))+0, trunc(mod((r+0),6))+0 )
|| color(lpad(' ',20), trunc(mod((r+0)/36,6))+0, trunc(mod((r+0)/6,6))+0, trunc(mod((r+0),6))+0 )
|| color(lpad(' ',20), trunc(mod((r+0)/36,6))+0, trunc(mod((r+0)/6,6))+0, trunc(mod((r+0),6))+0 )
|| color(lpad(' ',20), trunc(mod((r+0)/36,6))+0, trunc(mod((r+0)/6,6))+0, trunc(mod((r+0),6))+0 )
from
(select rownum - 1 r from dual connect by level <= 36*6)
/

52
tpt/demos/countstar.sql Normal file
View File

@@ -0,0 +1,52 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
-- count(columnX) is slower than count(*) or count(1)
drop table t;
create table t cache as select * from v$session;
insert into t select * from t;
insert into t select * from t;
insert into t select * from t;
insert into t select * from t;
insert into t select * from t;
insert into t select * from t;
insert into t select * from t;
insert into t select * from t;
insert into t select * from t;
insert /*+ append */ into t select * from t;
commit;
insert /*+ append */ into t select * from t;
commit;
insert /*+ append */ into t select * from t;
commit;
insert /*+ append */ into t select * from t;
commit;
insert /*+ append */ into t select * from t;
commit;
insert /*+ append */ into t select * from t;
commit;
exec dbms_stats.gather_table_stats(user, 'T');
-- to get better rowsource level timing accuracy
alter session set "_rowsource_statistics_sampfreq"=1;
select /*+ gather_plan_statistics */ count(*) from t;
set timing on
select /*+ gather_plan_statistics */ count(*) from t;
select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
select /*+ gather_plan_statistics */ count(1) from t;
select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
select /*+ gather_plan_statistics */ count(sid) from t;
select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
select /*+ gather_plan_statistics */ count(state) from t;
select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
-- set back to default
alter session set "_rowsource_statistics_sampfreq"=128;

View File

@@ -0,0 +1,28 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
-- This hard crashes the target process in 10.2.0.3 Solaris with SEGV
DROP VIEW v1;
DROP FUNCTION f1;
CREATE OR REPLACE FUNCTION f1 RETURN NUMBER AS
BEGIN
RETURN 1;
END;
/
CREATE OR REPLACE view v1 AS SELECT f1 FROM dual;
CREATE OR REPLACE FUNCTION f1 RETURN NUMBER AS
i NUMBER;
BEGIN
SELECT f1 INTO i FROM v1;
RETURN i;
END;
/
CREATE OR REPLACE view v1 AS SELECT f1 FROM dual;

View File

@@ -0,0 +1,48 @@
From Metalink note: 602111.1
-----------------------
connect scott/tiger
CREATE TABLE "SCOTT"."DS_CONFIG" (
"ID" NUMBER NOT NULL,
"TITLE" VARCHAR2(100 byte) NOT NULL,
"MENU" VARCHAR2(50 byte) NOT NULL,
"DESCRIPTION" VARCHAR2(200 byte),
"CODE" VARCHAR2(3 byte) NOT NULL,
"LOB_TABLE" VARCHAR2(1024 byte) NOT NULL,
"LOB_FIELD" VARCHAR2(100 byte) NOT NULL,
"ISBLOB" CHAR(1byte) NOT NULL,
"DOC_TYPE" VARCHAR2(4 byte),
"TYPE_FIELD" VARCHAR2(100 byte),
"ROLE" VARCHAR2(50 byte),
"KEY_FIELD" VARCHAR2(100 byte) NOT NULL,
"KEY_TYPE" CHAR(1 byte) NOT NULL,
"BROWSE_TABLE" VARCHAR2(1024 byte) NOT NULL,
"BROWSE_ORDER" VARCHAR2(250 byte),
"ISPROD" CHAR(1 byte),
CONSTRAINT "DS_CONFIG_PK" PRIMARY KEY("ID")
USING INDEX
TABLESPACE "USERS"
STORAGE ( INITIAL 64K NEXT 0K MINEXTENTS 1 MAXEXTENTS
2147483645 PCTINCREASE 0) PCTFREE 10 INITRANS 2 MAXTRANS 255
NOVALIDATE,
CONSTRAINT "DS_CONFIG__ISBLOB" CHECK("ISBLOB" IN ('T','F')))
TABLESPACE "USERS" PCTFREE 10 PCTUSED 0 INITRANS 1
MAXTRANS 255
STORAGE ( INITIAL 64K NEXT 0K MINEXTENTS 1 MAXEXTENTS
2147483645 PCTINCREASE 0);
connect / as sysdba
CREATE OR REPLACE VIEW "SCOTT"."DS_ROLES" ("ROLE","GRANTEE",
"CODE","MENU") AS
SELECT DISTINCT c1.ROLE, p1.GRANTEE,c1.CODE, c1.menu
FROM SYS.DBA_ROLE_PRIVS p1
LEFT JOIN DBA_ROLE_PRIVS p2 ON p1.granted_role = p2.grantee
LEFT JOIN DBA_ROLE_PRIVS p3 ON p2.granted_role = p3.grantee
LEFT JOIN DBA_ROLE_PRIVS p4 ON p3.granted_role = p4.grantee
LEFT JOIN DBA_ROLE_PRIVS p5 ON p4.granted_role = p5.grantee
LEFT JOIN SCOTT.DS_CONFIG c1 ON c1.role = p1.granted_role OR c1.role = p2.granted_role OR
c1.role = p3.granted_role OR c1.role = p4.granted_role OR c1.role = p5.granted_role
WHERE p1.GRANTEE LIKE 'OPS$%' AND c1.ID IS NOT NULL;

View File

@@ -0,0 +1,27 @@
-- Copyright 2020 Tanel Poder. All rights reserved. More info at https://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
DECLARE
cmd CLOB := 'CREATE TABLE widetable ( id NUMBER PRIMARY KEY ';
ins CLOB := 'INSERT INTO widetable SELECT rownum';
BEGIN
FOR x IN 1..999 LOOP
cmd := cmd || ', col'||TRIM(TO_CHAR(x))||' VARCHAR2(10)';
ins := ins || ', TRIM(TO_CHAR(rownum))';
END LOOP;
cmd := cmd || ')';
ins := ins || ' FROM dual CONNECT BY level <= 100';
EXECUTE IMMEDIATE cmd;
EXECUTE IMMEDIATE ins;
END;
/
COMMIT;
-- stats with histograms
EXEC DBMS_STATS.GATHER_TABLE_STATS(user,'WIDETABLE',method_opt=>'FOR TABLE, FOR ALL COLUMNS SIZE 254');
-- no histograms
-- EXEC DBMS_STATS.GATHER_TABLE_STATS(user,'WIDETABLE',method_opt=>'FOR TABLE, FOR ALL COLUMNS SIZE 1');
-- EXEC sys.dbms_shared_pool.purge('SYSTEM', 'WIDETABLE', 1, 1);

57
tpt/demos/cse.sql Normal file
View File

@@ -0,0 +1,57 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
--------------------------------------------------------------------------------
--
-- File name: demos/cse.sql
--
-- Purpose: Advanced Oracle Troubleshooting Seminar demo script
--
-- Demonstrating common subexpression elimination transformation
--
-- Author: Tanel Poder ( http://www.tanelpoder.com )
--
-- Copyright: (c) 2007-2009 Tanel Poder
--
--------------------------------------------------------------------------------
set serverout on size 1000000
create or replace function imhere( par in varchar2 )
return varchar2
as
begin
dbms_output.put_line('i''m here!: '||par);
return par;
end;
/
@pd eliminate_common_subexpr
set echo on
select /*+ ORDERED_PREDICATES tanel1 */ *
from dual
where
(imhere(dummy) = 'X' and length(dummy) = 10)
or (imhere(dummy) = 'X' and length(dummy) = 11)
/
alter session set "_eliminate_common_subexpr"=false;
select /*+ ORDERED_PREDICATES tanel2 */ *
from dual
where
(imhere(dummy) = 'X' and length(dummy) = 10)
or (imhere(dummy) = 'X' and length(dummy) = 11)
/
set echo off
select /*+ tanel3 */ *
from dual
where
(imhere(dummy) = 'X' and length(dummy) = 10)
or (imhere(dummy) = 'X' and length(dummy) = 11)
/

View File

@@ -0,0 +1,33 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
drop table t;
create table t as
select rownum a, 'zzz' b from dual connect by level<=1000;
create index i on t(a);
exec dbms_stats.gather_table_stats(user,'T',method_opt=>'FOR COLUMNS A SIZE 254');
@sqlt "select * from t where a ="
alter session set cursor_sharing = similar;
spool lotsofselects.sql
select 'select * from t where a = '||rownum||';' from dual connect by level<=10000;
spool off
@lotsofselects.sql
@hash
@sqlt "select * from t where a ="
--exec for i in 1 .. 10000 loop execute immediate 'delete t where a = '||to_char(i); end loop;
--declare j number; begin for i in 1..1000 loop select count(*) into

View File

@@ -0,0 +1,26 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
drop table t;
create table t as
select rownum a, 'zzz' b from dual connect by level<=1000
union all
select 0, 'yyy' FROM dual;
create index i on t(a);
exec dbms_stats.gather_table_stats(user,'T',method_opt=>'FOR COLUMNS A,B SIZE 254');
alter session set cursor_sharing = similar;
declare
j number;
begin
for i in 1..1000 loop
select count(*) into j from t where a = to_char(i);
end loop;
end;
/

92
tpt/demos/ddl_trigger.sql Normal file
View File

@@ -0,0 +1,92 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
--------------------------------------------------------------------------------
--
-- File name: ddl_trigger.sql
--
-- Purpose: Advanced Oracle Troubleshooting Seminar demo script
--
-- Allows creating a DDL safeguard trigger, which prohibits
-- DDL on all objects except the ones listed.
-- This helps to work around accidential table/index dropping etc
--
-- Author: Tanel Poder ( http://www.tanelpoder.com )
--
-- Copyright: (c) 2007-2009 Tanel Poder
--
--------------------------------------------------------------------------------
EXEC EXECUTE IMMEDIATE 'DROP TRIGGER ddl_trig'; EXCEPTION WHEN OTHERS THEN NULL;
DROP TABLE test_table;
DROP TABLE ddl_allowed_operations;
CREATE TABLE ddl_allowed_operations (
owner VARCHAR2(30) NOT NULL
, object_name VARCHAR2(128) NOT NULL
, create_allowed CHAR(1) NOT NULL
, alter_allowed CHAR(1) NOT NULL
, drop_allowed CHAR(1) NOT NULL
, truncate_allowed CHAR(1) NOT NULL
, CONSTRAINT ddl_allowed_operations PRIMARY KEY ( owner, object_name )
)
ORGANIZATION INDEX
/
CREATE OR REPLACE TRIGGER ddl_trig
BEFORE CREATE OR ALTER OR DROP OR TRUNCATE ON DATABASE
DECLARE
l_create CHAR(1);
l_alter CHAR(1);
l_drop CHAR(1);
l_truncate CHAR(1);
BEGIN
BEGIN
SELECT create_allowed, alter_allowed, drop_allowed, truncate_allowed
INTO l_create, l_alter, l_drop, l_truncate
FROM ddl_allowed_operations
WHERE owner = ora_dict_obj_owner
AND object_name = ora_dict_obj_name;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20000, 'DDL on '||ora_dict_obj_owner||'.'||ora_dict_obj_name|| ' prohibited. Object not listed in DDL_ALLOWED_OPERATIONS table.');
END;
CASE ora_sysevent
WHEN 'CREATE' THEN
IF UPPER(l_create) != 'Y' THEN
RAISE_APPLICATION_ERROR(-20000, 'CREATE on '||ora_dict_obj_owner||'.'||ora_dict_obj_name|| ' prohibited.');
END IF;
WHEN 'ALTER' THEN
IF UPPER(l_alter) != 'Y' THEN
RAISE_APPLICATION_ERROR(-20000, 'ALTER on '||ora_dict_obj_owner||'.'||ora_dict_obj_name|| ' prohibited.');
END IF;
WHEN 'DROP' THEN
IF UPPER(l_drop) != 'Y' THEN
RAISE_APPLICATION_ERROR(-20000, 'DROP on '||ora_dict_obj_owner||'.'||ora_dict_obj_name|| ' prohibited.');
END IF;
WHEN 'TRUNCATE' THEN
IF UPPER(l_truncate) != 'Y' THEN
RAISE_APPLICATION_ERROR(-20000, 'TRUNCATE on '||ora_dict_obj_owner||'.'||ora_dict_obj_name|| ' prohibited.');
END IF;
END CASE;
END;
/
SHOW ERR
INSERT INTO ddl_allowed_operations VALUES (user, 'TEST_TABLE', 'Y', 'N', 'N', 'N');
COMMIT;
CREATE TABLE test_table (a INT);
-- DROP TABLE test_table;
-- TRUNCATE TABLE test_table;
-- UPDATE ddl_allowed_operations SET drop_allowed = 'Y' WHERE owner = user AND object_name = 'TEST_TABLE';
-- DROP TABLE test_table;

View File

@@ -0,0 +1,27 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
--DROP TABLE t;
--CREATE TABLE t (a CHAR(100)) PCTFREE 99 PCTUSED 1 TABLESPACE users;
--@seg2 T
--@gts T
TRUNCATE TABLE t;
INSERT /*+ APPEND */ INTO t SELECT 'x' FROM dual CONNECT BY LEVEL <= 1000;
--@dump 4 99316 Start
--@dump 4 99317 Start
ALTER SYSTEM FLUSH BUFFER_CACHE;
COMMIT;
--@dump 4 99316 Start
--@dump 4 99317 Start
--@ev 10203 2
--@ev 10200 1
--@ev 10046 8
SELECT COUNT(*) FROM t;
--@dump 4 99316 Start
--@dump 4 99317 Start

37
tpt/demos/dontrun.sql Normal file
View File

@@ -0,0 +1,37 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
SELECT * FROM dual dontrun;
@hash
@oddc optim
ALTER SESSION SET EVENTS 'trace [SQL_Optimizer] [sql:g40pz6bqjwbzt] controlc_signal()';
ALTER SYSTEM FLUSH SHARED_POOL;
SELECT * FROM dual pleaserun;
SELECT * FROM dual dontrun;
SELECT * FROM dual dontrun;
ALTER SESSION SET EVENTS 'trace [SQL_Optimizer] [sql:g40pz6bqjwbzt] off';
ALTER SESSION SET EVENTS 'trace [Parallel_Execution] [sql:g40pz6bqjwbzt] controlc_signal()';
SELECT * FROM dual dontrun;
ALTER SESSION FORCE PARALLEL QUERY PARALLEL 4;
SELECT * FROM dual dontrun;
ALTER SESSION SET EVENTS 'trace [Parallel_Execution] [sql:g40pz6bqjwbzt] off';
ALTER SYSTEM FLUSH SHARED_POOL;
ALTER SESSION SET EVENTS 'trace [SQL_Optimizer] [sql:g40pz6bqjwbzt] crash';
SELECT * FROM dual dontrun;

View File

@@ -0,0 +1,86 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
--------------------------------------------------------------------------------
--
-- File name: demos/drop_logmine.sql
--
-- Purpose: Advanced Oracle Troubleshooting Seminar demo script
--
-- A logminer demo script showing logged DDL statement texts
--
-- Author: Tanel Poder ( http://www.tanelpoder.com )
--
-- Copyright: (c) 2007-2009 Tanel Poder
--
--------------------------------------------------------------------------------
@ti
--alter session set events '1349 trace name context forever, level 131071';
set echo on
create table tanel_drop_test( a int ) enable supplemental log data (all) columns;
--insert into t select rownum from dba_objects where rownum <= 25000;
alter system switch logfile;
connect tanel/oracle@lin11g
col member new_value member
col sequence# new_value sequence
select member from v$logfile where group# = (select group# from v$log where status = 'CURRENT');
select to_char(sequence#) sequence# from v$log where status = 'CURRENT';
prompt drop /* tanel_blah_&sequence */ table tanel_drop_test purge;;
drop /* tanel_blah_&sequence */ table tanel_drop_test purge;
delete from TANEL_DEL_TEST where rownum <= 1;
--delete from TANEL_DEL_TEST where rownum <= 1000;
commit;
@date
select
sid
, serial#
, audsid
, '0x'||trim(to_char(sid, 'XXXX')) "0xSID"
, '0x'||trim(to_char(serial#, 'XXXXXXXX')) "0xSERIAL"
, '0x'||trim(to_char(audsid, 'XXXXXXXX')) "0xAUDSID"
from
v$session
where
sid = userenv('SID')
/
connect tanel/oracle@lin11g
alter system switch logfile;
alter system dump logfile '&member';
set echo off
@minelog &member
select * from v$logmnr_contents where table_name = 'TANEL_DROP_TEST' and rbasqn = &sequence
.
@pr
select * from v$logmnr_contents where table_name = 'TANEL_DEL_TEST' or table_name like '%80184%' and rbasqn = &sequence
.
@pr
col member clear
col sequence# clear
alter system checkpoint;
host pscp oracle@linux03:&member c:\tmp\ddl.log

View File

@@ -0,0 +1,31 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
--drop table mytab;
--drop table tmp;
-- this is our "source table"
create table mytab as select * from all_objects;
create index i on mytab(owner);
-- this is where we copy only needed rows:
create table tmp
partition by range (owner) (
partition p1 values less than (maxvalue)
)
as
select * from mytab
where owner != 'SYS'
/
-- in order to do partition exchange, the physical structure of source table and target need to be the same (including indexes):
create index i_tmp on tmp(owner) local;
-- get rid of old rows
truncate table mytab;
-- exchange the tmp.p1 partition segment with mytab's segment
alter table tmp exchange partition p1 with table mytab including indexes;
-- you may need to run this to validate any constraints if they're in novalidate status
alter table mytab constraint <constraint_name> enable validate;

21
tpt/demos/explain.sql Normal file
View File

@@ -0,0 +1,21 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
drop table t;
create table t as select * from all_objects;
create index i on t(object_id);
@gts t
explain plan for
select * from t where object_id = 10000;
select * from table(dbms_xplan.display);
rollback;
var v number
exec :v:=10000;
explain plan for
select * from t where object_id = :v;
select * from table(dbms_xplan.display);

66
tpt/demos/fetch.sql Normal file
View File

@@ -0,0 +1,66 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
--------------------------------------------------------------------------------
--
-- File name: demos/fetch.sql "<SQL to execute>"
--
-- Purpose: Advanced Oracle Troubleshooting Seminar demo script
--
-- Shows effect of arraysize to fetch lengths and
-- in which execution/fetching stage data access work is done
--
-- Author: Tanel Poder ( http://www.tanelpoder.com )
--
-- Copyright: (c) 2007-2009 Tanel Poder
--
--------------------------------------------------------------------------------
set termout off
drop table t;
create table t as
select
rownum a
, CAST(rownum as CHAR(2000)) b
from
dual
connect by
level <= 50
/
create index i on t(a);
exec dbms_stats.gather_table_stats(user, 'T');
--set arraysize 5
col fetch_command new_value fetch_command
select replace(replace(replace('&1', '*', '\*'),'/','\/'),'>','\>') fetch_command from dual;
-- hard parse
clear buffer
1 &1
/
alter session set sql_trace=true;
@ti
set termout off
clear buffer
1 &1
/
set termout on
prompt TRACE OUTPUT:
prompt _________________________________
prompt
host "grep -A 99999 -B1 '&fetch_command' &trc | sed -e '/&fetch_command/p;/PARS/p;/EXEC/p;/FETCH/p;d'"
--select * from table(dbms_xplan.display_cursor(null,null, 'ALLSTATS LAST'));

View File

@@ -0,0 +1,50 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
--------------------------------------------------------------------------------
--
-- File name: demos/find_hash_collision.sql
-- Purpose: Advanced Oracle Troubleshooting seminar demo script
-- for finding different SQL statements which have colliding hash
-- values
--
-- Author: Tanel Poder
-- Copyright: (c) http://www.tanelpoder.com
--
-- Usage: @demos/find_hash_collision.sql
--
-- Other: In theory it may take a lot of memory if iterating way too many
-- times before finding colliding hash value
--
-- NB! This script is not working properly yet! As GET_SQL_HASH function
-- isn't doing its job right
--
--------------------------------------------------------------------------------
SET SERVEROUT ON SIZE 1000000
DECLARE
TYPE typ IS TABLE OF NUMBER INDEX BY VARCHAR2(10);
t typ;
i NUMBER := 0;
h VARCHAR2(10);
tmp NUMBER;
tmp_raw RAW(16);
str VARCHAR2(100):='select * from dual where rownum = ';
BEGIN
WHILE TRUE LOOP
h := TO_CHAR(DBMS_UTILITY.GET_SQL_HASH(str||TO_CHAR(i), tmp_raw, tmp));
IF t.EXISTS(h) THEN
DBMS_OUTPUT.PUT_LINE(CHR(10)||'Matching hash values found (hash='||TO_CHAR(h)||'):'||CHR(10)||CHR(10)||str||TO_CHAR(t(h))||CHR(10)||str||TO_CHAR(i));
DBMS_OUTPUT.PUT_LINE('raw='||RAWTOHEX(tmp_raw));
EXIT;
ELSE
t(h):=i;
i:=i+1;
END IF;
END LOOP;
END;
/
SET SERVEROUT OFF

24
tpt/demos/heapdump.sql Normal file
View File

@@ -0,0 +1,24 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
set echo on
declare
type tabtype is table of char(100);
t tabtype := NULL;
begin
select object_name
bulk collect into t
from dba_objects
order by lower(object_name);
dbms_lock.sleep(999999);
end;
/
set echo off

View File

@@ -0,0 +1,40 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
drop table t;
create table t PCTFREE 0 as select * from dba_source, (select 1 from dual connect by level<=5);
--create table t PCTFREE 0 as select * from dba_source;
-- deliberately using analyze table command to compute the number of chained rows
analyze table t compute statistics;
select num_rows,blocks,empty_blocks,chain_cnt from user_tables where table_name = 'T';
update t set owner = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' where rownum <= 100000;
commit;
update t set owner = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' where rownum <= 100000;
commit;
update t set owner = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' where rownum <= 100000;
commit;
update t set owner = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' where rownum <= 100000;
commit;
update t set owner = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' where rownum <= 100000;
commit;
update t set owner = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' where rownum <= 100000;
commit;
analyze table t compute statistics;
select num_rows,blocks,empty_blocks,chain_cnt from user_tables where table_name = 'T';
--exec dbms_stats.gather_table_stats(user,'T');
pause About to create the index, run snapper in another window on this session. Press ENTER to continue...
create index i on t(case when owner = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' then owner else null end) online;

View File

@@ -0,0 +1,15 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
drop table t;
create table t PCTFREE 0 as select * from all_objects;
update t set owner = lpad('x',30,'x') where owner = 'SYS' and rownum <= 10;
analyze table t compute statistics;
select chain_cnt from user_tables where table_name = 'T';
create index i on t(owner);

View File

@@ -0,0 +1,60 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
desc sydney_demo1
desc sydney_demo2
desc sydney_demo3
alter session set plsql_optimize_level=0;
set timing on
exec for i in 1..&1 loop insert into sydney_demo1 values (0); end loop;
set timing off termout off
rollback;
alter system checkpoint;
set timing on termout on
exec for i in 1..&1 loop insert into sydney_demo2 values (0); end loop;
set timing off termout off
rollback;
alter system checkpoint;
set timing on termout on
exec for i in 1..&1 loop insert into sydney_demo3 values (0); end loop;
set timing off termout off
rollback;
alter system checkpoint;
set timing on termout on
set timing off
--create table sydney_demo1 (a int) tablespace system;
--create table sydney_demo2 (a int) tablespace users;
--create table sydney_demo3 (a int) tablespace users2;

View File

@@ -0,0 +1,40 @@
-- Oracle join elimiation demo by Tanel Poder (https://tanelpoder.com)
DROP TABLE o;
DROP TABLE u;
CREATE TABLE u AS SELECT * FROM all_users;
CREATE TABLE o AS SELECT * FROM all_objects WHERE owner IN (SELECT username FROM all_users);
ALTER SESSION SET statistics_level = ALL;
-- set echo on
SELECT COUNT(*) FROM u, o WHERE u.username = o.owner;
SELECT * FROM TABLE(dbms_xplan.display_cursor(format=>'+OUTLINE -NOTE'));
SELECT COUNT(*) FROM u, o WHERE u.username = o.owner AND u.created IS NULL;
SELECT * FROM TABLE(dbms_xplan.display_cursor(format=>'+OUTLINE -NOTE'));
ALTER TABLE u ADD PRIMARY KEY (username);
ALTER TABLE o ADD CONSTRAINT fk_u FOREIGN KEY (owner) REFERENCES u(username);
SELECT COUNT(*) FROM u, o WHERE u.username = o.owner;
SELECT * FROM TABLE(dbms_xplan.display_cursor(format=>'+OUTLINE -NOTE'));
ALTER TABLE o DISABLE CONSTRAINT fk_u;
SELECT COUNT(*) FROM u, o WHERE u.username = o.owner;
SELECT * FROM TABLE(dbms_xplan.display_cursor(format=>'+OUTLINE -NOTE'));
ALTER TABLE o ENABLE NOVALIDATE CONSTRAINT fk_u;
SELECT COUNT(*) FROM u, o WHERE u.username = o.owner;
SELECT * FROM TABLE(dbms_xplan.display_cursor(format=>'+OUTLINE -NOTE'));
ALTER TABLE o ENABLE VALIDATE CONSTRAINT fk_u;
SELECT COUNT(*) FROM u, o WHERE u.username = o.owner;
SELECT * FROM TABLE(dbms_xplan.display_cursor(format=>'+OUTLINE -NOTE'));
-- set echo off

48
tpt/demos/kghupr1.sql Normal file
View File

@@ -0,0 +1,48 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
--------------------------------------------------------------------------------
--
-- File name: demos/kghupr1.sql
--
-- Purpose: Advanced Oracle Troubleshooting Seminar demo script
--
-- Author: Tanel Poder ( http://www.tanelpoder.com )
--
-- Copyright: (c) 2007-2009 Tanel Poder
--
--------------------------------------------------------------------------------
col laddr new_value laddr
col wordsize new_value wordsize
alter system flush shared_pool;
select addr laddr, vsize(addr) wordsize
from v$latch_children
where gets + immediate_gets >= (
select max(gets+immediate_gets)
from v$latch_children
where name = 'shared pool'
)
and name = 'shared pool'
/
-- oradebug watch 0x&laddr &wordsize self
alter session set session_cached_cursors = 0;
alter session set "_close_cached_open_cursors"=true;
prompt Running lots of soft parses. Use latchprofx on my SID in another session
declare
x number;
begin
for i in 1..10000000 loop
execute immediate 'select count(*) from dual where rownum = 1';
end loop;
end;
/
col laddr clear
col wordsize clear

19
tpt/demos/load.sql Normal file
View File

@@ -0,0 +1,19 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
alter session set plsql_optimize_level=0;
declare
l_sid number;
begin
select sid into l_sid from v$mystat where rownum = 1;
while true loop
execute immediate 'insert into t values('||to_char(l_sid)||')';
execute immediate 'commit';
execute immediate 'delete from t where a = '||to_char(l_sid);
execute immediate 'commit';
end loop;
end;
/

10
tpt/demos/load_1.sql Normal file
View File

@@ -0,0 +1,10 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
prompt starting demo_load_1...
set termout off
insert into t values(0);
commit;
delete t where a=0;
set termout on
prompt done. run demo_load_2 now in another session...

5
tpt/demos/load_2.sql Normal file
View File

@@ -0,0 +1,5 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
prompt starting demo_load_2...
delete from t where a=0;

27
tpt/demos/loadlock.sql Normal file
View File

@@ -0,0 +1,27 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
--------------------------------------------------------------------------------
--
-- File name: demoX.sql
--
-- Purpose: Advanced Oracle Troubleshooting Seminar demo script
--
-- If executed in multiple session, should cause library cache load lock contention
--
-- Author: Tanel Poder ( http://www.tanelpoder.com )
--
-- Copyright: (c) 2007-2009 Tanel Poder
--
--------------------------------------------------------------------------------
prompt compiling procedure p in loop...
begin
for i in 1..100000 loop
execute immediate 'alter system flush shared_pool';
execute immediate 'alter procedure p compile';
end loop;
end;
/

View File

@@ -0,0 +1,28 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
drop table t;
exec dbms_random.seed(0);
create table t(a) tablespace users as select dbms_random.random from dual connect by level <= 10000;
create index i on t(a);
@gts t
@stat changes "update (select a from t where a < 10000) set a = a + 1"
drop table t;
exec dbms_random.seed(0);
create table t(a) tablespace users as select dbms_random.random from dual connect by level <= 10000;
create index i on t(a);
@gts t
@stat changes "update (select /*+ index(t) */ a from t where a < 10000) set a = a + 1"
drop table t;
exec dbms_random.seed(0);
create table t(a) tablespace users as select dbms_random.random from dual connect by level <= 10000 order by 1;
create index i on t(a);
@gts t
@stat changes "update (select /*+ index(t) */ a from t where a < 10000) set a = a + 1"

View File

@@ -0,0 +1,29 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
DROP TABLE t;
CREATE TABLE t AS SELECT * FROM dual;
INSERT INTO t VALUES ('Y');
COMMIT;
PROMPT Sleeping for 3 seconds...
EXEC DBMS_LOCK.SLEEP(5);
PROMPT Running...
DECLARE
j NUMBER;
t NUMBER := 0;
curscn NUMBER;
BEGIN
SELECT current_scn INTO curscn FROM v$database;
FOR i IN 1..10000 LOOP
EXECUTE IMMEDIATE 'select count(*) from t as of scn '||curscn INTO j;
t := t + j;
DBMS_OUTPUT.PUT_LINE(j);
END LOOP;
DBMS_OUTPUT.PUT_LINE(t);
END;
/
@topcur

View File

@@ -0,0 +1,42 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
EXEC EXECUTE IMMEDIATE 'drop table t_children'; EXCEPTION WHEN OTHERS THEN NULL;
CREATE TABLE t_children AS SELECT rownum a, 'zzz' b FROM dual CONNECT BY LEVEL<=1000;
CREATE INDEX i_children ON t_children(a);
-- deliberately gathering a histogram
EXEC DBMS_STATS.GATHER_TABLE_STATS(user,'T_CHILDREN',method_opt=>'FOR COLUMNS A SIZE 254');
-- this is the crap setting
ALTER SESSION SET cursor_sharing = similar;
@saveset
SET PAGES 0 HEAD OFF TRIMOUT OFF TRIMSPOOL OFF ARRAYSIZE 5000 TERMOUT OFF
SPOOL tmp_lotschildren.sql
SELECT 'SELECT COUNT(*) FROM t_children WHERE a = '||TO_CHAR(ABS(DBMS_RANDOM.RANDOM))||';'
FROM dual CONNECT BY LEVEL <= 100000;
SPOOL OFF
@loadset
PROMPT Now run @tmp_lotschildren.sql
-- this hack is not working, must use plain SQL instead of plsql
-- ALTER SESSION SET session_cached_cursors = 0;
-- ALTER SESSION SET "_close_cached_open_cursors" = TRUE;
-- ALTER SESSION SET plsql_optimize_level = 0;
--
-- DECLARE
-- j NUMBER;
-- x NUMBER;
-- BEGIN
-- EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM t_children WHERE a = '||TO_CHAR(ABS(DBMS_RANDOM.RANDOM)) INTO j;
-- x:=x+j;
-- COMMIT;
-- END;
-- /

10015
tpt/demos/lotsofselects.sql Normal file

File diff suppressed because it is too large Load Diff

33
tpt/demos/mysgastat.sql Normal file
View File

@@ -0,0 +1,33 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
CREATE TABLE myspstat (
sample_time DATE
, subpool NUMBER
, name VARCHAR2(100)
, bytes NUMBER
);
BEGIN
WHILE TRUE LOOP
INSERT INTO myspstat
SELECT
SYSDATE
, ksmdsidx
, ksmssnam
, SUM(ksmsslen)
FROM
x$ksmss
WHERE
ksmsslen > 0
AND ksmdsidx > 0
GROUP BY
SYSDATE
, ksmdsidx
, ksmssnam;
COMMIT;
DBMS_LOCK.SLEEP(5);
END LOOP;
END;
/

28
tpt/demos/nl.sql Normal file
View File

@@ -0,0 +1,28 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
drop table t1;
drop table t2;
create table t1 as select * from dba_users;
create table t2 as select * from dba_objects;
select /*+ ordered use_nl(t2) gather_plan_statistics */
t1.user_id, t1.username, sum(length(t2.object_name))
from t1, t2
where t1.username = t2.owner
and t1.username = 'SYSTEM'
group by t1.user_id, t1.username
/
@x
select /*+ ordered use_nl(t2) gather_plan_statistics */
t1.user_id, t1.username, sum(length(t2.object_name))
from t1, t2
where t1.username = t2.owner
and t1.username like 'SYS%'
group by t1.user_id, t1.username
/
@x

View File

@@ -0,0 +1,6 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
alter session set "_old_connect_by_enabled"=true;
select 1 from dual connect by level < 2;

View File

@@ -0,0 +1,12 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
SELECT * FROM (
select rownum r from
all_users where username like 'S%'
order by r desc
)
WHERE r NOT IN (select /*+ HASH_AJ(a) */ rownum FROM all_users a where rownum<= 2)
and rownum <= 5
/

View File

@@ -0,0 +1,18 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
DROP TABLE t_commit;
CREATE TABLE t_commit AS SELECT 1 a FROM dual;
-- experiment with
ALTER SESSION SET COMMIT_LOGGING = IMMEDIATE;
ALTER SESSION SET COMMIT_WRITE = WAIT;
BEGIN
FOR i IN 1..1000000 LOOP
UPDATE t_commit SET a=a+1;
COMMIT;
END LOOP;
END;
/

View File

@@ -0,0 +1,36 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
drop table t1;
drop table t2;
set echo on
create table t1 as select rownum a from dual connect by level < 10;
create table t2 as select rownum+10 b from dual connect by level < 10;
exec dbms_stats.gather_table_stats(user,'T1');
exec dbms_stats.gather_table_stats(user,'T2');
--alter session set events '10053 trace name context forever';
--alter session set "_optimizer_trace"=all;
--alter session set events '10046 trace name context forever, level 4';
select * from t1;
select * from t2;
select a
from t1
where a in (select b from t2);
@x
select a
from t1
where a in (select /*+ PRECOMPUTE_SUBQUERY */b from t2);
@x
set echo off

View File

@@ -0,0 +1,42 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
drop table t;
set echo on
create or replace function f(x in number) return number as
begin
dbms_output.put_line('F='||to_char(x));
return x;
end;
/
set serverout on size 1000000
select * from dual
where
rownum = f(2)
or rownum = f(1)
/
create table t (a, b) as select 1, 1 from dual connect by level <= 100000;
insert into t values (1,2);
commit;
@gts t
truncate table t;
insert into t values (1,2);
commit;
--exec dbms_stats.set_table_stats(user, 'T', numrows=>1000000, numblks=>10000, avgrlen=>10, no_invalidate=>false);
select * from t where b=f(2) or a=f(1);
set echo off serverout off
/
@x

View File

@@ -0,0 +1,21 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
declare
procedure p is
pragma autonomous_transaction;
begin
begin
insert into t values(1);
-- set transaction read only;
dbms_lock.sleep(1);
-- exception
-- when others then null;
end;
p;
end;
begin
p;
end;
/

View File

@@ -0,0 +1,155 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
drop table t;
create table t(a int);
create or replace package recursive_session_test
-- authid definer
as
procedure p;
end;
/
create or replace package body recursive_session_test as
procedure p is
pragma autonomous_transaction;
begin
begin
-- insert into t values(1);
insert into t select rownum from dual connect by level <=100000;
dbms_lock.sleep(60);
-- set transaction read only;
exception
when others then null;
end;
p;
end;
begin
recursive_session_test.p;
end;
/
show err
grant execute on recursive_session_test to public;
select q'\@sample "decode(bitand(ksuseflg,19),17,'BACKGROUND',1,'USER',2,'RECURSIVE','?'),ksuudsna" x$ksuse ksusepro=hextoraw('\'||hextoraw(paddr)||''') 10000' run_this
from v$session where sid = userenv('SID')
union all
select ' ' from dual
union all
select 'select decode(bitand(ksuseflg,19),17,''BACKGROUND'',1,''USER'',2,''RECURSIVE'',''?''),ksuudsna,ksusepro,ksspaown'||chr(10)
||'from x$ksuse'||chr(10)
||'where ksusepro=hextoraw('''||paddr||''');' run_this
from v$session where sid = userenv('SID');
--'
insert into t select rownum from dual connect by level <= 100000;
exec recursive_session_test.p;
--, STATUS
--, SERVER
--, SCHEMA#
--, SCHEMANAME
--, OSUSER
--, PROCESS
--, MACHINE
--, TERMINAL
--, PROGRAM
--, TYPE
--, SQL_ADDRESS
--, SQL_HASH_VALUE
--, SQL_ID
--, SQL_CHILD_NUMBER
--, PREV_SQL_ADDR
--, PREV_HASH_VALUE
--, PREV_SQL_ID
--, PREV_CHILD_NUMBER
--, MODULE
--, MODULE_HASH
--, ACTION
--, ACTION_HASH
--, CLIENT_INFO
--, FIXED_TABLE_SEQUENCE
--, ROW_WAIT_OBJ#
--, ROW_WAIT_FILE#
--, ROW_WAIT_BLOCK#
--, ROW_WAIT_ROW#
--, LOGON_TIME
--, LAST_CALL_ET
--, PDML_ENABLED
--, FAILOVER_TYPE
--, FAILOVER_METHOD
--, FAILED_OVER
--, RESOURCE_CONSUMER_GROUP
--, PDML_STATUS
--, PDDL_STATUS
--, PQ_STATUS
--, CURRENT_QUEUE_DURATION
--, CLIENT_IDENTIFIER
--, BLOCKING_SESSION_STATUS
--, BLOCKING_INSTANCE
--, BLOCKING_SESSION
--, SEQ#
--, EVENT#
--, EVENT
--, P1TEXT
--, P1
--, P1RAW
--, P2TEXT
--, P2
--, P2RAW
--, P3TEXT
--, P3
--, P3RAW
--, WAIT_CLASS_ID
--, WAIT_CLASS#
--, WAIT_CLASS
--, WAIT_TIME
--, SECONDS_IN_WAIT
--, STATE
--, SERVICE_NAME
--, SQL_TRACE
--, SQL_TRACE_WAITS
--, SQL_TRACE_BINDS )
--as
--select
--s.inst_id,s.addr,s.indx,s.ksuseser,s.ksuudses,s.ksusepro,s.ksuudlui,s.ksuudlna,s.ksuudoct,s.ksusesow
--,
--decode(s.ksusetrn,hextoraw('00'),null,s.ksusetrn),decode(s.ksqpswat,hextoraw('00'),null,s.ksqpswat),
--decode(bitand(s.ksuseidl,11),1,'ACTIVE',0,decode(bitand(s.ksuseflg,4096),0,'INACTIVE','CACHED'),2,'SNIPED',3,'SNIPED', 'KILLED'),
--decode(s.ksspatyp,1,'DEDICATED',2,'SHARED',3,'PSEUDO','NONE'),
--s.ksuudsid,s.ksuudsna,s.ksuseunm,s.ksusepid,s.ksusemnm,s.ksusetid,s.ksusepnm,
--decode(bitand(s.ksuseflg,19),17,'BACKGROUND',1,'USER',2,'RECURSIVE','?'), s.ksusesql, s.ksusesqh,
--s.ksusesqi, decode(s.ksusesch, 65535, to_number(null), s.ksusesch), s.ksusepsq, s.ksusepha,
--s.ksusepsi, decode(s.ksusepch, 65535, to_number(null), s.ksusepch), s.ksuseapp, s.ksuseaph,
--s.ksuseact, s.ksuseach, s.ksusecli, s.ksusefix, s.ksuseobj, s.ksusefil, s.ksuseblk, s.ksuseslt,
--s.ksuseltm, s.ksusectm,decode(bitand(s.ksusepxopt, 12),0,'NO','YES'),decode(s.ksuseft, 2,'SESSION',
--4,'SELECT',8,'TRANSACTIONAL','NONE'),decode(s.ksusefm,1,'BASIC',2,'PRECONNECT',4,'PREPARSE','NONE'),
--decode(s.ksusefs, 1, 'YES','NO'),s.ksusegrp,decode(bitand(s.ksusepxopt,4),4,'ENABLED',decode(bitand(s.ksusepxopt,8),8,'FORCED',
--'DISABLED')),decode(bitand(s.ksusepxopt,2),2,'FORCED',decode(bitand(s.ksusepxopt,1),1,'DISABLED','ENABLED'))
--,decode(bitand(s.ksusepxopt,32),32,'FORCED',decode(bitand(s.ksusepxopt,16),16,'DISABLED','EN
--ABLED')), s.ksusecqd, s.ksuseclid, decode(s.ksuseblocker,4294967295,'UNKNOWN', 4294967294,
--'UNKNOWN',4294967293,'UNKNOWN',4294967292,'NO HOLDER', 4294967291,'NOT IN WAIT','VALID'),
--decode(s.ksuseblocker, 4294967295,to_number(null),4294967294,to_number(null),
--4294967293,to_number(null), 4294967292,to_number(null),4294967291,
--to_number(null),bitand(s.ksuseblocker, 2147418112)/65536),decode(s.ksuseblocker,
--4294967295,to_number(null),4294967294,to_number(null), 4294967293,to_number(null),
--4294967292,to_number(null),4294967291, to_number(null),bitand(s.ksuseblocker, 65535)),s.ksuseseq,
--s.ksuseopc,e.kslednam, e.ksledp1, s.ksusep1,s.ksusep1r,e.ksledp2,
--s.ksusep2,s.ksusep2r,e.ksledp3,s.ksusep3,s.ksusep3r,e.ksledclassid, e.ksledclass#, e.ksledclass,
--decode(s.ksusetim,0,0,-1,-1,-2,-2, decode(round(s.ksusetim/10000),0,-1,round(s.ksusetim/10000))),
--s.ksusewtm,decode(s.ksusetim, 0, 'WAITING', -2, 'WAITED UNKNOWN TIME', -1, 'WAITED SHORT TIME',
--decode(round(s.ksusetim/10000),0,'WAITED SHORT TIME','WAITED KNOWN TIME')),s.ksusesvc,
--decode(bitand(s.ksuseflg2,32),32,'ENABLED','DISABLED'),decode(bitand(s.ksuseflg2,64),64,'TRUE','FALSE'),
--decode(bitand(s.ksuseflg2,128),128,'TRUE','FALSE')
--from x$ksuse s, x$ksled e
--where
-- s.ksuseopc=e.indx
----and bitand(s.ksspaflg,1)!=0
----and bitand(s.ksuseflg,1)!=0

View File

@@ -0,0 +1,67 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
-- Connor McDonald's example
-- drop table t;
--
-- create table T
-- as select rownum x
-- from dual connect by level <= 10;
--
-- create or replace
-- type numlist is table of number;
-- /
--
-- create or replace function F(c sys_refcursor) return numlist pipelined is
-- n number;
-- begin
-- loop
-- fetch c into n;
-- exit when c%notfound;
-- pipe row (n);
-- end loop;
-- close c;
-- return;
-- end;
-- /
--
delete t;
commit;
variable rc refcursor;
lock table T in exclusive mode;
exec open :rc for select * from table(f(cursor(select * from t)));
commit;
insert into T values (11);
commit;
print rc
variable rc refcursor;
variable rc1 refcursor;
delete t;
commit;
lock table T in exclusive mode;
exec open :rc1 for select * from t;
exec open :rc for select * from table(f(:rc1));
commit;
insert into T values (11);
commit;
print rc
select * from dual;

View File

@@ -0,0 +1,40 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
drop table t;
Prompt Creating table with NO rowdependencies...
create table t tablespace users as select * From dba_objects;
update t set object_id = 1;
alter system flush buffer_cache;
@db
commit;
pause Press any key to select count(*) from t...
select distinct ora_rowscn from t;
pause Done. Press any key to continue...
drop table t;
Prompt Creating table WITH rowdependencies...
create table t tablespace users ROWDEPENDENCIES as select * From dba_objects;
update t set object_id = 1;
alter system flush buffer_cache;
@db
commit;
pause Press any key to select count(*) from t...
select distinct ora_rowscn from t;

View File

@@ -0,0 +1,72 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
-- A-Times were misestimated with the default sampling
-- ALTER SESSION SET "_rowsource_statistics_sampfreq"=1;
ALTER SESSION SET "_serial_direct_read"=ALWAYS;
SELECT /*+ MONITOR test2a */
SUM(LENGTH(object_name)) + SUM(LENGTH(object_type)) + SUM(LENGTH(owner))
FROM
test_objects_100m o
WHERE
o.owner = (SELECT u.username FROM test_users u WHERE user_id = 13)
/
@getprev
@xpi &prev_sql_id
@xia &prev_sql_id &prev_child_number
-- @ash/asqlmon &prev_sql_id &prev_child_number
-- @sqlidx &prev_sql_id &prev_child_number
SELECT /*+ MONITOR NO_PUSH_SUBQ(@"SEL$2") test2b */
SUM(LENGTH(object_name)) + SUM(LENGTH(object_type)) + SUM(LENGTH(owner))
FROM
test_objects_100m o
WHERE
o.owner = (SELECT u.username FROM test_users u WHERE user_id = 13)
/
@getprev
-- @ash/asqlmon &prev_sql_id &prev_child_number
-- @sqlidx &prev_sql_id &prev_child_number
@xpi &prev_sql_id
@xia &prev_sql_id &prev_child_number
-- ALTER SESSION SET "_rowsource_statistics_sampfreq"=128;
SELECT /*+ MONITOR OPT_PARAM('cell_offload_processing', 'false') test3a */
SUM(LENGTH(object_name)) + SUM(LENGTH(object_type)) + SUM(LENGTH(owner))
FROM
test_objects_100m o
WHERE
o.owner = (SELECT u.username FROM test_users u WHERE user_id = 13)
/
SELECT /*+ MONITOR NO_PUSH_SUBQ(@"SEL$2") OPT_PARAM('cell_offload_processing', 'false') test3b */
SUM(LENGTH(object_name)) + SUM(LENGTH(object_type)) + SUM(LENGTH(owner))
FROM
test_objects_100m o
WHERE
o.owner = (SELECT u.username FROM test_users u WHERE user_id = 13)
/
SELECT /*+ MONITOR PUSH_SUBQ(@"SEL$2") OPT_PARAM('cell_offload_processing', 'true') test4a */
SUM(LENGTH(object_name)) + SUM(LENGTH(object_type)) + SUM(LENGTH(owner))
FROM
test_objects_100m o
WHERE
o.owner = (SELECT u.username FROM test_users u WHERE user_id = 13)
/
SELECT /*+ MONITOR NO_PUSH_SUBQ(@"SEL$2") OPT_PARAM('cell_offload_processing', 'true') test4b */
SUM(LENGTH(object_name)) + SUM(LENGTH(object_type)) + SUM(LENGTH(owner))
FROM
test_objects_100m o
WHERE
o.owner = (SELECT u.username FROM test_users u WHERE user_id = 13)
/

View File

@@ -0,0 +1,39 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
-- DROP TABLE test_users;
-- DROP TABLE test_objects;
CREATE TABLE test_users AS SELECT * FROM all_users;
CREATE TABLE test_objects AS SELECT * FROM all_objects;
@gts test_users
@gts test_objects
@53on
SELECT /*+ GATHER_PLAN_STATISTICS */
u.username
, (SELECT MAX(created) FROM test_objects o WHERE o.owner = u.username)
FROM
test_users u
WHERE
username LIKE 'S%'
/
@53off
@xall
@53on
-- ALTER SESSION SET "_optimizer_unnest_scalar_sq" = FALSE;
SELECT /*+ GATHER_PLAN_STATISTICS NO_UNNEST(@ssq) */
u.username
, (SELECT /*+ QB_NAME(ssq) */ MAX(created) FROM test_objects o WHERE o.owner = u.username)
FROM
test_users u
WHERE
username LIKE 'S%'
/
@53off
@xall

54
tpt/demos/spin.sql Normal file
View File

@@ -0,0 +1,54 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
-- metalink bug# 5245101
create table TCMDTY(CMDTY_CD VARCHAR2(4),CMDTY_DESC VARCHAR2(30));
create or replace package UGS_LKUPS is
TYPE T_CURSOR IS REF CURSOR;
PROCEDURE GET_ACTIVE_CMDTYS (COMMODITIES_CURSOR IN OUT T_CURSOR);
end ugs_lkups;
/
create or replace package body UGS_LKUPS IS
PROCEDURE GET_ACTIVE_CMDTYS (COMMODITIES_CURSOR IN OUT T_CURSOR) IS
v_commodities T_CURSOR;
TYPE cmdty_code_type IS TABLE OF TCMDTY.CMDTY_CD%TYPE;
TYPE cmdty_desc_type IS TABLE OF TCMDTY.CMDTY_DESC%TYPE;
t_CMDTY_CD cmdty_code_type;
t_CMDTY_DESC cmdty_desc_type;
BEGIN
OPEN v_commodities FOR
SELECT CMDTY_CD, CMDTY_DESC
BULK COLLECT INTO t_CMDTY_CD, t_CMDTY_DESC
FROM TCMDTY
ORDER BY CMDTY_CD;
COMMODITIES_CURSOR := v_commodities;
END GET_ACTIVE_CMDTYS;
end ugs_lkups;
/
insert into TCMDTY values('a','aaaa');
insert into TCMDTY values('b','bbbb');
commit;
set serverout on
DECLARE
v_cursor ugs_lkups.t_cursor;
v_cmdty_cd tcmdty.cmdty_cd%TYPE;
v_cmdty_desc tcmdty.cmdty_desc%TYPE;
BEGIN
ugs_lkups.GET_ACTIVE_CMDTYS (COMMODITIES_CURSOR => v_cursor);
LOOP
FETCH v_cursor INTO v_cmdty_cd, v_cmdty_desc;
EXIT WHEN v_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_cmdty_cd || ' | ' || v_cmdty_desc);
END LOOP;
CLOSE v_cursor;
END;
/

52
tpt/demos/spm_synonym.sql Normal file
View File

@@ -0,0 +1,52 @@
-- Copyright 2019 Tanel Poder. All rights reserved. More info at https://blog.tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
-- this demos that a SQL Plan Baseline will still apply, even a synonym repoints to a different table.
-- the table has to have the same name (as otherwise the plan hash value changes), but the schema
-- is not part of plan hash value.
PROMPT This script will drop some tables called "T".
PROMPT Hit enter to continue, CTRL+C to cancel...
PAUSE
ALTER SESSION SET optimizer_use_sql_plan_baselines=TRUE;
DROP TABLE system.t;
DROP TABLE scott.t;
DROP SYNONYM syn;
CREATE TABLE system.t AS SELECT * FROM dba_objects;
CREATE TABLE scott.t AS SELECT * FROM system.t;
CREATE INDEX system.i ON system.t (object_id);
CREATE INDEX scott.i ON scott.t (object_id);
EXEC DBMS_STATS.GATHER_TABLE_STATS('SYSTEM','T', cascade=>TRUE);
EXEC DBMS_STATS.GATHER_TABLE_STATS('SCOTT' ,'T', cascade=>TRUE);
-- First point SYN to system schema
CREATE SYNONYM syn FOR system.t;
SELECT COUNT(owner) FROM syn t WHERE object_id = 12345;
@x
SELECT /*+ FULL(t) */ COUNT(owner) FROM syn t WHERE object_id = 12345;
@x
@create_sql_baseline bfwpapz4cfwz2 2966233522 3v3yzqv6dp704
SELECT COUNT(owner) FROM syn t WHERE object_id = 12345;
@x
-- Then point SYN to scott schema and run the same query text
DROP SYNONYM syn;
CREATE SYNONYM syn FOR scott.t;
SELECT COUNT(owner) FROM syn t WHERE object_id = 12345;
@x
@drop_sql_baseline SQL_547b571057dbd3d4

20
tpt/demos/sql_cursor.sql Normal file
View File

@@ -0,0 +1,20 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
set echo on
select curno,status,pers_heap_mem,work_heap_mem from v$sql_cursor where status != 'CURNULL';
pause
var x refcursor
exec open :x for select * from all_objects order by dbms_random.random;
pause
declare r all_objects%rowtype; begin fetch :x into r; end;
/
pause
select curno,status,pers_heap_mem,work_heap_mem from v$sql_cursor where status != 'CURNULL';
set echo off

View File

@@ -0,0 +1,20 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
create or replace function delete_func (owner_name in varchar2) return number
as
num_deleted number;
begin
-- this is a demo procedure
-- it does not do anything useful!
DELETE FROM mytab WHERE owner = owner_name;
COMMIT;
num_deleted := SQL%ROWCOUNT;
DBMS_OUTPUT.PUT_LINE('Deleted rows ='|| TO_CHAR(num_deleted));
return num_deleted;
end;
/
show err

24
tpt/demos/t_c_hotsos.sql Normal file
View File

@@ -0,0 +1,24 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
ALTER SESSION SET EVENTS 'immediate trace name trace_buffer_on level 1048576';
DECLARE
j NUMBER;
BEGIN
WHILE TRUE LOOP
BEGIN
SELECT /*+ INDEX_RS_ASC(t i_c_hotsos) */ data_object_id INTO j
FROM t_c_hotsos t
WHERE object_id = 21230 - 5000 + TRUNC(DBMS_RANDOM.VALUE(0, 10000)); -- 21230
--DBMS_LOCK.SLEEP(DBMS_RANDOM.VALUE(0,0.01));
EXCEPTION
WHEN OTHERS THEN NULL; -- Do not show this to Tom Kyte!!!
END;
END LOOP;
END;
/
ALTER SESSION SET EVENTS 'immediate trace name trace_buffer_off';

View File

@@ -0,0 +1,43 @@
-- Tom Kyte's script: http://tkyte.blogspot.com/2009/10/httpasktomoraclecomtkyteunindex.html
COL child_table_name FOR A30
COL child_constraint_name FOR A30
COL fk_columns FOR A100 WORD_WRAP
select table_name child_table_name, constraint_name child_constraint_name,
cname1 || nvl2(cname2,','||cname2,null) ||
nvl2(cname3,','||cname3,null) || nvl2(cname4,','||cname4,null) ||
nvl2(cname5,','||cname5,null) || nvl2(cname6,','||cname6,null) ||
nvl2(cname7,','||cname7,null) || nvl2(cname8,','||cname8,null) fk_columns
from ( select b.table_name,
b.constraint_name,
max(decode( position, 1, column_name, null )) cname1,
max(decode( position, 2, column_name, null )) cname2,
max(decode( position, 3, column_name, null )) cname3,
max(decode( position, 4, column_name, null )) cname4,
max(decode( position, 5, column_name, null )) cname5,
max(decode( position, 6, column_name, null )) cname6,
max(decode( position, 7, column_name, null )) cname7,
max(decode( position, 8, column_name, null )) cname8,
count(*) col_cnt
from (select substr(table_name,1,30) table_name,
substr(constraint_name,1,30) constraint_name,
substr(column_name,1,30) column_name,
position
from user_cons_columns ) a,
user_constraints b
where a.constraint_name = b.constraint_name
and b.constraint_type = 'R'
group by b.table_name, b.constraint_name
) cons
where col_cnt > ALL
( select count(*)
from user_ind_columns i
where i.table_name = cons.table_name
and i.column_name in (cname1, cname2, cname3, cname4,
cname5, cname6, cname7, cname8 )
and i.column_position <= cons.col_cnt
group by i.index_name
)
/

View File

@@ -0,0 +1,64 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
-- DROP TABLE t;
-- CREATE TABLE t (a NUMBER, b CHAR(2000));
--
-- CREATE INDEX i ON t(a,b) PCTFREE 0;
--
-- ALTER SESSION SET plsql_optimize_level = 0;
-- EXEC FOR i IN 1..50000 LOOP INSERT INTO t VALUES (i, 'x'); END LOOP;
-- modified version, based on http://sai-oracle.blogspot.com/2009/04/beware-of-index-contention-after-mass.html
CREATE TABLESPACE tmp_freelist_ts DATAFILE 'tmp_freelist_ts.dbf' SIZE 100M AUTOEXTEND ON EXTENT MANAGEMENT LOCAL UNIFORM SIZE 1M SEGMENT SPACE MANAGEMENT MANUAL;
DROP TABLE idx1;
DROP TABLE idx2;
CREATE TABLE idx1(a NUMBER) TABLESPACE tmp_freelist_ts;
CREATE INDEX idx1_idx ON idx1 (a) TABLESPACE tmp_freelist_ts PCTFREE 0;
INSERT INTO idx1 SELECT rownum FROM all_objects, all_objects WHERE ROWNUM <= 250000;
COMMIT;
CREATE TABLE idx2 TABLESPACE tmp_freelist_ts AS SELECT * FROM idx1 WHERE 1=2;
INSERT INTO idx2
SELECT * FROM idx1 WHERE rowid IN
(SELECT rid FROM
(SELECT rid, ROWNUM rn FROM
(SELECT rowid rid FROM idx1 WHERE a BETWEEN 10127 AND 243625 ORDER BY a)
)
WHERE MOD(rn, 250) = 0
)
/
COMMIT;
DELETE FROM idx1 WHERE a BETWEEN 10127 AND 243625;
COMMIT;
INSERT INTO idx1 SELECT * FROM idx2;
COMMIT;
INSERT INTO IDX1 SELECT 250000+ROWNUM FROM ALL_OBJECTS WHERE ROWNUM <= 126;
COMMIT;
SELECT SQL_ID, EXECUTIONS, BUFFER_GETS, DISK_READS, CPU_TIME, ELAPSED_TIME, ROWS_PROCESSED, SQL_TEXT FROM V$SQL
WHERE SQL_TEXT LIKE '%INSERT%IDX1%' AND SQL_TEXT NOT LIKE '%V$SQL%';
INSERT INTO IDX1 VALUES (251000);
COMMIT;
SELECT SQL_ID, EXECUTIONS, BUFFER_GETS, DISK_READS, CPU_TIME, ELAPSED_TIME, ROWS_PROCESSED, SQL_TEXT FROM V$SQL
WHERE SQL_TEXT LIKE '%INSERT%IDX1%' AND SQL_TEXT NOT LIKE '%V$SQL%';

36
tpt/demos/uga_alloc.sql Normal file
View File

@@ -0,0 +1,36 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
--------------------------------------------------------------------------------
--
-- File name: demos/uga_alloc.sql
--
-- Purpose: Advanced Oracle Troubleshooting Seminar demo script
--
-- Author: Tanel Poder ( http://www.tanelpoder.com )
--
-- Copyright: (c) 2007-2009 Tanel Poder
--
--------------------------------------------------------------------------------
set echo on
declare
type tabtype is table of char(1000);
t tabtype := NULL;
begin
select object_name
bulk collect into t
from dba_objects
order by lower(object_name);
dbms_lock.sleep(999999);
end;
/
set echo off

View File

@@ -0,0 +1,23 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
DROP TABLE t_child;
DROP TABLE t_parent;
CREATE TABLE t_parent(a INT PRIMARY KEY);
CREATE TABLE t_child(b INT, c INT, FOREIGN KEY (c) REFERENCES t_parent(a));
INSERT INTO t_parent SELECT rownum FROM dual CONNECT BY LEVEL<=10;
INSERT INTO t_child SELECT rownum, MOD(rownum,9)+1 FROM dual CONNECT BY LEVEL <= 10;
COMMIT;
PAUSE Press enter to update CHILD table:
PROMPT UPDATE t_child SET c = 10 WHERE c = 1;;
UPDATE t_child SET c = 10 WHERE c = 1;
PROMPT -- In another session run:
PROMPT UPDATE t_parent SET a = 7 WHERE a = 6;;
PROMPT

View File

@@ -0,0 +1,25 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
set echo on
drop table t;
create table t(a int, b char(100));
insert /*+ APPEND */ into t select rownum, object_name from all_objects;
create &1 index i on t(a);
exec dbms_stats.gather_table_stats(user,'T');
-- hard parse statement
set termout off
select a from t where a = 40000;
set termout on
set autot trace stat
select a from t where a = 40000;
set echo off autot off

66
tpt/demos/xa1.sql Normal file
View File

@@ -0,0 +1,66 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
-- Taken and customized from http://docs.oracle.com/cd/E18283_01/appdev.112/e17125/adfns_xa.htm
-- CREATE TABLE xa_t (a INT, b VARCHAR2(100));
-- INSERT INTO xa_t VALUES (1, 'tanel is testing');
-- COMMIT;
SET SERVEROUT ON
--ACCEPT global_trans_id NUMBER DEFAULT 123 PROMPT "Enter value for global_trans_id [123]: "
DEF global_trans_id = &1
PROMPT
REM Session 1 starts a transaction and does some work.
DECLARE
gtid NUMBER := &global_trans_id;
PROCEDURE handle_err (rc IN PLS_INTEGER, p_comment IN VARCHAR2 DEFAULT 'N/A') IS
xae EXCEPTION;
oer PLS_INTEGER;
BEGIN
IF rc!=DBMS_XA.XA_OK THEN
oer := DBMS_XA.XA_GETLASTOER();
DBMS_OUTPUT.PUT_LINE('ORA-' || oer || ' occurred, XA call '||p_comment||' failed');
RAISE xae;
ELSE
DBMS_OUTPUT.PUT_LINE('XA call '||p_comment||' succeeded');
END IF;
END handle_err;
BEGIN
HANDLE_ERR(SYS.DBMS_XA.XA_SETTIMEOUT(5), 'XA_SETTIMEOUT');
HANDLE_ERR(DBMS_XA.XA_START(DBMS_XA_XID(gtid), DBMS_XA.TMNOFLAGS), 'XA_START ('||gtid||')');
UPDATE xa_t SET b = 'tanel is not testing anymore' WHERE a = 1;
HANDLE_ERR(DBMS_XA.XA_END(DBMS_XA_XID(gtid), DBMS_XA.TMSUSPEND), 'XA_END/SUSP('||gtid||')');
HANDLE_ERR(DBMS_XA.XA_PREPARE(DBMS_XA_XID(gtid)), 'XA_PREPARE ('||gtid||')');
-- this is not needed for our test
-- DBMS_LOCK.SLEEP(10);
-- HANDLE_ERR(DBMS_XA.XA_ROLLBACK(DBMS_XA_XID(gtid)), 'XA_ROLLBACK('||gtid||')');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('XA error occurred, rolling back the transaction ...');
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_STACK);
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_CALL_STACK);
HANDLE_ERR(DBMS_XA.XA_END(DBMS_XA_XID(gtid), DBMS_XA.TMSUCCESS), 'XA_END/SUCC('||gtid||')');
HANDLE_ERR(DBMS_XA.XA_ROLLBACK(DBMS_XA_XID(gtid)), 'XA_ROLLBACK('||gtid||')');
END;
/
PROMPT Now wait for 10 seconds and run SELECT * FROM dba_2pc_pending;;
EXEC DBMS_LOCK.SLEEP(10);
COL tran_comment FOR A20
COL global_tran_id FOR A20
SELECT * FROM dba_2pc_pending WHERE state != 'forced rollback';
SET SERVEROUT OFF

30
tpt/demos/xa_rollback.sql Normal file
View File

@@ -0,0 +1,30 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
DEF trans_id=&1
VAR begin_scn NUMBER;
VAR end_scn NUMBER;
EXEC :begin_scn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER;
ROLLBACK FORCE '&1';
EXEC :end_scn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER;
-- noarchivelog:
DECLARE
logfile VARCHAR2(1000);
BEGIN
SELECT member INTO logfile FROM v$logfile WHERE group# = (SELECT group# FROM v$log WHERE status = 'CURRENT') AND rownum = 1;
SYS.DBMS_LOGMNR.ADD_LOGFILE(logfile, DBMS_LOGMNR.NEW);
SYS.DBMS_LOGMNR.START_LOGMNR(:begin_scn, :end_scn, OPTIONS=>DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG);
END;
/
SELECT * FROM v$logmnr_contents;
SELECT scn,timestamp,xid,operation,seg_owner,seg_name,row_id,sql_redo FROM v$logmnr_contents;
-- then exit the session or close the logmnr session or run
-- EXEC SYS.DBMS_LOGMNR.END_LOGMNR;

40
tpt/demos/xterm-color.sql Normal file
View File

@@ -0,0 +1,40 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
col a for a20
col b for a20
col c for a20
col d for a20
col e for a20
col f for a20
col g for a20
col h for a20
select
chr(27)||'[40m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' a
, chr(27)||'[41m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' b
, chr(27)||'[42m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' c
, chr(27)||'[43m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' d
, chr(27)||'[44m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' e
, chr(27)||'[45m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' f
, chr(27)||'[46m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' g
, chr(27)||'[47m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' h
from dual
connect by level<=8
union all
select chr(27)||'[0m', null, null, null, null, null, null, null from dual
union all
select
chr(27)||'[32m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' a
, chr(27)||'[33m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' b
, chr(27)||'[34m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' c
, chr(27)||'[35m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' d
, chr(27)||'[36m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' e
, chr(27)||'[37m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' f
, chr(27)||'[38m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' g
, chr(27)||'[39m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' h
from dual
connect by level<=8
union all
select chr(27)||'[0m', null, null, null, null, null, null, null from dual
/

View File

@@ -0,0 +1,16 @@
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
-- oracle 11.2+
SELECT
LISTAGG (CHR(27)||'[48;5;'||
( 16 + MOD(r,6) + MOD(TRUNC(r/6),6)*6 + MOD(TRUNC(r/36),6)*6*6 )||'m'||
LPAD(16 + MOD(r,6) + MOD(TRUNC(r/6),6)*6 + MOD(TRUNC(r/36),6)*6*6,4)||
CHR(27)||'[0m'
) WITHIN GROUP (ORDER BY MOD(TRUNC(r/6),6))
FROM
(SELECT rownum r FROM dual CONNECT BY LEVEL <= 216)
GROUP BY
MOD(TRUNC(r/36),6)
/