ManualiOracle.it
  
 
> Quizzes > Quizzes 2015-2019 -- Oracle / Postgresql -- Best Pratices / How to
 
 
 
 
 


In the page Prices and Donations, you can find how to have the solutions of the quizzes.

Nella pagina Prezzi Quiz potete vedere come avere le soluzioni dei quiz.


If it is not specified, the commands must be executed connected as a database "superuser".
About the solutions:
- could be more than one. Here is one solution that often takes into account of the performance tuning
- they could change because of the database version
- it is not warranted to be error-free in all the database environments


December 2019 - Postgres Unused Indexes

Level (*) : 3
Topic (*) : Postgres


You are connected in a Postgres 11.
Write a query reading the system catalog in order to get all the indexes matching these conditions:
- they must be never used since their creation
- not unique
- existing on the schema public in the database where you are connected

The query must return their SQL definition (you want it in case you have to re-create these indexes).
Result set example:
                     indexdef                      
 -------------------------------------------------------------------------
 CREATE INDEX t1_idx ON public.t1 USING btree (c1);
 CREATE INDEX model_gin ON public.dbelement USING gin (data jsonb_path_ops);




November 2019 - Postgres SQL Tuning

Level (*) : 3
Topic (*) : Postgres/Progr


You are connected in a postgres 11. In it, you have a partitioned table called JOU.
The partitioning is done by range on column DT_INSERT (its data type is timestamp and the partitioning is done monthly).

You have these 2 queries (today is 30th of October):
  SELECT col_1, count(*)
  FROM jou
  WHERE to_char(dt_insert,'yyyymm') >= '201910'
  GROUP BY col_1;

  SELECT col_1, count(*)
  FROM jou
  WHERE dt_insert >= (date_trunc('month', current_date))
  GROUP BY col_1;
How can you check which of these SELECT is faster?
Which database parameter you should check in order to discover if the "partition pruning" is enabled in your database?
How can you check, which of these SELECT is using the "partition pruning"?



October 2019 - Postgres connections

Level (*) : 2
Topic (*) : Postgres


You are connected in a machine where are 2 postgres installations:
one postgres 10 and one postgres 11:
  $ ps -ef |grep "bin/postg"
  postgres  1003   1  0 14:42 ?   00:00:00 /usr/lib/postgresql/11/bin/postgres ...
  postgres  3866   1  0 15:34 ?   00:00:00 /usr/lib/postgresql/10/bin/postgres ...
How can you do a connection to these databases using psql ?



September 2019 - Postgres connection

Level (*) : 2
Topic (*) : Postgres


You are connected to a Postgres database thru psql.
You are connected with the database user postgres.
How can you check which user are you using?
And how can you create a new table with the owner called user_eco (without knowing its password).



August 2019 - Postgres data files

Level (*) : 2
Topic (*) : Postgres


You are connected to a database called db_lor.
In it, you have 20 tables and you want to know all the data files (and their timestamps) associated to these tables.

Then find a "metadata query" that return an output like this (to be executed on Linux command line):
 ls -ld /var/lib/postgresql/10/main/base/13014/19441
 ls -ld /var/lib/postgresql/10/main/base/13014/19805
 ls -ld /var/lib/postgresql/10/main/base/13014/19797
 ls -ld /var/lib/postgresql/10/main/base/13014/19800



July 2019 - Postgres sequence

Level (*) : 2
Topic (*) : Postgres


In your database there is a sequence called seq_test.
Using the postgresql dictionary, which are 2 queries useful to get some information of this sequence ?

And find 2 other queries in order to get the current value of this sequence.



June 2019 - Postgres connections

Level (*) : 2
Topic (*) : Postgres


