(Part 1) New features in Oracle Database 12c : SQL Enhancements
Native SQL Support for Query Row Limits and Row Offsets
Oracle 12c has
introduced the row limiting clause to simplify Top-N queries and paging through
ordered result sets. The FETCH FIRST and OFFSET clauses provides native SQL
language support to limit the number of rows returned and to specify a starting
row for the return set.
[ OFFSET offset { ROW | ROWS } ] [ FETCH { FIRST | NEXT } [ { rowcount | percent PERCENT } ] { ROW | ROWS } { ONLY | WITH TIES } ]
Row
Limiting: Examples
SQL> SELECT employee_id, last_name FROM employees ORDER BY employee_id FETCH FIRST 5 ROWS ONLY;
SQL> SELECT employee_id, last_name FROM employees ORDER BY employee_id OFFSET 5 ROWS FETCH NEXT 5 ROWS ONLY;
SQL> SELECT employee_id, last_name, salary FROM employees ORDER BY salary FETCH FIRST 5 PERCENT ROWS ONLY;
SQL> SELECT employee_id, last_name, salary FROM employees ORDER BY salary FETCH FIRST 5 PERCENT ROWS WITH TIES;
Increased Size Limit for VARCHAR2, NVARCHAR2, and RAW Data Types
The maximum
size of the VARCHAR2, NVARCHAR2, and RAW data types has been increased from
4,000 to 32,767 bytes.
Beginning
with Oracle Database 12c, you can specify a maximum size of 32767 bytes for the
VARCHAR2, NVARCHAR2, and RAW data types. You can control whether your database
supports this new maximum size by setting the initialization parameter MAX_STRING_SIZE
as follows:
·
If
MAX_STRING_SIZE = STANDARD, then the size limits for releases prior to Oracle
Database 12c apply: 4000 bytes for the VARCHAR2 and NVARCHAR2 data types, and
2000 bytes for the RAW data type. This is the default.
·
If
MAX_STRING_SIZE = EXTENDED, then the size limit is 32767 bytes for the
VARCHAR2, NVARCHAR2, and RAW data types.
A VARCHAR2
or NVARCHAR2 data type with a declared size of greater than 4000 bytes, or a RAW
data type with a declared size of greater than 2000 bytes, is an extended data type.
Extended data type columns are stored out-of-line, leveraging Oracle's LOB
technology. The LOB storage is always aligned with the table. In tablespaces
managed with Automatic Segment Space Management (ASSM), extended data type
columns are stored as SecureFiles LOBs. Otherwise, they are stored as
BasicFiles LOBs. The use of LOBs as a storage mechanism is internal only.
Oracle
strongly discourages the use of BasicFiles LOBs as a storage mechanism.
BasicFiles LOBs not only impose restrictions on the capabilities of extended
data type columns, but the BasicFiles data type is planned to be deprecated in
a future release.
Note:
You can change the value of
MAX_STRING_SIZE from STANDARD to EXTENDED. However, you cannot change the value
of MAX_STRING_SIZE from EXTENDED to STANDARD.
Increasing the Maximum Size of VARCHAR2, NVARCHAR2, and RAW Columns in
a Non-CDB
- Shut down the database.
- Restart the database in UPGRADE mode.
- Change the setting of MAX_STRING_SIZE to EXTENDED.
- Run the rdbms/admin/utl32k.sql script. You must be connected AS SYSDBA to run the script.
- Restart the database in NORMAL mode.
- Shut down the PDB.
- Reopen the PDB in migrate mode. ALTER PLUGGABLE DATABASE pdb-name OPEN UPGRADE;
- Change the setting of MAX_STRING_SIZE in the PDB to EXTENDED.
- Run the rdbms/admin/utl32k.sql script in the PDB. You must be connected AS SYSDBA to run the script.
- Reopen the PDB in NORMAL mode.
To increase the maximum size of VARCHAR2, NVARCHAR2, and RAW columns in
an Oracle RAC database:
- Shut down all of the Oracle RAC database instances, except one.
- Restart the Oracle RAC database instance in UPGRADE mode.
- Change the setting of MAX_STRING_SIZE to EXTENDED.
- Run the rdbms/admin/utl32k.sql script in the Oracle RAC database instance. You must be connected AS SYSDBA to run the script.
- Restart the Oracle RAC database instance in NORMAL mode.
- Restart the other Oracle RAC database instances in NORMAL mode.
DEFAULT Values for Table Columns
· Default Values for Columns Based on Oracle Sequences
Default values for
columns can directly refer to Oracle sequences. Valid entries are
sequence.CURVAL and sequence.NEXTVAL. Providing the functionality to directly
refer to a sequence as a default value expression simplifies code development.
SQL> CREATE SEQUENCE test_seq;
SQL>
CREATE TABLE test_tab (id NUMBER DEFAULT test_seq.NEXTVAL,
description VARCHAR2(30));
SQL>
INSERT INTO test_tab (description) VALUES ('DESCRIPTION only');
SQL>
INSERT INTO test_tab (id, description) VALUES (122, 'ID=122 and DESCRIPTION');
SQL>
INSERT INTO test_tab (id, description) VALUES (NULL, 'ID=NULL and
DESCRIPTION');
SQL>
SELECT * FROM test_tab;
Notes:
During table creation, the sequence must
exist and you must have select privilege on.
The users performing inserts against the
table must have select privilege on the sequence, as well as insert privilege
on the table.
If the sequence is dropped after table creation,
subsequent inserts will error.
· DEFAULT Values for Columns on Explicit NULL Insertion
The DEFAULT
definition of a column can be extended to have the DEFAULT being applied for
explicit NULL insertion.
The DEFAULT clause
has a new ON NULL clause, which instructs the database to assign a specified
default column value when an INSERT statement attempts to assign a value that
evaluates to NULL.
SQL>
CREATE SEQUENCE test_seq2;
SQL>
CREATE TABLE test_tab2 (id NUMBER DEFAULT ON NULL test_seq2.NEXTVAL, description VARCHAR2(30));
SQL>
INSERT INTO test_tab2 (description) VALUES ('DESCRIPTION only');
SQL>
INSERT INTO test_tab2 (id, description) VALUES (NULL, 'NULL,DESCRIPTION');
SQL>
SELECT * FROM test_tab2;
· Metadata-Only DEFAULT Column Values for NULL Columns
The default values
of columns are maintained in the data dictionary for columns specified as NULL.
Adding new columns
with DEFAULT values no longer requires the default value to be stored in all
existing records. This not only enables a schema modification in sub-seconds
and independent of the existing data volume, it also does not consume any
space.
Oracle 11g introduced the concept of metadata-only default values.
Adding a NOT NULL column with a DEFAULT clause to an existing table involved
just a metadata change, rather than a change to all the rows in the table.
Queries of the new column were rewritten by the optimizer to make sure the
result was consistent with the default definition.
Oracle 12c takes this a step further, allowing metadata-only default
values of both mandatory and optional columns. As a result, adding a new column
with a DEFAULT clause to an existing table will be handled as a metadata-only
change, regardless of whether that column is defined as NOT NULL or not. This represents
both a space saving and performance improvement.
IDENTITY Columns
Table columns have
been enhanced to support the American National Standards Institute (ANSI) SQL
keyword IDENTITY.
The 12c database introduces the ability define an identity clause
against a table column defined using a numeric type. The syntax is show below.
GENERATED
[ ALWAYS | BY DEFAULT [ ON NULL ] ] AS IDENTITY [ ( identity_options ) ]
ALWAYS If you specify
ALWAYS, then Oracle Database always uses the sequence generator to assign a
value to the column. If you attempt to explicitly assign a value to the column
using INSERT or UPDATE, then an error will be returned. This is the default.
BY DEFAULT If you specify BY DEFAULT, then Oracle Database uses the sequence
generator to assign a value to the column by default, but you can also
explicitly assign a specified value to the column. If you specify ON NULL, then
Oracle Database uses the sequence generator to assign a value to the column
when a subsequent INSERT statement attempts to assign a value that evaluates to
NULL.
identity_options: use the
identity_options clause to configure the sequence generator. The
identity_options clause has the same parameters as the CREATE SEQUENCE
statement.
SQL>
CREATE TABLE test_tab1 (Id NUMBER GENERATED ALWAYS
AS IDENTITY, description VARCHAR2(30));
SQL>
CREATE TABLE test_tab2 (id NUMBER GENERATED BY
DEFAULT AS IDENTITY, description VARCHAR2(30));
SQL>
CREATE TABLE test_tab3 (id NUMBER GENERATED BY
DEFAULT ON NULL AS IDENTITY, description VARCHAR2(30));
The
[DBA|ALL|USER]_TAB_IDENTITY_COLS
views show information about identity columnsInvisible Columns
Invisible columns
are not seen unless specified explicitly in the SELECT list. Any generic access
of a table (such as a SELECT * FROM table or a DESCRIBE) will not show
invisible columns. You can make a column invisible during table creation or
when you add a column to a table, and you can later alter the table to make the
same column visible. You can also alter a table to make a visible column
invisible.
The idea of
invisible columns is similar to the idea of creating a view on a table while
leaving out the columns that you do not want the end-user to see.
·
The SELECT * syntax will
not display an INVISIBLE column. However, if you include an INVISIBLE column in
the select list of a SELECT statement, then the column will be displayed.
SQL> CREATE TABLE test_tab1 ( a
number, b number invisible, c number);
SQL> desc test_tab1
Name Null?
Type
----------------------------------------- --------
------
A NUMBER
C NUMBER
SQL> SELECT * FROM test_tab1;
A C
---------- ----------
1 3
SQL> SELECT a,b,c FROM test_tab1;
A B C
---------- ---------- ----------
1 2 3
·
You cannot implicitly
specify a value for an INVISIBLE column in the VALUES clause of an INSERT
statement. You must specify the INVISIBLE column in the column list.
SQL>
INSERT INTO test_tab1 VALUES (1,2,3);
INSERT
INTO test_tab1 VALUES (1,2,3)
*
ERROR
at line 1:
ORA-00913:
too many values
SQL> INSERT INTO test_tab1(a,b,c) VALUES (1,2,3);
1
row created.
SQL>
INSERT INTO test_tab1 VALUES (1,2);
1
row created.
·
You can configure SQL*Plus
to allow INVISIBLE column information to be viewed with the DESCRIBE command.
SQL>
SET COLINVISIBLE ON
SQL>
desc test_tab1
Name Null?
Type
-----------------------------------------
-------- ------
A NUMBER
C NUMBER
B (INVISIBLE) NUMBER
·
Restrictions
on VISIBLE and INVISIBLE Columns
INVISIBLE columns are not supported in external
tables, cluster tables, or temporary tables.
You cannot make a system-generated hidden
column visible.
The ALL_, DBA_, and
USER_TAB_COLS views show information about Hidden columns, query the HIDDEN_COLUMN and USER_GENERATED
columns of.
SQL>
Select TABLE_NAME,COLUMN_NAME,COLUMN_ID,HIDDEN_COLUMN,USER_GENERATED from
USER_TAB_COLS where TABLE_NAME='TEST_TAB1';
TABLE_NAME COLUMN_NAME
COLUMN_ID HID USE
---------------
--------------- ---------- --- ---
TEST_TAB1 C
2 NO YES
TEST_TAB1 B YES YES
TEST_TAB1 A
1 NO YES
Define PL/SQL Subprograms in a SQL Statement
With Oracle
Database 12c, you can now define PL/SQL
functions and procedures in the WITH clause of a subquery and then use them as
you would any other built-in or user-defined function. Example of In Line
PL/SQL Function in SQL query:
WITH
FUNCTION betwnstr (
string_in IN VARCHAR2, start_in IN PLS_INTEGER, end_in
IN PLS_INTEGER)
RETURN VARCHAR2
IS
BEGIN
RETURN (SUBSTR
(string_in, start_in, end_in - start_in + 1));
END;
SELECT betwnstr (last_name,1,5) FROM employees
So why would a developer want to copy logic from a PL/SQL function into
a SQL statement? To improve performance. When call own PL/SQL function in a SQL
statement, the SQL engine must perform a performance-affecting context switch
to the PL/SQL engine. Moving the code inside the SQL statement means that that
context switch no longer occurs.
Enhanced Online DDL Capabilities
Several schema
maintenance DDL operations no longer require blocking locks, making these
operations non-intrusive and transparent for online use. The improved schema
maintenance DDL operations are:
·
DROP INDEX ONLINE
·
DROP CONSTRAINT ONLINE
·
SET UNUSED COLUMN ONLINE
·
ALTER INDEX UNUSABLE ONLINE
·
ALTER INDEX [VISIBLE | INVISIBLE]
Removing internal
blocking locks enables simpler and more robust application development,
especially for application migrations. It avoids application disruptions for
many of the typical schema maintenance operations.
NO REDO for UNDO of Global Temporary Tables
Global Temporary Tables hold temporary non persistent data. The data in
Global Temporary Tables are either deleted after commit or kept until the
session is connected depending of the definition of the Global Temporary
Tables.(ON COMMIT PRESERVE OR DELETE ROWS ).
Global Temporary Tables They can be part of a transaction and also
support rollback and commit. For this to happen, Oracle DB has to maintain some
undo information for each transaction. And until now, any block change in UNDO
also generates some REDO. Since the data is not persistent by definition of
Global Temporary Tables, it looks like a waste of precious cycles generating
REDO.
In 12c, oracle can now write UNDO of Global Temporary Tables in temp
tablespace instead of UNDO tablespace. This way you can now avoid generation of
REDO for the UNDO, while still having the ability to rollback a
transaction.With this feature, some of the I/O contention is reduced for online
redo logfiles.
TEMP_UNDO_ENABLED determines whether transactions within a particular
session can have a temporary undo log. The default choice for database
transactions has been to have a single undo log per transaction. This
parameter, at the session level / system level scope, lets a transaction split
its undo log into temporary undo log (for changes on temporary objects) and
permanent undo log (for changes on persistent objects). When TEMP_UNDO_ENABLED
is set to true 0, this feature is enabled. The temporary undo feature is
enabled
Once the value of the parameter is set, it cannot be changed for the
lifetime of the session. If the session has temporary objects using temporary
undo, the parameter cannot be disabled for the session. Similarly, if the
session already has temporary objects using regular undo, setting this
parameter will have no effect.
SQL> alter system set temp_undo_enabled=TRUE;
SQL> CREATE GLOBAL TEMPORARY TABLE temp_table (col1
NUMBER,col2 NUMBER) ON COMMIT DELETE ROWS;
Table created.
SQL> set autotrace traceonly statistics
SQL> Insert into temp_table(col1,col2) select
object_id,object_id from dba_objects where rownum < 90001;
90000 rows created.
Statistics
----------------------------------------------------------
28
recursive calls
1275
db block gets
3136 consistent gets
0
physical reads
272 redo size
854 bytes sent via SQL*Net to client
899 bytes received via SQL*Net from client
3
SQL*Net roundtrips to/from client
1
sorts (memory)
0
sorts (disk)
90000 rows processed
SQL> update temp_table set col1=col2+1;
90000 rows updated.
Statistics
----------------------------------------------------------
11
recursive calls
95966 db block gets
473 consistent gets
0
physical reads
0 redo size
856 bytes sent via SQL*Net to client
834 bytes received via SQL*Net from client
3
SQL*Net roundtrips to/from client
1
sorts (memory)
0
sorts (disk)
90000 rows processed
Truncate Table Cascade
In Oracle 12c new word CASCADE can be specified for TRUNCATE command. If
you specify CASCADE, then Oracle Database truncates all child tables that
reference TABLE with an enabled ON DELETE referential constraint. This is a
recursive operation that will truncate all child tables, grandchild tables, and
so on, using the specified options.
SQL> create table test_tab_ma(col1 number primary key,
col2 number);
Table created.
SQL> create table test_tab_ch(col1 number primary key,
col2 number);
Table created.
SQL> alter table test_tab_ch add constraint child_fk
foreign key (col2) references test_tab_ma ON DELETE CASCADE;
Table altered.
SQL> insert into test_tab_ma values(1,1);
1 row created.
SQL> insert into test_tab_ch values(1,1);
1 row created.
SQL> commit;
Commit complete.
SQL> truncate table test_tab_ma CASCADE;
Table truncated.
SQL> select count(*) from test_tab_ma;
COUNT(*)
----------
0
SQL> select count(*) from test_tab_ch;
COUNT(*)
----------
0
No comments:
Post a Comment