You want to know how many server processes are currently in your database cluster.
And you want to see these processes divided by database name and username.
So you have to find a query to get this information (in the "result set" you don't want to consider the server process you are using).

For istance, you want a result like this :
  datname   | usename  | count 
 -----------+----------+-------
 db_lassi   | lassi    |    10
 db_lassi   | loris    |     4
 db_pippo   | lassi    |     1
            | postgres |     1



May 2019 - Postgres Data Files

Level (*) : 1
Topic (*) : Postgres


You want to know where are the data files of your database cluster.
You see this:
  postgres=# SELECT * FROM pg_tablespace;
    spcname   | spcowner | spcacl | spcoptions 
  ------------+----------+--------+------------
   pg_default |       10 |        | 
   pg_global  |       10 |        | 
So which database parameter can you see to discover where are the data files?

Solution

You should check the data_directory parameter.
Example:
postgres=# show data_directory;
	       data_directory
	-----------------------------
	 /var/lib/postgresql/10/main

Then in this case, the data files will be inside the directories in:

	/var/lib/postgresql/10/main/base/



April 2019 - Postgres Dump & Restore

Level (*) : 2
Topic (*) : Postgres


You have 2 db cluster:
- machine_1 with postgres 10.7
- machine_2 with postgres 11.2

In machine_1, there is this database (it is quite big):
 postgres=# \l db_test_def
         List of databases
    Name     |     Owner     | ...
 ----------------------------+ ...
 db_test_def | user_test_def | ...
In the server machine_2, you have the user called user_test_def but these is no the database db_test_def.

You want to move that database from machine_1 to machine_2.
Which steps (and commands) you should do?



March 2019 - Postgres Barman

Level (*) : 2
Topic (*) : Postgres


You have a barman server version 2.4 in a debian machine.
You get two problems:
 1. You want to upgrade it to the latest version (2.6).
    How can you do it?

 2. You have a new postgres cluster database, version 11, to be backupped (until now, you
    have backupped only postgresql 10 databases).

    You are not able to backup the new cluster database and in the barman logs there is:
     2019-03-07 09:51:01,825 [30468] barman.server ERROR: ArchiverFailure:pg_receivexlog
     not present in $PATH

    Which can be the problem and How can you backup it?



February 2019 - Postgres data order

Level (*) : 1
Topic (*) : Postgres/Progr


In your postgres db, you have this table:
 CREATE TABLE t_order
 (id VARCHAR(6),
  description VARCHAR(100));

 INSERT INTO t_order VALUES ('1','product 1');
 INSERT INTO t_order VALUES ('11','product 11');
 INSERT INTO t_order VALUES ('2','product 2');

You must find a query in order to extract all the data ordered as if the ID column was a NUMBER (instead of VARCHAR).
Then you want a result like this:
  id | description 
 ----+-------------
  1  | product 1
  2  | product 2
  11 | product 11

Solution

To have the order using ID column as an INTEGER, you could launch this query :
 SELECT * 
 FROM t_order
 ORDER BY id::INT;



January 2019 - Postgres partition table creation

Level (*) : 2
Topic (*) : Postgres


In your postgres db, you have this partitioned table:
 # \dt
             List of relations
  Schema |   Name     | Type  |  Owner   
 --------+------------+-------+----------
  public | tb         | table | postgres
  public | tb_2018_4q | table | postgres
  public | tb_2019_1q | table | postgres

 # \d+ tb
                                                           Table "public.tb"
  Column |            Type             | ... | Nullable |             Default             
 --------+-----------------------------+-----+----------+---------------------------------
  id     | integer                     |     | not null | nextval('tb_id_seq'::regclass)
  dt_ins | timestamp without time zone |     | not null |                                 
  code   | character varying(255)      |     | not null |                                 
  detail | character varying(255)      |     |          |                                 
 Partition key: RANGE (dt_ins)
 Partitions: tb_2018_4q FOR VALUES FROM ('2018-10-01 00:00:00') TO ('2019-01-01 00:00:00'),
             tb_2019_1q FOR VALUES FROM ('2019-01-01 00:00:00') TO ('2019-04-01 00:00:00')

You must create the SQL scripts in order to create a table like this.



December 2018 - Postgres Date and Jsonb

Level (*) : 2
Topic (*) : Postgres/Progr


You have a table like this:
                    Table "public.t1"
  Column |            Type             | Collation | Nullable | Default 
 --------+-----------------------------+-----------+----------+---------
  id     | character varying(64)       |           | not null | 
  data   | jsonb                       |           | not null | 
  ts     | timestamp without time zone |           | not null |
You have to find a very simple query in order to get the rows where:
- column "ts" is bigger or equal to yesterday
- column "data" contains the word "PAYPAL"

You don't care about the "performace optimization" because the table T1 has no many rows.



November 2018 - Postgres SQL command

Level (*) : 2
Topic (*) : Postgres


Look at the describe of a table called T1.
  postgres=# \d t1
                                        Table "public.t1"
     Column    |         Type          | Collation | Nullable |            Default             
  -------------+-----------------------+-----------+----------+--------------------------------
   id          | integer               |           | not null | nextval('t1_id_seq'::regclass)
   description | character varying(10) |           |          | 
  Indexes:
      "t1_pkey" PRIMARY KEY, btree (id)
Find out a single SQL command in order to create exactly a table like this (then using only CREATE TABLE ... and not ALTER TABLE ...).



October - Postgres backup thru barman

Level (*) : 2
Topic (*) : Postgres


You are connected in a Barman server on Linux and you want to see:
- the barman logs
- which postgres database are configured for the backup system
- the connection status to the postgresql server
- the status of the Postgres server

How can you do these?



September 2018 - Postgres Read-Only database

Level (*) : 2
Topic (*) : Postgres


You are connected on a database called db_lor (single database, not database cluster).
You want to check if it's in read-only mode and, if not, you want to change it in read-only mode.
How can you do these?



August 2018 - Postgres db users

Level (*) : 1
Topic (*) : Postgres


You are connected, thru the psql tool, on a Postgres database cluster.
You must say two methods to have the list of the users in that db cluster.

Solution

You can get this information in these ways:
  Using the psql comand \du

  Example:

   postgres=# \du
		        List of roles
           Role name |   Attributes   | Member of 
	-------------+----------------+-----------
	 aitan       |                | {}
	 backup      | Replication    | {}
	 boiae       |                | {}
	 lassi       | Superuser      | {}

Or using this SELECT on a system table called PG_USER (it is shared across all databases of
a cluster):

  Example:

   postgres=# select usename from pg_user;
    datname  
  -----------
   aitan
   backup
   boiae
   lassi

   If you want more information regarding these users, use this query:

     select * from pg_user;




July 2018 - Postgres db list

Level (*) : 1
Topic (*) : Postgres


You are connected, thru the psql tool, on a Postgres database cluster.
You must say two methods to have the list of the databases in that db cluster.

Solution

You can get this information in these ways:
  Using the psql comand \list or \l

  Example:

   postgres=# \l
                                    List of databases
     Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
  -----------+----------+----------+-------------+-------------+-----------------------
   db_loris  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
   postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
   template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
             |          |          |             |             | postgres=CTc/postgres
   template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
             |          |          |             |             | postgres=CTc/postgres
   (4 rows)

Or using this SELECT on a system table called PG_DATABASE (it is shared across all databases
of a cluster):

  Example:

   postgres=# select datname from pg_database;
    datname  
  -----------
   db_loris
   postgres
   template0
   template1
   (4 rows)

   If you want more information regarding these databases, launch this:

     select * from pg_database;




June 2018 - Postgres Index Creation

Level (*) : 2
Topic (*) : Postgres


In postgres you have a table called T1 with a column called "data". Its type is JSONB.
Inside it, you have:
- a top level key called "customerinfo"
- a second level key called "cod"

Example taken from "data" column:
  "customerinfo": {
    "cod": "XWZLUX18S20D510K",
You have to create an index called T1_IDX on "cod" inside "customerinfo".
This must be done "online": while the people are using the database.
Write the SQL index creation.



May 2018 - Oracle SQL cursor problem

Level (*) : 2
Topic (*) : DBA


You are connected in an Oracle database 11.2.0.4.

Looking at the Oracle dynamic system views, you have to find 2 queries:
- one query in order to find the SELECTs with many version_count
- one query in order to find the reason why the SQL cursor of a known sql_id (i.e. a5w5hm8nn657b) is not shared



April 2018 - Postgres Streaming Replication

Level (*) : 2
Topic (*) : Postgres


You have 2 postgres database servers (postgresql version 10.3 in Linux machines) in Streaming Replication.
You are connected in both servers and you want to discover which is the master / primary database and which is the slave / secondary database (this accepts read-only transactions).

To be sure, you can get this information using many methods. Find some of these methods:
- one method using a Recovery Information Function
- one using a database system parameter
- one looking at the O.S. processes in the machines

And find which Recovery Information Functions can you use in order to check if now there is a lag between the data on the 2 databases.



March 2018 - Postgres Dblink

Level (*) : 3
Topic (*) : Postgres


You are working on a Postgresql cluster database, version 9.5.
Connected as USER_1 user on the DB_1 database, you must create a view called V_1 reading the T_2 table (owner USER_2, database DB_2, schema public).
DB_1 and DB_2 are in the same cluster database.

The describe of T_2 table is:
                 Table "public.t_2"
  Column |            Type             | Collation | Nullable | Default 
 --------+-----------------------------+-----------+----------+---------
  id     | character varying(64)       |           | not null | 
  data   | jsonb                       |           | not null | 
  time   | timestamp without time zone |           | not null | now()
You decide to create a dblink and use it.
The USER_1 is not a "super user" and you want to avoid to write the USER_2 password.
Then inside the query of the view, you decide to use the dblink_connect_u.

Write that query and all the needed steps.



February 2018 - Oracle SQL*Plus commands

Level (*) : 1
Topic (*) : DBA/Progr


You are connected on the db thru the SQL*Plus tool.
You try to write an Oracle procedure and you get an error:
  SQL > 
   1  CREATE OR REPLACE PROCEDURE pr_error
   2  BEGIN
   3   null;
   4* END;

  Warning: Procedure created with compilation errors.
How can you see the details of this error?
And which SQL*Plus command can you use in order to modify easily the procedure?

Solution

To see the error you must write SHOW ERROR:
  SQL > show error
  Errori in PROCEDURE PR_ERROR:

  LINE/COL ERROR
  -------- -----------------------------------------------------------------
  2/1      PLS-00103: Encountered the symbol "BEGIN" when expecting one of the following:
           ( ; is
           with authid as cluster compress order using compiled wrapped
           external deterministic parallel_enable pipelined result_cache
           The symbol "is" was substituted for "BEGIN" to continue.
To modify the procedure, you could use the SQL*Plus command called EDIT: it will open a text edit where you can easily work.



January 2018 - Oracle AWR report

Level (*) : 2
Topic (*) : DBA


You are connected on the db thru an Oracle client using a TNS connection.
You want to do an AWR report and, because of you are not in the server, you can't launch the awrrpt.sql script.
Which queries can you do in order to do the AWR report?



December 2017 - Table name

Level (*) : 1
Topic (*) : DBA


You are connected in Oracle 11g as SYS user.
You want to search some information regarding the table called T1, so you launch this:
  select *
  from dba_tables
  where table_name = 't1';
But you don't receive any result, why?

Solution

Because usually in the "DBA_" views you should search the information using the Uppercase, so you should launch:
  select *
  from dba_tables
  where table_name = 'T1';



November 2017 - Redo log switches

Level (*) : 3
Topic (*) : DBA


You want to discover how many redo log switches your db has done in the last 8 days.
You want the result in tabular format divided in day and hour.
For example, you want a result like this:
  DAY         00  01  02  03  04  05  06  07  08  09  10  11  12  13  14  15  16  17
  ----------- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --
  11/25, SAT  0   0   0   1   0   0   0   1   2   0   0   0   5   1   1   0   1   1
  11/26, SUN  0   0   0   15  0   0   0   0   4   1   6   5   5   2   0   1   6   3
  11/27, MON  1   0   0   20  0   0   0   0   1   4   6   1   3   9   0   5   5   1
  11/28, TUE  1   0   0   30  0   0   0   0   2   1   2   0   7   4   0   1   1   0
  11/29, WED  1   0   0   12  0   0   0   0   0   0   0   0   0   1   0   0   4   0
  11/30, THU  1   0   0   10  0   0   0   0   0   0   0   0   0   0   0   0   2   0
  12/01, FRI  0   0   0   3   0   0   0   0   0   1   9   4   1   0   1   20  10  0
  12/02, SAT  0   0   0   2   2   0   0   2   1   0   5   1   1   7   9   1   0   0
This means that today, 2 December, between 2pm and 3pm the db has done 9 redo log switches.
In the example above, last column is "17" only because of the website layout: the actual query should be done until the column "23".



October 2017 - Index monitoring

Level (*) : 3
Topic (*) : DBA


You want to discover if the index LORIS.PK_EMP is used or not.
In order to do this, connected as SYS, you launch the following SQL:
  ALTER INDEX loris.pk_emp
  MONITORING USAGE;
After this, still connected as SYS, in the V$OBJECT_USAGE view you don't see any record regarding to the PK_EMP index.
Why? And which query can you use in order to check if the index is used?



September 2017 - Oracle users

Level (*) : 1
Topic (*) : DBA


You are connected in an Oracle 11g database.
You have to find a query useful in order to know all the db users, their account status and when they have been created.
For example, you must have a result like this:
 USERNAME    ACCOUNT_STATUS    CREATED
 ----------- ----------------- ---------
 SYS         OPEN              30-MAR-10
 SCOTT       OPEN              30-MAR-10
 LORIS       OPEN              04-AUG-14
 SYSTEM      EXPIRED(GRACE)    30-MAR-10
 OUTLN       EXPIRED & LOCKED  30-MAR-10
 ...
Solution

Connected as SYS (or another privileged user) you could use the static system view called DBA_USERS:
  SELECT username, account_status, created
  FROM dba_users;



August 2017 - Combined query

Level (*) : 2
Topic (*) : DBA/Progr


In your db, you want to find all the tables with determinated "pattern names".
Example:
 SELECT owner, table_name
 FROM dba_tables
 WHERE table_name LIKE 'ICOLD%'
    OR table_name LIKE '%ROLE_DATA%';
You have to find the query that does the same thing writing only one WHERE condition (then without using the "OR").

Solution

You should use the regular expression called REGEXP_LIKE:
  SELECT owner, table_name
  FROM dba_tables
  WHERE REGEXP_LIKE (table_name, '^ICOLD|ROLE_DATA');



July 2017 - Table stats

Level (*) : 1
Topic (*) : DBA


In your db, under the LASSI schema, there is a table called T1 with about 1 million rows.
How to discover when has been done last statistics on this table?
If its statistics are old, how can you do new simple statistics of T1?

Solution

To find last statistics time, launch :
  SELECT table_name, last_analyzed
  FROM dba_tables
  WHERE table_name = 'T1' AND owner = 'LASSI';
To analyze the table, launch :
  exec dbms_stats.gather_table_stats ( 'LASSI', 'T1')
In this way, Oracle will do the statistics of the table T1 and its indexes.



June 2017 - Redo log problem

Level (*) : 2
Topic (*) : DBA


In your db you want to drop a redo log file:
  SQL > ALTER DATABASE DROP LOGFILE MEMBER 'C:\ORA\ADMIN\ORADATA\ORCL\REDO01.LOG';
  ALTER DATABASE DROP LOGFILE MEMBER 'C:\ORA\ADMIN\ORADATA\ORCL\REDO01.LOG'
  *
  ERROR at line 1:
  ORA-00361: cannot remove last log member C:\ORA\ADMIN\ORADATA\ORCL\REDO1.LOG for group 1.

You got it because of in your db the redo log files aren't multiplexed.
So you try this:
  18:14:19 ORCL > ALTER DATABASE DROP LOGFILE GROUP 1;
  ALTER DATABASE DROP LOGFILE GROUP 1
  *
  ERROR at line 1:
  ORA-01623: log 1 is current log for instance orcl (thread 1) - cannot drop
  ORA-00312: online log 1 thread 1: 'C:\ORA\ADMIN\ORADATA\ORCL\REDO01.LOG'

So why this happens? And how can you drop this redo log file?

Solution

You can't drop that redo log file because it is active.
You can have a confirmation of it looking at the view V$LOG: you'll see that the GROUP# 1 has the STATUS column with the value = CURRENT.

Then to drop it, you should do the following a redo log switch:
  ALTER SYSTEM SWITCH LOGFILE;
In this way its STATUS will change and you'll be able to drop it.



May 2017 - Oracle roles

Level (*) : 1
Topic (*) : DBA


Find a query in order to discover which Oracle users have the DBA role.

Solution

Connected as SYS (or another privileged user) you could use the static system view called DBA_ROLE_PRIVS:
  SELECT *
  FROM dba_role_privs 
  WHERE granted_role = 'DBA';



April 2017 - Oracle Exadata

Level (*) : 3
Topic (*) : DBA


You are connected in an Oracle exadata.
You have to find a query in order to know some info about its cells.

For example, you have to receive a result like this:
  KERNEL_VERSION                  MAKE_MODEL                                           N cells N Instances
  ------------------------------- ---------------------------------------------------- ------- -----------
  2.6.39-400.248.3.el6uek.x86_64  Oracle Corporation SUN SERVER X4-2L High Performance       3           2



March 2017 - Oracle 12c multitenant environment

Level (*) : 2
Topic (*) : DBA


You are connected in an Oracle 12c database with multitenant configuration: you are connected as SYS in the CDB$root.
You have to find the SQL*Plus commands or SELECTs in order to receive results like these:
  CON_NAME
  -------------
  CDB$ROOT

  NAME      OPEN_MODE
  --------- ----------------
  OR2017    READ WRITE

  INSTANCE_NAME    VERSION        STATUS
  ---------------- -------------- -------
  or2017           12.1.0.2.0     OPEN

  NAME        OPEN_MODE
  ----------- ----------
  PDB$SEED    READ ONLY
  PDB2017     MOUNTED
Solution

Connected in SQL*Plus, you can launch these:
  show con_name

  select name, open_mode from v$database;

  select instance_name, version, status from v$instance;

  select name, open_mode from v$pdbs;



February 2017 - Dates

Level (*) : 2
Topic (*) : Progr


You have a table like this:
 CREATE TABLE data 
  (aod DATE);
 
  insert into data values (to_date(20150331,'yyyymmdd'));
  insert into data values (to_date(20150630,'yyyymmdd'));
  insert into data values (to_date(20150930,'yyyymmdd'));
  insert into data values (to_date(20151231,'yyyymmdd'));
 
  insert into data values (to_date(20160331,'yyyymmdd'));
  insert into data values (to_date(20160630,'yyyymmdd'));
  insert into data values (to_date(20160930,'yyyymmdd'));
  insert into data values (to_date(20161231,'yyyymmdd'));
Then it contains the End Of the Quarter of different years.
You have to find a query in order to have a result like this:
  AOD         Q-1         EOY-1
  ----------- ----------- -----------
  31-MAR-2015 31-DEC-2014 31-DEC-2014
  30-JUN-2015 31-MAR-2015 31-DEC-2014
  30-SEP-2015 30-JUN-2015 31-DEC-2014
  31-DEC-2015 30-SEP-2015 31-DEC-2014
  31-MAR-2016 31-DEC-2015 31-DEC-2015
  30-JUN-2016 31-MAR-2016 31-DEC-2015
  30-SEP-2016 30-JUN-2016 31-DEC-2015
  31-DEC-2016 30-SEP-2016 31-DEC-2015
It means that for each AOD, you have to find :
- the end of the previous Quarter
- the end of the Year of the previous Year

Solution

You should use some datetime functions:
  SELECT aod,
         add_months(aod,-3) "Q-1",
         trunc(aod,'year')-1 "EOY-1"
  FROM data;


January 2017 - Column Indexed

Level (*) : 1
Topic (*) : DBA


You are connected on the db thru the SYS user.
You must find a query in order to know the COLUMN_NAMEs where you have the index called FACT1_IDX (under the LASSI schema).

Solution

Connected as SYS (or another privileged user) you could use the static system view called DBA_IND_COLUMNS:
  SELECT *
  FROM dba_ind_columns
  WHERE index_owner = 'LASSI' and 
        index_name = 'FACT1_IDX';




December 2016 - Space Used

Level (*) : 1
Topic (*) : DBA


You have to find a query in order to discover the total space (in MBytes) used from all the indexes of the database.

Solution
You should read the DBA_SEGMENTS view and use the "WHERE condition" in order to check all the indexes (partitioned and not):
  SELECT round(sum(bytes)/1024/1024) mb
  FROM dba_segments
  WHERE segment_type like 'INDEX%';



November 2016 - Different result sets

Level (*) : 3
Topic (*) : Prog


You have the table T1: it is "list partitioned" by the DATE1 column and "list sub-partitioned" by the FT_NO column.
Look at this:
 SELECT distinct ft_no
 FROM t1
 WHERE date1 = 20160912 AND
       le = 'LOR';

 FT_NO
 -----
   306

 SELECT *
 FROM t1
 WHERE date1 = 20160912 AND
       ft_no = 306;

 No rows.
 
Then using the first query seems to exist the FT_NO 306 with DATE1 = 20160912, using the other query no.
The sub-partitions on the table T1 are populate thru the EXCHANGE SUBPARTITION command and among the sub-partitions doesn't exists the value 306.

How is it possible this situation?
How can you fix it?



October 2016 - Find out the duplicated rows

Level (*) : 3
Topic (*) : DBA/Progr


Looking at the Oracle dictionary and given a table name (the table has no unique constraint and it is under the schema where you are connected), you have to find a query useful in order to find all the duplicated rows on that table.

Example:
This is the table containing duplicated rows:
 desc STG_TABLE

 Name      Type
 --------- ------------------
 C1        NUMBER
 C2        NUMBER
 C3        VARCHAR2(300)
Launching the query reading the dictionary, you must have a dynamic result like this:
 select C1, C2, C3, count(1)
 from STG_TABLE
 group by C1, C2, C3
 having count(1) = 1;
Then, launching it, you’ll find the duplicated rows.



September 2016 - Big Tables

Level (*) : 3
Topic (*) : DBA


You have to write a query in order to find the biggest tables (or partitions or subpartitions) under your schema.
The size of these objects must be more than 10GB and, in the result, you want to see also their compression information.

Result example:
 SEGMENT PARTITION_NAME SEGMENT_TYPE    COMPRESS COMPRESS_FOR COMPRESS COMPRESS_FOR    MB
 ------- -------------- --------------- -------- ------------ -------- ------------ -----
 D_ST                   TABLE                                                       19200
 F_DATA  TP_20160609_W  TABLE SUBPARTIT                       DISABLED              14406
 F_DATA  TP_20160728_D  TABLE SUBPARTIT                       DISABLED              12209
 F_VAR   F_20150219     TABLE PARTITION ENABLED  QUERY LOW                          10500



August 2016 - Sub-Partitioned Table

Level (*) : 3
Topic (*) : DBA


You have a composite partitioned table called FACT_TABLE created like this:
  CREATE TABLE FACT_TABLE
   ( DAY NUMBER,
     DESCR VARCHAR2(10),
	...
    )
  PARTITION BY LIST (DAY)
  SUBPARTITION BY LIST (DESCR)
  SUBPARTITION TEMPLATE (
    SUBPARTITION S1 VALUES ( 'SOL1' ),
    SUBPARTITION S2 VALUES ( 'SOL2' ),
    SUBPARTITION S3 VALUES ( 'SOL3' ) )
 ( PARTITION TP_20160101  VALUES (20160101),
   PARTITION TP_20160102  VALUES (20160102),
  ...);
After the table has been populated, you want to add a subpartition called S4 containing the value 'SOL4'.
This subpartition must be added only in the partitions with DAY >= 20160801.
Which is a fast way to do it?
Using the Oracle dictionary, how can you check the current subpartition template?
And write a script to modify the subpartition template: in it, you want to include the S4 subpartition.



July 2016 - Sub-Partitioned Indexes

Level (*) : 2
Topic (*) : DBA


You have an index called FACT_IDX1. This index is a local index in the composite-partitioned table called FACT1.
Looking at 2 different data dictionary views, you have to find the partitioning key columns and the subpartitioning key columns of FACT_IDX1.
Write the 2 queries in order to find out these info.

Solution
Connected as SYS or another “super user”:
 1. To get the partitioning key columns:

  SELECT *
  FROM dba_part_key_columns
  WHERE name = 'FACT_IDX1';

 2. To get the subpartitioning key columns:

  SELECT *
  FROM dba_subpart_key_columns
  WHERE name = 'FACT_IDX1';



June 2016 - Table DEGREE

Level (*) : 1
Topic (*) : DBA


You have to write a query in order to find, in the schemas starting with the letter "L", all the tables with degree of parallelism different than the value 1.

For instance, you want a result like this:
 DEGREE OWNER   TABLE_NAME
------- ------- ------------
      5 LORIS   FACT1
      4 LORIS   FACT12
      2 LAS     DIM4
Solution
Connected as SYS user or another “super user”, you could launch this query on the DBA_TABLES view:
  SELECT degree, owner, table_name
  FROM dba_tables a
  WHERE owner like 'L%' and 
        degree != 1;



May 2016 - Columns Size

Level (*) : 3
Topic (*) : DBA/Progr


Loading the tables (also big tables) on your db schema, you often get the error "ORA-12899: value too large for column ...".
In order to reduce the probability to have this error, you have to write a PL/SQL code that checks 20.000 rows in all the VARCHAR2 columns of your schema.
If they seem little, you have to enlarge them.

Example:
In your schema you have the TABLE_1 and TABLE_2 tables so launching that program you should get something like:
 TABLE_1
 ----------
 0,15

 TABLE_2
 ----------
 0,95
 
This means that in the TABLE_2 the column where it is easier to get the error ORA-12899 is a column where there is data long 95% compared to its definition.
Example: you have the column COL3 VARCHAR2(100) and in it there is data 95 chars long, so it is better to modify it in something like VARCHAR2(200).

Additional Step: As wrote, usually you should check every table using a condition like "WHERE rownum<20000", but if the table has a column called "DAY", in that table you must use a condition like "WHERE day>sysdate-180 and rownum<20000".



April 2016 - Table Columns

Level (*) : 2
Topic (*) : DBA


You have to write a query in order to find all the tables (and not views) that have a column called ERROR.
For instance, you want a result like this:
 OWNER   TABLE_NAME   COLUMN_NAME  DATA_TYPE  DATA_LENGTH
 ------- ------------ ------------ ---------- -----------
 LASSI   ST_ERROR     ERROR        VARCHAR2   200
 LORIS2  DIM_ERRORS   ERROR        VARCHAR2   600
 LORIS2  FACT_ERRORS  ERROR        VARCHAR2   2000

Solution
Usually you should use the view DBA_TAB_COLUMNS alone but in it there is also the columns of the views, so in this case you should launch something like this:
  SELECT tc.owner, tc.table_name, tc.column_name, tc.data_type, tc.data_length
  FROM     	dba_tab_columns tc,
        	dba_tables t
  WHERE tc.table_name = t.table_name and tc.owner = t.owner 
        and column_name in UPPER( '&col_name' ) 
  ORDER BY 1,2;



March 2016 - Interval Partition

Level (*) : 2
Topic (*) : DBA


You have the LASSI.T1 table and you want to know if it's "INTERVAL partitioned" or not.
Which query can you do in order to discover this information?

Solution
You should look at the DBA_PART_TABLES:
 SELECT owner, table_name, partitioning_type, subpartitioning_type, partition_count, interval
 FROM dba_part_tables
 WHERE owner = 'LASSI' and table_name = 'T1';
E.g.:
 OWNER  TABLE_NAME  PARTITION SUBPARTIT PARTITION_COUNT INTERVAL
 ------ ----------- --------- --------- --------------- --------------------------
 LASSI  T1          RANGE     NONE              1048575 NUMTOYMINTERVAL(1,'MONTH')
In this case you can see that the table T1 is “interval partitioned” because of the PARTITIONING_TYPE column is RANGE and the INTERVAL column is not null.



February 2016 - Segments drop problem

Level (*) : 3
Topic (*) : DBA


You have a tablespace where there are a lot of partitioned tables without statistics.
You try to drop these tables but often the DROP operation is very slow (about 5 minutes each partition) and their sessions have the event “optimizer stats update retry".

You check the number of extents of each segment and it is not very high.

Which are 2 workarounds of this issue?
And which Oracle MOS note talks about it?



January 2016 - SQL Plan execution

Level (*) : 2
Topic (*) : DBA/Progr


Just now you have launched the query with SQL_ID = '57hfsgdfs876la'.
You want to see its SQL execution plan thru this query:
 SELECT *
 FROM TABLE
  (dbms_xplan.display_awr('57hfsgdfs876la', null, null, 'ALL'));
But you don't receive any result.
What you could do in order to have a result?
And what you could do in a RAC?

Solution
To have a result, you need to do an AWR snapshot:
  exec DBMS_WORKLOAD_REPOSITORY.create_snapshot
If you have a RAC you should do the same from any instance.




December 2015 - db parameters

Level (*) : 3
Topic (*) : DBA


In this moment in your db a session with SID = 1976 is running.
You think that this session is running with some Oracle initialization parameters value different than the default value.
How can you find out if this is true?
And, in that session, which are the Oracle parameters with value different than the default values?



November 2015 - Info Connection

Level (*) : 2
Topic (*) : Prog/DBA


Thru a simple query on DUAL, you have to find the name of the instance and if you are connected thru a user with DBA privileges.

Find out this query.

Solution
You could use the function SYS_CONTEXT :

 SELECT
    SYS_CONTEXT('USERENV', 'INSTANCE_NAME') instance,
    SYS_CONTEXT('USERENV', 'ISDBA') amidba
 FROM dual;




October 2015 - Clean up a little part of the library cache

Level (*) : 3
Topic (*) : DBA


In a RAC, a query Q1 with sql_id=25ucwzczhs4la get always the same bad plan hash value.
You do some modification on the db and you want to be sure that the Oracle optimizer will do again the HARD PARSE of Q1.
Of course, you don't need to clean up (flush) the entire shared pool but you only want to purge the library cache part regarding that query.

How can you do it?
If the query has been launched only on the instance 1, can you do that purge being connected to the db thru the instance 2?




September 2015 - Execution Plan

Level (*) : 3
Topic (*) : Prog/DBA


A query Q1 has sql_id 0bffz5s6gflor and plan hash value 635035975.
This Q1 query is running in an Oracle RAC in this moment and you can't analyze it thru AWR/ADDM, you should need to do an AWR snapshot.
Instead of using the AWR snapshot, you have to find a query in order to keep the execution plan of this Q1.

E.g. the result of your query should be something like this:
 ID OPERATION                  OBJECT CARDINALITY   KB TEMP  COST TIME PStart PStop QBLOCK
--- -------------------------- ------ ----------- ---- ---- ----- ---- ------ ----- ------
  0 SELECT - Plan 635035975                                  5668
  1  PX COORDINATOR                                                                 SEL$1
  2   PX SEND QC (RANDOM)      :TQ107       20063  467       5668    3
  3    HASH GROUP BY                        20063  467   76  5668    3
  4     PX RECEIVE                          20063  467       5667    3
  5      PX SEND HASH          :TQ106       20063  467       5667    3
  6       BUFFER SORT                       20063  467       5668    3
  7        NESTED LOOPS                     20063  467       5667    3
  8         HASH JOIN                       20063  369       5667    3
etc...
 15      PARTITION LIST SINGLE               2857              12    1 3       3
 16       INDEX RANGE SCAN     FACT1         2857              12    1 KEY     KEY  SEL$1




August 2015 - Init parameters on RAC

Level (*) : 2
Topic (*) : DBA


You are working on a RAC db composed by 2 instances.
You want to check which Oracle initialization parameters are different between these instances. So you must write a query in order to get this information.

The query result must be something like this:
 NAME                  VALUE_I1                             VALUE_I2
 --------------------- -------------------------------- --------------------------------
 background_dump_dest  /opt/ora/diag/rdbms/db/db1/trace /opt/ora/diag/rdbms/db/db2/trace
 cluster_interconnects 192.168.10.1:192.168.10.2        192.168.10.3:192.168.10.4
 core_dump_dest        /opt/ora/diag/rdbms/db/db1/cdump /opt/ora/diag/rdbms/db/db2/cdump
 instance_name         db1                              db2
 instance_number       1                                2

Solution
Reading the GV$SYSTEM_PARAMETER views, you could use a query like this:

 select	i1.name,
	i1.value value_i1,
	i2.value value_i2
 from GV$SYSTEM_PARAMETER  i1,
      GV$SYSTEM_PARAMETER  i2
 where i1.inst_id = (select min(inst_id) from GV$SYSTEM_PARAMETER)  and
       i2.inst_id = (select max(inst_id) from GV$SYSTEM_PARAMETER)  and
       i1.num = i2.num and
       i1.value != i2.value
 order by 1;

Usually in a RAC, two instance have at least 8-10 parameters with different values.





July 2015 - Tablespace size History

Level (*) : 2
Topic (*) : DBA


You are in Oracle 11.2 and you want to know some stats about the size of tablespace TB1.
You want these stats referred to the last 2 weeks and you want to see them aggregated by day.
For example you want a result like this:
 DAY       TSNAME  SIZE_GB    MAXSIZE_GB    USEDSIZE_GB
 --------- ------- ---------- ------------- -----------
 09-JUL-15 TB1     3543          3700           3438
 10-JUL-15 TB1     3543          3700           3438
 11-JUL-15 TB1     3543          3700           3431
 12-JUL-15 TB1     3543          3700           3453
 13-JUL-15 TB1     3548          3860           3458
 14-JUL-15 TB1     3548          3860           3476
 15-JUL-15 TB1     3548          3860           3480
 16-JUL-15 TB1     3548          3860           3417
 17-JUL-15 TB1     3548          3860           3410
 18-JUL-15 TB1     3548          3860           3410
 19-JUL-15 TB1     3548          3860           3410
 20-JUL-15 TB1     3548          3860           3439
 21-JUL-15 TB1     3726          3860           3584
 22-JUL-15 TB1     3726          3860           3589
 23-JUL-15 TB1     3726          3860           3554
Find out the query in order to get these information.

Solution
You could use a query like this (in bold font what you should change according to your
tablespace and period to analyze) :

 select trunc(begin_interval_time) day,tsname, 
    round(max(tablespace_size*8192)/1024/1024/1024) size_gb, 
    round(max(tablespace_maxsize*8192)/1024/1024/1024) maxsize_gb,
    round(max(tablespace_usedsize*8192)/1024/1024/1024) usedsize_gb
 from (
    select
         s.snap_id, s.dbid, s.instance_number, s.startup_time, s.begin_interval_time, 
         s.end_interval_time, tablespace_size, tablespace_maxsize, tablespace_usedsize,
         tsname, contents, status, segment_space_management, extent_management, is_backup
    from  dba_hist_tbspc_space_usage u,
          dba_hist_snapshot s ,
          dba_hist_tablespace_stat t
    where u.snap_id=s.snap_id and u.dbid=s.dbid and u.snap_id=t.snap_id and t.dbid=s.dbid
      and u.tablespace_id=t.ts# and s.instance_number=t.instance_number
      and tsname = 'TB1'
      and begin_interval_time > sysdate-14 
    order by s.snap_id desc
    ) 
 group by trunc(begin_interval_time), tsname 
 order by trunc(begin_interval_time), tsname desc;



June 2015 - SQL*Plus Settings

Level (*) : 3
Topic (*) : DBA


In your pc, you have an Oracle client installed and in your desktop you create 2 files called dblor.cmd and dblassi.cmd .
These files are useful to launch the SQL*Plus connections to the DBs called DBLOR and DBLASSI.

When you launch these files, in SQL*Plus you don't want a prompt like this:
  SQL > 
But you want always prompted the time and the db where you are connected. Example:
 18:03:23 dblor >
And you want other settings like:
 set lin 180 pages 120
 alter session set nls_language='AMERICAN';
In order to do automatically these settings, you have to create or modify another file.

Explain these solutions:
- in the case that you are "well granted" on the PC
- in the case where you don't have good privileges on the PC



May 2015 - Dates in SQL*Plus

Level (*) : 1
Topic (*) : Prog/DBA


You are connected on the db thru SQL*Plus, you want to know what's the time (and the date), so you launch :
 SQL> select sysdate from dual;

 SYSDATE
 ---------
 02-GIU-15
But you see only the date and not the time.

To solve easily this issue, you have 2 solutions:
1. modification of the query
2. modification of the session
So, you please describe better both solutions.

Solution
1. You could modify the query using the function TO_CHAR

    SQL> SELECT to_char(sysdate,'yyyymmdd hh24.mi') date_time 
         FROM dual;

         DATE_TIME
    --------------
    20150602 21.37

2. You could modify the NLS_DATE_FORMAT on the session where you are connected using the
   ALTER SESSION command:

    SQL> alter session set nls_date_format = 'yyyymmdd hh24.mi';
    Session modified.

    SQL> SELECT sysdate 
         FROM dual;

           SYSDATE
    --------------
    20150602 21.37




April 2015 - Bind variables

Level (*) : 3
Topic (*) : Prog/DBA


You are in an Oracle 11g RAC and you have a query with bind variables running with SQL_ID 0kkhhb2w93cx1.
You want to know some information about its session and the values of its bind variables.

For example, you want to know something like :
 INST_ID  SID Plan_Hash_V SQL_ID        CHILD_ADDRESS    NAME  LAST_CAPTURED  Value
 ------- ---- ----------- ------------- ---------------- ----- -------------- -----
       2  285  2170058777 0kkhhb2w93cx1 0000000692F75980 :1    23/04 14.00    1
       2  285  2170058777 0kkhhb2w93cx1 0000000692F75980 :2    23/04 14.00    2
       2  285  2170058777 0kkhhb2w93cx1 0000000692F75980 :3    23/04 14.00    44506
Find the query in order to get these info.




March 2015 - Subquery Behaviour

Level (*) : 3
Topic (*) : Prog


You create a simple table called A:
  create table a (aa char);
  insert into a values ('Z');
  commit;
You try this query:

  SQL > select aa from dual;
  select aa from dual
         *
  ERROR at line 1:
  ORA-00904: "AA": invalid identifier
Of course, you receive an error because the column AA is not in the table DUAL.
But if you put the above query in a subquery, you don't receive any error :
  SQL > select * from a where aa in (select aa from dual);

  A
  -
  Z
How is it possible? Why Oracle doesn't give you an error?
How you should write the query in order to receive an error (during the SQL parsing) when a column in the subquery doesn't exists?



February 2015 - Your environment

Level (*) : 2
Topic (*) : DBA/Progr


You are connected on the db through a not "DBA" user (SYS, SYSTEM or someone else "strong").
You have to find 2 queries to know:
- the instance_name
- the db global name

Solution
 Instance_name : you could use the sys_context function :

	select sys_context ('USERENV', 'INSTANCE_NAME') 
	from dual;

 Database Global name : you could use the view global_name :

	select *
	from global_name;




January 2015 - EXCHANGE error

Level (*) : 3
Topic (*) : DBA/Progr


You want to exchange the table T2 with the subpartition SP_20141218_MI (inside the table T1) but you get an error:
 ALTER TABLE t1
 EXCHANGE SUBPARTITION sp_20141218_mi
 WITH TABLE t2
 INCLUDING INDEXES WITHOUT VALIDATION;
 Report errors:
 Error SQL: ORA-14278: column type or size mismatch in EXCHANGE SUBPARTITION
 14278. 00000 -  "column type or size mismatch in EXCHANGE SUBPARTITION"
 *Cause:    The corresponding columns in the tables specified in the
            ALTER TABLE EXCHANGE SUBPARTITION are of different type or size
 *Action:   Ensure that the two tables have the same number of columns
            with the same type and size.
So you check all the columns in both tables but you don't find any mismatch.
There is no difference also between their indexes.
Then what could be the reason? And what you can do to avoid this error?


(*)
Level:
1: easy solution
2: medium solution
3: hard (or long) solution

Topic:
DBA:
quiz usually suitable for Oracle DBAs
Progr: quiz usually suitable for PL/SQL or SQL Programmers
DBA/Progr: quiz suitable for Oracle DBAs and for Programmers
Postgres: regarding the Postgresql database

   

This website is not connected with Oracle Corporation or the official Oracle website.
Some words used here are registered trade marks of their owners.