<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>dbanotes.com &#187; Database Development</title>
	<atom:link href="http://www.dbanotes.com/category/database-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dbanotes.com</link>
	<description>Data expands knoweldge. Database technology is the tool we use.</description>
	<lastBuildDate>Sun, 01 Jan 2012 21:05:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>What is a Database?</title>
		<link>http://www.dbanotes.com/database-administration/what-is-a-database/</link>
		<comments>http://www.dbanotes.com/database-administration/what-is-a-database/#comments</comments>
		<pubDate>Sun, 01 Jan 2012 20:49:13 +0000</pubDate>
		<dc:creator>Michael Ritacco</dc:creator>
				<category><![CDATA[Database Administration]]></category>
		<category><![CDATA[Database Development]]></category>
		<category><![CDATA[Oracle Database]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://dbanotes.com/?p=159</guid>
		<description><![CDATA[For the technical purpose of database developers and administrators, a database is simply a collection of operating system files. Database files are normally stored in a proprietary binary format that can only be mounted by an instance of the relational database software that created them. The purpose of the database instance is to to manage and [...]]]></description>
			<content:encoded><![CDATA[<p>For the technical purpose of database developers and administrators, a database is simply a collection of operating system files.</p>
<p>Database files are normally stored in a proprietary binary format that can only be mounted by an instance of the relational database software that created them.</p>
<p>The purpose of the database instance is to to manage and deliver the data held within the database files for the users.</p>
<p>Modern Relational Database Management Systems (RDBMS) provide a declarative natural language abstraction layer called SQL to query the data held within the database, and provides <strong>ACID</strong> (<em><a title="Atomicity (database systems)" href="http://en.wikipedia.org/wiki/Atomicity_(database_systems)">atomicity</a>, <a title="Consistency (database systems)" href="http://en.wikipedia.org/wiki/Consistency_(database_systems)">consistency</a>, <a title="Isolation (database systems)" href="http://en.wikipedia.org/wiki/Isolation_(database_systems)">isolation</a>, <a title="Durability (database systems)" href="http://en.wikipedia.org/wiki/Durability_(database_systems)">durability</a></em>) based transactions as a key feature and benefit over other alternatives for data storage.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbanotes.com/database-administration/what-is-a-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Understanding Oracle 11g Constraints</title>
		<link>http://www.dbanotes.com/database-development/understanding-oracle-11g-constraints/</link>
		<comments>http://www.dbanotes.com/database-development/understanding-oracle-11g-constraints/#comments</comments>
		<pubDate>Mon, 26 Sep 2011 02:49:42 +0000</pubDate>
		<dc:creator>Contributing Author</dc:creator>
				<category><![CDATA[Database Development]]></category>
		<category><![CDATA[Oracle Database]]></category>
		<category><![CDATA[Oracle11g]]></category>

		<guid isPermaLink="false">http://www.dbanotes.com/?p=791</guid>
		<description><![CDATA[Introduction to Constraints Oracle constraints are defined as the rules to preserve the data integrity in the application. These rules are imposed on a column of a database table, so as to define the basic behavioral layer of a column of the table and check the sanctity of the data flowing into it. The data [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction to Constraints</h3>
<p>Oracle constraints are defined as the rules to preserve the data integrity in the application. These rules are imposed on a column of a database table, so as to define the basic behavioral layer of a column of the table and check the sanctity of the data flowing into it.</p>
<p>The data which violates the rule, fails to pass the constraint layer and oracle raises a predefined exception. The integrity layer can be further expanded programmatically through triggers and validation subprograms as per the application requirements and standards.</p>
<p>Constraints establish an underlying business nature of data like its uniqueness, its references, NULL behavior or domain oriented limits. The key milestones achieved by the usage of constraints are:</p>
<ul>
<li>Validate NULL property of the data</li>
<li>Validate uniqueness of the data</li>
<li>Validate referential integrity of the data</li>
</ul>
<div>
<h3>Constraint: Common Usage Guidelines</h3>
<p>Before I dig into complete understanding, I shall list the common usage guidelines of constraints.</p>
<ul>
<li>Constraints can be imposed on a single column or group of columns.</li>
<li>Constraints can be defined at column level or table level (except NOT NULL). ‘Column level’</li>
<li>Constraint definition means that the constraint would be associated directly and adjacently to the column. ‘Table level’ constraint definition starts once all the columns are already declared.</li>
<li>Constraints are not only effective while data creation, but also during data modification and deletion.</li>
<li>Constraints can be explicitly added on a table column using ALTER TABLE command</li>
<li>Constraints can be disabled if not required, especially during bulk loads; later they can be re-enabled.</li>
</ul>
<div>
<p>The figure below lists the types of constrains available in Oracle. We shall discuss each one of them in detail.</p>
<p><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/oracle11g-constraints.png"><img class="alignnone size-full wp-image-824" title="oracle11g-constraints" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/oracle11g-constraints.png" alt="" width="524" height="193" /></a></p>
<h3>NOT NULL Constraint</h3>
<p>The NOT NULL constraint restricts prevents the inclusion of NULL values in a column. If any NULL values are encountered during insertion, Oracle raises exception ‘ORA-01400: cannot insert NULL into [Column description]’. NOT NULL constraint is also active during update operation; violation of the rule results in exception ‘ORA-10407: cannot update [Column description] to NULL’.</p>
<div>
<h4>Syntax</h4>
<p>[COLUMN NAME] [DATA TYPE] [CONSTRAINT (CONSTRAINT NAME)] [NOT NULL] In the syntax, [CONSTRAINT (CONSTRAINT NAME)] are optional.</p>
<p>Examples:</p>
<p>&#8211;A table NN_DEMO is created with NOT NULL Constraint by name.&#8211;</p>
</div>
<pre class="brush: sql; gutter: true">CREATE TABLE NN_DEMO
(A NUMBER CONSTRAINT CONS_NN_DEMO_A NOT NULL);</pre>
<p class="brush: sql; gutter: true">Table created.</p>
<p>&#8211;A table NN_DEMO is created with NOT NULL Constraint without any name.&#8211;</p>
<pre class="brush:sql">CREATE TABLE NN_DEMO (A NUMBER NOT NULL);</pre>
<p class="brush:sql">Table created.</p>
<p>‘Not Null’ constraint can be defined only at the column level. However, there is no specific exception for the syntax violation in this case.</p>
<p>&#8211;A table NN_DEMO is created with NOT NULL at table level. However, there is no specific exception defined for this violation.&#8211;</p>
<pre class="brush:sql">CREATE TABLE NN_DEMO
(A NUMBER,
NAME VARCHAR2(100),
CONSTRAINT CONS_NN_DEMO_A NOT NULL(A))
/</pre>
<p class="brush:sql">CONSTRAINT CONS_NN_DEMO_A NOT NULL(A)) ERROR at line 4: ORA-00904: : invalid identifier</p>
<h3>UNIQUE Constraint</h3>
<p>As the name suggests, the constraint enforces barrier on the uniqueness of the data. It prevents duplication of the column data, but interestingly allows NULLs. It allows multiple NULLs during creation as well as modification of the column data.</p>
<h4>Syntax</h4>
<p><strong>Column Level:</strong><br />
COLUMN [data type] [CONSTRAINT &lt;name&gt;] [UNIQUE]. At column level, CONSTRAINT keyword and CONSTRAINT_NAME are optional.</p>
<p><strong>Table Level:</strong><br />
CONSTRAINT [constraint name] UNIQUE (column name).At table level, CONSTRAINT keyword and CONSTRAINT_NAME are mandatory.</p>
<h4>Examples</h4>
<p>&#8212;&#8211;Demonstrate column level definition of unique constraint&#8212;&#8211;</p>
<pre class="brush:sql">CREATE TABLE UNIQUE_DEMO_COL 2 (ID NUMBER, NAME VARCHAR2(100) UNIQUE);</pre>
<p>Table created.</p>
<p>&#8212;&#8211;Demonstrate Insertion of Unique Values in the table&#8212;&#8211;</p>
<pre class="brush:sql">INSERT INTO UNIQUE_DEMO_COL VALUES(1,'Name 1');</pre>
<p>1 row created.</p>
<p>&#8212;&#8211;Demonstrate Violation of Unique constraint&#8212;&#8211;</p>
<pre class="brush:sql">INSERT INTO UNIQUE_DEMO_COL VALUES(2,'Name 1');</pre>
<p>ERROR at line 1:ORA-00001: unique constraint (SCOTT.SYS_C0011341) violated</p>
<p>&#8212;&#8211;Demonstrate Table level definition of unique constraint&#8212;&#8211;</p>
<pre class="brush:sql">CREATE TABLE UNIQUE_DEMO (ID NUMBER, NAME VARCHAR2(100),
CONSTRAINT UN_UNIQUE_DEMO_ID UNIQUE(ID));</pre>
<p>Table created.</p>
<p>&#8212;&#8211;Display constraint metadata. Note the Index created&#8212;&#8211;</p>
<pre class="brush:sql">SELECT constraint_name, constraint_type, index_name from user_constraints
where table_name='UNIQUE_DEMO';</pre>
<p>&#8212;&#8211;Demonstrate association of an existing index with Unique Key&#8212;&#8211;</p>
<pre class="brush:sql">CREATE TABLE UNIQUE_DEMO 2 (ID NUMBER, NAME VARCHAR2(100));</pre>
<p>Table created.</p>
<p>&#8212;&#8211;Creating a Unique Index on ID column&#8212;&#8211;</p>
<pre class="brush:sql">CREATE UNIQUE INDEX IDX_UNIQUE_DEMO ON UNIQUE_DEMO(ID);</pre>
<p>Index created.</p>
<p>&#8212;&#8211;Addition of Unique constraint&#8212;&#8211;</p>
<pre class="brush:sql">ALTER TABLE UNIQUE_DEMO ADD CONSTRAINT UN_UNIQUE_DEMO_ID UNIQUE(ID);</pre>
<p>Table altered.</p>
<p>&#8212;&#8211;Verify the association of Index with the unique constraint&#8212;&#8211;</p>
<pre class="brush:sql">SELECT constraint_name, constraint_type, index_name from user_constraints
where table_name='UNIQUE_DEMO';</pre>
<h3>Primary Key Constraint</h3>
<p>As known by its name, Primary key is the ‘most premier’ column of a table. It strictly allows only unique and definite values in the column. Often it is referred to as the hybrid evolution of NOT NULL and UNIQUE, but with different logical and physical implications.</p>
<p>A column or group of columns of a table can be declared as Primary Key of the table. Composite primary keys can accommodate maximum of 32 columns. The declaration can be either made at Column level, Table level or using ALTER TABLE command.</p>
<p>Unlike other constraints, there can be one and only one Primary Key in a table. It can be either a single column or a composite primary key. Oracle raises the exception ‘ORA-02260: table can have only one primary key’, if one attempts to duplicate the primary key in a table.</p>
<h4>Syntax</h4>
<p><strong>Column level:</strong><br />
COLUMN [data type] [CONSTRAINT &lt;constraint name&gt; PRIMARY KEY] At column level, CONSTRAINT keyword and CONSTRAINT_NAME are optional.</p>
<p><strong>Table level:</strong><br />
CONSTRAINT [constraint name] PRIMARY KEY [column (s)]<br />
At column level, CONSTRAINT keyword and CONSTRAINT_NAME are mandatory. Addition of system generated Primary Key</p>
<pre class="brush:sql">ALTER TABLE [TABLE NAME] ADD PRIMARY KEY [COLUMN NAME]</pre>
<p>Above ALTER TABLE command creates a primary key with a system generated name of format SYS_CXX.</p>
<p>Similar to UNIQUE key, a unique b-tree index is always created whenever a primary key is created, with the same name as that of primary key constraint. Remember, a unique key cannot be promoted as the primary key in a table.</p>
<h4>Examples</h4>
<p>&#8212;&#8211;Demonstrate column level definition of Primary key constraint&#8212;&#8211;</p>
<pre class="brush:sql">CREATE TABLE PK_DEMO_1 2 (ID NUMBER PRIMARY KEY, NAME VARCHAR2(100));</pre>
<p>Table created.</p>
<p>&#8212;&#8211;Verify Primary key metadata from USER_CONSTRAINTS. Note that the GENERATED column denotes whether the constraint name has been SYSTEM generated or USER given&#8212;&#8211;</p>
<pre class="brush:sql">SELECT CONSTRAINT_NAME, INDEX_NAME, GENERATED
FROM USER_CONSTRAINTS
WHERE TABLE_NAME='PK_DEMO_1';</pre>
<p>&#8212;&#8211;Demonstrate Table level definition of Primary key constraint&#8212;&#8211;</p>
<pre class="brush:sql">CREATE TABLE PK_DEMO_2 2 ( ID NUMBER, NAME VARCHAR2(100),
CONSTRAINT PK_ID PRIMARY KEY(ID));</pre>
<p>Table created.</p>
<p>&#8212;&#8211;Verify Primary key metadata in USER_CONSTRAINTS. Note the different value for GENERATED column&#8212;&#8211;</p>
<pre class="brush:sql">SELECT CONSTRAINT_NAME, INDEX_NAME, GENERATED FROM USER_CONSTRAINTS WHERE TABLE_NAME='PK_DEMO_2';</pre>
<p>&#8212;&#8211;Demonstrate manual addition of Primary key using ALTER TABLE command&#8212;-</p>
<pre class="brush:sql">CREATE TABLE PK_DEMO_3 (ID NUMBER, NAME VARCHAR2(100));</pre>
<p>Table created.</p>
<pre class="brush:sql">ALTER TABLE PK_DEMO_3 ADD PRIMARY KEY (ID); Table altered.

SELECT CONSTRAINT_NAME, INDEX_NAME, GENERATED FROM USER_CONSTRAINTS WHERE TABLE_NAME='PK_DEMO_3';</pre>
<p>If an index already exists on a column and primary key is created on the same column, the primary key gets associated with the same index.</p>
<h3>Foreign Key Constraint</h3>
<p>Referential integrity is one of the key data features in a normalized database. Two tables can be connected through a column, where one table acts as Parent table while the other one is the child table.</p>
<p>The key column value set in the child table is always the subset of key column value set in the parent table, thus establishing the Parent Child relationship and obeys the referential integrity of data.</p>
<p>The key column in child table is known as Foreign Key i.e. its data references an ‘external or foreign’ set of values.</p>
<p>Now, Oracle follows certain guidelines to establish this relationship.</p>
<ol>
<li>The key column in the Parent table must be a Primary Key.</li>
<li>Multiple Child key columns can refer single Parent key column.</li>
<li>Though the Parent table key column is a Primary Key (which does not allows NULLs), foreign key can accommodate NULL values.</li>
<li>Oracle prevents the deletion of a Parent record, if its corresponding child exists in the child table.<br />
If the constraint is enforced with ON DELETE CASCADE option, then the child record would also be deleted.<br />
If the constraint is enforced with ON DELETE SET NULL option, then the child record would not be deleted, but their key column value would be set to NULL</li>
<li>Oracle prevents the creation of a Child record, for which value of key column does not exists in the Parent table.</li>
</ol>
<h4>Syntax</h4>
<p><strong>Column Level:</strong><br />
COLUMN [data type] [CONSTRAINT] [constraint name] [REFERENCES] [table name (column name)]</p>
<p>[CONSTRAINT] and [constraint name] are optional keywords during Column level declaration.</p>
<p><strong>Table level:</strong><br />
CONSTRAINT [constraint name] [FOREIGN KEY (foreign key column name) REFERENCES] [referenced table name (referenced column name)]</p>
<h4>Examples</h4>
<p>&#8212;&#8211;Creating a Parent table with a Primary key&#8212;&#8211;</p>
<p>CREATE TABLE FK_PARENT (PID NUMBER PRIMARY KEY);</p>
<p>Table created.</p>
<p>&#8212;&#8211;Verify the Primary Key constraint metadata&#8212;&#8211;</p>
<p>SELECT CONSTRAINT_NAME, INDEX_NAME FROM USER_CONSTRAINTS WHERE TABLE_NAME=&#8217;FK_PARENT&#8217;;</p>
<p>&#8212;&#8211;Querying the FK_PARENT table to check the value sets&#8212;&#8211;</p>
<pre class="brush:sql">SELECT * FROM FK_PARENT;</pre>
<p>&#8212;&#8211;Demonstrate Column level definition of foreign key constraint&#8212;&#8211;</p>
<pre class="brush:sql">CREATE TABLE FK_DEMO_1 (CID NUMBER REFERENCES FK_PARENT(PID));</pre>
<p>Table created.</p>
<p>&#8212;&#8211;Multiple foreign keys can refer the same Parent key&#8212;&#8211;</p>
<pre class="brush:sql">CREATE TABLE FK_DEMO_2 (CID NUMBER REFERENCES FK_PARENT(PID));</pre>
<p>Table created.</p>
<p>&#8212;&#8211;Verify the FK constraint metadata in USER_CONSTRAINTS view&#8212;&#8211;</p>
<pre class="brush:sql">SELECT TABLE_NAME, CONSTRAINT_NAME, R_CONSTRAINT_NAME, DELETE_RULE, GENERATED FROM USER_CONSTRAINTS WHERE TABLE_NAME IN ('FK_DEMO_1','FK_DEMO_2');</pre>
<p>&#8212;&#8211;Demonstrate table level definition of foreign key constraint&#8212;&#8211;</p>
<p>CREATE TABLE FK_DEMO_3 2 (CID NUMBER,NAME VARCHAR2(1000),<br />
CONSTRAINT FK_CID FOREIGN KEY (CID) REFERENCES FK_PARENT(PID));</p>
<p>Table created.</p>
<p>&#8212;&#8211;Demonstrate sample data insertion in the Child Table&#8212;&#8211;</p>
<p>INSERT INTO FK_DEMO_3 VALUES (1,&#8217;Insert 1&#8242;);</p>
<p>1 row created.</p>
<p>&#8212;&#8211;Demonstrate violation of foreign key constraint&#8212;&#8211;</p>
<p>INSERT INTO FK_DEMO_3 VALUES (20,&#8217;Insert 20&#8242;); INSERT INTO FK_DEMO_3 VALUES (20,&#8217;Insert 20&#8242;)</p>
<p>ERROR at line 1:<br />
ORA-02291: integrity constraint (SCOTT.FK_CID) violated &#8211; parent key not found</p>
<p>&#8212;&#8211;Exceptionally, NULL is an accepted value in foreign key&#8212;&#8211;</p>
<p>INSERT INTO FK_DEMO_3 VALUES (null,&#8217;Insert 20&#8242;); 1 row created.</p>
<h3>CHECK Constraint</h3>
<p>Till now, we had discussed the constraints which mentor the nature of data flowing into a table column. Now we would see upon the CHECK constraint which monitors the physical data to enforce domain integrity rule on a column.</p>
<p>The CHECK constraint logically fixes the column value by using expressions. If the incoming value satisfies the condition in the expression, it passes through for insertion; in opposite cases, constraint violation exception is raised.</p>
<p>The CHECK constraint expression must use the columns of the same table. Like other constraints, CHECK constraint specification can either be made inline at the column level or can be given at the table level.</p>
<p><strong>Syntax</strong></p>
<p><strong>Column level:</strong><br />
COLUMN [data type] CONSTRAINT [name] [CHECK (condition)]<br />
[CONSTRAINT] and [constraint name] are optional keywords during Column level declaration.</p>
<p><strong>Table level:</strong><br />
CONSTRAINT [name] CHECK (condition)</p>
<p>Additionally, CHECK constraint specification has below restrictions while its specification.</p>
<ul>
<li>Subqueries expressions cannot be used within CHECK expression</li>
<li>Pseudo columns CURRVAL, NEXTVAL, LEVEL, or ROWNUM are not allowed since their value is dynamic</li>
<li>User defined functions and Deterministic functions like CURRENT_DATE, CURRENT_TIMESTAMP, DBTIMEZONE, LOCALTIMESTAMP,SESSIONTIMEZONE,SYSDATE, SYSTIMESTAMP, UID, USER, and USERENV</li>
<li>Composite data types or collections</li>
</ul>
<h4>Examples</h4>
<p>&#8212;&#8211;Demonstrate Column level definition of Check constraint&#8212;&#8211;</p>
<pre class="brush:sql">CREATE TABLE CK_DEMO_1 (ID NUMBER, NAME VARCHAR2(100), EMPLOYED VARCHAR2(1) CHECK (EMPLOYED IN ('Y','N')) );</pre>
<p>Table created.</p>
<p>&#8212;&#8211;Verify Check constraint metadata in USER_CONSTRAINTS table&#8212;&#8211;</p>
<pre class="brush:sql">SELECT constraint_name, search_condition, generated from user_constraints
where table_name='CK_DEMO_1';</pre>
<p>&#8212;&#8211;Demonstrate the insertion</p>
<pre class="brush:sql">INSERT INTO CK_DEMO_1 VALUES (1, 'JOHN','Y');</pre>
<p>1 row inserted.</p>
<p>&#8212;&#8211;Demonstrate the violation</p>
<pre class="brush:sql">INSERT INTO CK_DEMO_1 VALUES 2 (2, 'KATE','A');</pre>
<p>￼ERROR at line 1:<br />
ORA-02290: check constraint (SCOTT.SYS_C0011477) violated</p>
<p>&#8212;&#8211;Demonstrate table level definition of foreign key constraint&#8212;&#8211;</p>
<pre class="brush:sql">CREATE TABLE CK_DEMO_1 (ID NUMBER, NAME VARCHAR2(100), EMPLOYED VARCHAR2(1),
CONSTRAINT CK_EMPLOYED_YN CHECK (EMPLOYED IN ('Y','N')) );</pre>
<p>Table created.</p>
<p>&#8212;&#8211;Demonstrate the restriction of UDF in Check constraint expressions&#8212;&#8211;</p>
<pre class="brush:sql">CREATE OR REPLACE FUNCTION CHECK_RANGE RETURN NUMBER
IS
BEGIN
RETURN 100;
END;
CREATE TABLE CK_DEMO_FUN 2 (ID NUMBER,
NAME VARCHAR2(100), AGE NUMBER CHECK (AGE &lt; CHECK_RANGE));
)</pre>
<p>ERROR at line 5:<br />
ORA-02438: Column check constraint cannot reference other columns</p>
<h3>Constraints: Common Operations</h3>
<h3>Dropping a Constraint</h3>
<p>A constraint can be dropped from a table using ALTER TABLE command. Syntax for the same is as below</p>
<pre class="brush:sql">ALTER TABLE [TABLE NAME] DROP CONSTRAINT [CONSTRAINT NAME]</pre>
<p>For Example, dropping the CHECK constraint from CK_DEMO_1 would be done as below. SQL&gt; alter table ck_demo_1 drop constraint ck_employed_yn;</p>
<p>Table altered.</p>
<h3>Enabling/Disabling a Constraint</h3>
<p>At times, a constraint can be enabled or disabled. Usually, such activities are carried out during data loading from legacy systems. We shall take up a small scenario to illustrate it.</p>
<p>&#8212;&#8211;Verify the data in CK_DEMO_1&#8212;&#8211;</p>
<pre class="brush:sql">SELECT * FROM CK_DEMO_1;</pre>
<p>&#8212;&#8211;Disable the CHECK constraint in table CK_DEMO_1&#8212;&#8211;</p>
<pre class="brush:sql">ALTER TABLE CK_DEMO_1 DISABLE CONSTRAINT CK_EMPLOYED_YN;</pre>
<p>Table altered.</p>
<p>&#8212;&#8211;Inserting a sample data which violates the CHECK constraint expression. The data is successfully inserted&#8212;&#8211;</p>
<pre class="brush:sql">INSERT INTO CK_DEMO_1 VALUES (3, NEL','A');</pre>
<p>1 row created.</p>
<p>&#8212;&#8211;Verify the above insertion in the table&#8212;&#8211;</p>
<pre class="brush:sql">SELECT * FROM CK_DEMO_1;</pre>
<p>&#8212;&#8211;Re-enabling the CHECK constraint raises exception, since the table has the violating data&#8212;&#8211;</p>
<pre class="brush:sql">ALTER TABLE CK_DEMO_1 ENABLE CONSTRAINT CK_EMPLOYED_YN;</pre>
<p>ORA-02293: cannot validate (SCOTT.CK_EMPLOYED_YN) &#8211; check constraint violated</p>
<p>&#8212;&#8211;Deleting the violating data from the CK_DEMO_1 table&#8212;&#8211;</p>
<pre class="brush:sql">DELETE FROM CK_DEMO_1 WHERE EMPLOYED='A';</pre>
<p>ERROR at line 1: ￼1 row deleted.</p>
<p>&#8212;&#8211;Enabling the constraint successfully&#8212;&#8211;</p>
<pre class="brush:sql">ALTER TABLE CK_DEMO_1 ENABLE CONSTRAINT CK_EMPLOYED_YN; Table altered.</pre>
<h3>Conclusion: Seeing the constraints ahead</h3>
<p>Constraints are the first step to impose the integrity rules on the data. They not only check the sanctity of the data, but also define a high level data behavioral layer.</p>
<p>Later versions of Oracle have also introduced data types (POSITIVEN, SIMPLE_INTEGER) which have NOT NULL behavior exhibited in their primitive definitions. These recent developments have moved NOT NULL to an obsolete category.</p>
<p>Over the years, Primary key has emerged to be an important aspect of table designing exercise and data storage philosophies.</p>
<p>The paper covers the basics of constraints available in database. I hope the readers to try their hands out with more concrete scenarios of constraints.</p>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.dbanotes.com/database-development/understanding-oracle-11g-constraints/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Oracle 11g Pivot Functions</title>
		<link>http://www.dbanotes.com/database-development/oracle-11g-pivot-functions/</link>
		<comments>http://www.dbanotes.com/database-development/oracle-11g-pivot-functions/#comments</comments>
		<pubDate>Sun, 04 Sep 2011 21:15:51 +0000</pubDate>
		<dc:creator>Michael Ritacco</dc:creator>
				<category><![CDATA[Database Development]]></category>
		<category><![CDATA[Oracle Database]]></category>
		<category><![CDATA[Oracle11g]]></category>

		<guid isPermaLink="false">http://www.dbanotes.com/wp/?p=714</guid>
		<description><![CDATA[Data mining, processing and its presentation are the key activities in a production environment. The views and analytic integrals of the information through multiple spectacles can help in better business forecasting and strategic implementations. This innovative exercise of creating varying views might involve aggregation, data transposing, or cross tabulation reporting. Data Pivoting, one of the [...]]]></description>
			<content:encoded><![CDATA[<p>Data mining, processing and its presentation are the key activities in a production environment. The views and analytic integrals of the information through multiple spectacles can help in better business forecasting and strategic implementations. This innovative exercise of creating varying views might involve aggregation, data transposing, or cross tabulation reporting.</p>
<p>Data Pivoting, one of the ways to implement and achieve above purposes, can evolve multiple views with varying combinations of columns as rows and vice versa.<br />
Oracle supports data pivoting through Pivot aggregate operators, which can be used in SQL statements. Oracle 11g introduced two new keywords PIVOT and UNPIVOT in support of this operation. While the PIVOT operation refers to the conversion of rows into columns, UNPIVOT implies the reverse operation.</p>
<p>Prior to the induction of the Pivot operator, such cross tabular reports used to get generated through workaround SQLs using self joins. While it achieved the purpose in small database, it proved to be nightmare in large enterprise data warehouse database systems. Performance used to be the most cursed area where high volume of data was multi folded on self joins.</p>
<h3>PIVOT</h3>
<p>Pivot operator transposes an aggregated row of a table into a column. The distinct row values become the columns in the output and aggregated column value places itself under the appropriate pivoted column. The syntax of Pivot operator is as below.</p>
<div class="woo-sc-box normal   ">
<p>SELECT [COLUMN(S)]<br />
FROM [TABLE NAME]<br />
PIVOT [XML]<br />
( pivot_clause<br />
pivot_for_clause<br />
pivot_in_clause )<br />
WHERE [CONDITIONS]</div>
<p><em>Syntax explanation</em></p>
<ul>
<li>[XML] – optional clause to convert the pivoted data into XML</li>
<li>PIVOT_CLAUSE uses an aggregate function on one of the column of the table. This is the data which places itself against the pivoted column accordingly.</li>
<li>PIVOT_FOR_CLAUSE and PIVOT_IN_CLAUSE specify a column and its distinct values which are to be pivoted. In a transposed report, the distinct values of the pivoted column appear as the header in the output. Both are mandatory clauses, so distinct values of the column must be in hand.</li>
</ul>
<h3>Examples and illustrations</h3>
<p>A retail firm maintains the track of customer sales in three products (Product_A, Product_B, Product_C) for the months of January, February and March. The sales data is collected for three privileged customers C1, C2 and C3.</p>
<p>The relational table CUST_SALES stores the data for each customer against each product in each month. The table data is as below</p>
<p><strong><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/Oracle-11g-Pivot-functions9.jpg"><img class="alignnone size-full wp-image-747" title="Oracle 11g Pivot functions9" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/Oracle-11g-Pivot-functions9.jpg" alt="" width="622" height="237" /></a></strong></p>
<p>Now, we shall pivot the table data to give a new analytic dimension. Refer the below cases.</p>
<h3>Case 1: Customer sales in each month for each product</h3>
<p>PRODUCT_ID column of the CUST_SALES table has been pivoted in the below query. Now observe the beauty and intelligence of Pivot operator; it retains the positions of remaining columns (i.e. CUSTOMER_ID and MONTH) and formats the sales data in accordance with the pivoted column. Also note that the PRODUCT_ID is no more a column but its distinct values i.e. Prod A, Prod B,</p>
<p>Prod C are transposed as the column header in the query output.</p>
<div class="woo-sc-box normal   ">SELECT * FROM CUST_SALES<br />
PIVOT<br />
(<br />
SUM(SALES)<br />
FOR PRODUCT_ID<br />
IN (&#8216;Prod A&#8217;, &#8216;Prod B&#8217;, &#8216;Prod C&#8217;)<br />
)</div>
<p>In the above query, note the aggregated function, FOR clause and IN clause of Pivot operator.</p>
<p><strong><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/Oracle-11g-Pivot-functions8.jpg"><img class="alignnone size-full wp-image-746" title="Oracle 11g Pivot functions8" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/Oracle-11g-Pivot-functions8.jpg" alt="" width="663" height="165" /></a></strong></p>
<p>Now, check the Explain Plan of the pivot query.</p>
<p>The plan generated shows the pivot specific optimization of the SQL query in HASH GROUP BY function.</p>
<p><strong><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/Oracle-11g-Pivot-functions7.jpg"><img class="alignnone size-full wp-image-745" title="Oracle 11g Pivot functions7" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/Oracle-11g-Pivot-functions7.jpg" alt="" width="662" height="197" /></a></strong></p>
<h3>Case 2: Customer sales for each product in each month</h3>
<p>Now, changing the angle of perception by replacing PRODUCT_ID with the MONTH at the header level. Distinct values of MONTH appear as column in the query output.<br />
<div class="woo-sc-box normal   ">SELECT * FROM CUST_SALES<br />
PIVOT<br />
(<br />
SUM(SALES)<br />
FOR MONTH<br />
IN (&#8216;Jan&#8217; as &#8220;January&#8221;, &#8216;Feb&#8217; as &#8220;February&#8221;, &#8216;Mar&#8217; as &#8220;March&#8221;)<br />
)</div></p>
<p>In the query, note that if the value(s) of the pivoted column had to have a customized title for better readability, the same can be specified using “AS” keyword. In the CUST_SALES table, abbreviated values of the MONTH column have been replaced with their complete names.</p>
<p><strong><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/Oracle-11g-Pivot-functions6.jpg"><img class="alignnone size-full wp-image-744" title="Oracle 11g Pivot functions6" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/Oracle-11g-Pivot-functions6.jpg" alt="" width="657" height="143" /></a></strong></p>
<p>Similarly, if MONTH column has to be made as key analysis column, CUSTOMER can be raised to column header. Sales data would automatically find its place in the new matrix.<br />
<div class="woo-sc-box normal   ">SELECT * FROM CUST_SALES<br />
PIVOT<br />
(<br />
SUM(SALES)<br />
FOR CUSTOMER_ID<br />
IN (&#8216;Adam&#8217;, &#8216;Jones&#8217;, &#8216;Kanes&#8217;)<br />
)<br />
ORDER BY DECODE(MONTH,&#8217;Jan&#8217;,1,&#8217;Feb&#8217;,2,&#8217;Mar&#8217;,3)</div></p>
<p><strong><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/Oracle-11g-Pivot-functions5.jpg"><img class="alignnone size-full wp-image-743" title="Oracle 11g Pivot functions5" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/Oracle-11g-Pivot-functions5.jpg" alt="" width="657" height="148" /></a></strong></p>
<h3>UNPIVOT</h3>
<p>Unpivot operator functions just at the opposite principle of Pivot. Very rare occasions exist when an element is created along with its anti counterpart. Unpivot brings data in pivoted form back to the normal form. Its syntax and usage is same as that of Pivot.<br />
<em>Syntax</em><br />
<div class="woo-sc-box normal   ">UNPIVOT<br />
( unpivot_clause<br />
unpivot_for_clause<br />
unpivot_in_clause )</div></p>
<p>Here, UNPIVOT_CLAUSE is not an aggregated column, but an arbitrary column name, which appears in the query to accommodate the values of unpivoted columns.<br />
UNPIVOT_FOR_CLAUSE is also an arbitrary column name to hold the unpivoted columns values.<br />
UNPIVOT_IN_CLAUSE defines the distinct values of the columns to be unpivoted.</p>
<h3>Illustration</h3>
<p>CUST_SALES_MONTH is the table which holds the data in binary format, to denote whether a product has been consumed by a customer in a specific month or not. It looks more like a spreadsheet.</p>
<p><strong><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/Oracle-11g-Pivot-functions4.jpg"><img class="alignnone size-full wp-image-742" title="Oracle 11g Pivot functions4" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/Oracle-11g-Pivot-functions4.jpg" alt="" width="657" height="334" /></a></strong></p>
<p>Now, Unpivot operator can be used here to break the CUST_SALES_MONTH table into rows to show only CUSTOMER_ID, PRODUCT_ID, MONTH and its corresponding sales. Check the query below:<br />
<div class="woo-sc-box normal   ">select * from cust_sales_month<br />
unpivot<br />
(<br />
month_count<br />
for month<br />
in (&#8220;January&#8221;,&#8221;February&#8221;,&#8221;March&#8221;)<br />
)<br />
order by customer_id, product_id<br />
/</div></p>
<p>Now observe the output.</p>
<p><strong><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/Oracle-11g-Pivot-functions3.jpg"><img class="alignnone size-full wp-image-741" title="Oracle 11g Pivot functions3" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/Oracle-11g-Pivot-functions3.jpg" alt="" width="663" height="320" /></a></strong></p>
<p>For each customer and product, the „month‟ column is repetitive to list the corresponding „month_count‟ value. The UNPIVOT_FOR_CLAUSE and UNPIVOT_IN_CLAUSE are responsible to have columns of the table listed as value under MONTH column.</p>
<p>The UNPIVOT_CLAUSE (here, MONTH_COUNT) specifies fetches the corresponding value of the unpivoted column and places at correct position alongside its customer_id, product_id and month. This demonstrates the power intelligence of UNPIVOT operator.</p>
<p>The explain plan for the above query shows the UNPIVOT operation for the conversion of column headers as row values.</p>
<p><strong><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/Oracle-11g-Pivot-functions2.jpg"><img class="alignnone size-full wp-image-740" title="Oracle 11g Pivot functions2" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/Oracle-11g-Pivot-functions2.jpg" alt="" width="684" height="369" /></a></strong></p>
<h3 align="LEFT">Applications of Pivoting</h3>
<p align="LEFT">We have already seen the benefits of Pivot operator. On need basis, data can be pivoted in the required format. Still, from developers perspective, I would mention an application derived from the previous ones.</p>
<p align="LEFT"><strong>Conversion of columns to rows and vice versa.</strong></p>
<p align="LEFT">For example, you have a test data of known values, which is required in rows. One way is to combine all the separate SELECT statements using UNION operator as below:<br />
<div class="woo-sc-box normal   ">SELECT S1, „Cricket‟ FROM DUAL<br />
UNION<br />
SELECT S2, „Football‟ FROM DUAL<br />
UNION<br />
SELECT S3, „Badminton‟ FROM DUAL<br />
UNION<br />
SELECT S4, „Tennis‟ FROM DUAL<br />
&#8216;S &#8216;CRICKET&#8217; </div><br />
<div class="woo-sc-box normal   ">&#8211; &#8212;&#8212;&#8212;<br />
S1 Cricket<br />
S2 Football<br />
S3 Badminton<br />
S4 Tennis </div></p>
<p align="LEFT">Unpivot operator eases this overhead in efficient and simple way. Check the query below.<br />
<div class="woo-sc-box normal   ">WITH C AS<br />
(SELECT &#8216;Cricket&#8217; s1, &#8216;Football&#8217; s2, &#8216;Badminton&#8217; s3, &#8216;Tennis&#8217; s4<br />
FROM DUAL)<br />
SELECT *<br />
FROM C<br />
UNPIVOT<br />
( VALUE<br />
FOR STRING IN (S1,S2,S3,S4)<br />
)</div></p>
<p>&nbsp;</p>
<p><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/Oracle-11g-Pivot-functions1.jpg"><img class="alignnone size-full wp-image-739" title="Oracle 11g Pivot functions1" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/Oracle-11g-Pivot-functions1.jpg" alt="" width="657" height="113" /></a></p>
<h3>Conclusion</h3>
<p>Pivot and Unpivot have made an impactful entry into the SQL language. They have set aside the cumbersome work around solutions and efficiently transpose the data of a relational table.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbanotes.com/database-development/oracle-11g-pivot-functions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introduction to Oracle 11g Cursors</title>
		<link>http://www.dbanotes.com/database-development/introduction-to-oracle-11g-cursors/</link>
		<comments>http://www.dbanotes.com/database-development/introduction-to-oracle-11g-cursors/#comments</comments>
		<pubDate>Thu, 23 Jun 2011 20:21:17 +0000</pubDate>
		<dc:creator>Contributing Author</dc:creator>
				<category><![CDATA[Database Development]]></category>
		<category><![CDATA[Oracle Database]]></category>
		<category><![CDATA[Oracle11g]]></category>

		<guid isPermaLink="false">http://www.dbanotes.com/?p=685</guid>
		<description><![CDATA[Cursors are one of the most common and fundamental terms in the database terminology. It is one of the core database programming concepts, which forms a basic unit of execution of SQL statement. A cursor is a pointer, which points towards a pre allocated memory location in the SGA. For transparent understanding, it is a [...]]]></description>
			<content:encoded><![CDATA[<p>Cursors are one of the most common and fundamental terms in the database terminology. It is one of the core database programming concepts, which forms a basic unit of execution of SQL statement.</p>
<p>A cursor is a pointer, which points towards a pre allocated memory location in the SGA. For transparent understanding, it is a handle or gateway adopted by Oracle to execute a SQL query. The memory location to which it points is known as Context area. Oracle associates every SELECT statement with a cursor to hold the query information in this context area.</p>
<p>Cursor follows a defined execution cycle to execute the SQL statement associated with it. The article describes the Oracle cursors and their usage.</p>
<p>There are two types of cursors: Implicit cursors and explicit cursors.</p>
<h3>Implicit Cursors</h3>
<p>Oracle server processes every SQL statement in a PL/SQL block as an implicit cursor. All the DML statements (INSERT, UPDATE or DELETE) and SELECT query with INTO or BULK COLLECT clauses are candidates for implicit cursors.</p>
<p>Whenever a SQL statement is executed, Oracle automatically allocates a memory area (known as context area) in Oracle database PGA i.e. Process Global Area. This allocated memory space is the query work area which holds the query related information.</p>
<p>For implicit cursor, the complete execution cycle is internally handled and maintained by the oracle server. For developers, implicit cursor appears to be an abstract concept. Only thing which is physically available and visible to them is the cursor status flags and information. Cursor attributes reveal the cursor related information and status. Following are the cursor attributes available</p>
<ul>
<li><strong>SQL%ROWCOUNT</strong> – Number of rows returned/changed in the last executed query. Applicable for SELECT as well as DML statement</li>
<li><strong>SQL%ISOPEN</strong> – Boolean TRUE if the cursor is still open, else FALSE. For implicit cursor it is FALSE only</li>
<li><strong>SQL%FOUND</strong> – Boolean TRUE, if the cursor fetch points to a record, else FALSE</li>
<li><strong>SQL%NOTFOUND</strong> – Inverse of SQL%FOUND. The flag is set as FALSE when the cursor pointer does not point to a record in the result set.</li>
</ul>
<p>These attributes are set at the different stages of execution cycle and retained in the context area.</p>
<p>Example Code [1]: The PL/SQL block below shows an implicit cursor created by SELECT statement.</p>
<div class="woo-sc-box normal   ">DECLARE<br />
L_SAL NUMBER;<br />
BEGIN<br />
SELECT SALARY<br />
INTO L_SAL<br />
FROM EMPLOYEES<br />
WHERE EMPLOYEE_ID=110;<br />
DBMS_OUTPUT.PUT_LINE(‘Salary for KING is : ’||TO_CHAR(L_SAL));<br />
END;</div>
<p>Above example code contains a SELECT query in the executable section of the anonymous PL/SQL block. It executes successfully because the query returns scalar output. Having being the query returning multiple rowed result set, it would end up raising an exception and hence, abnormal termination.</p>
<p>The above coding practice carries its own pros and cons. If the SELECT query is expected and framed to written a single row, SELECT with INTO clause is performance efficient.</p>
<p>But, implicit cursor runs serious threat to the application, when it returns zero or multiple rows. Zero rows returning implicit cursor raises NO_DATA_FOUND exception, while multiple rows one raises TOO_MANY_ROWS exception. Check the exception situations in the below screen dumps.</p>
<p><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Introduction-to-Oracle-11g-Cursors_img_01.jpg"><img class="aligncenter" title="Introduction to Oracle 11g Cursors_img_0" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Introduction-to-Oracle-11g-Cursors_img_01.jpg" alt="" width="579" height="185" /></a></p>
<p><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Introduction-to-Oracle-11g-Cursors_img_11.jpg"><img class="size-full wp-image-698 aligncenter" title="Introduction to Oracle 11g Cursors_img_1" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Introduction-to-Oracle-11g-Cursors_img_11.jpg" alt="" width="584" height="205" /></a></p>
<p>Explicit cursors are best suited in situations where number of records in the result set is not known. It not only avoids the exception threat but also well indents the coding standards.</p>
<h3>Single and Multiple row Implicit cursors</h3>
<p>Oracle 11g identifies a different categorization basis of implicit cursors. Implicit cursors, based on number of rows affected by the cursors, can be categorized as single row implicit cursors and multiple row implicit cursors. All SELECT statements and DML statements which affect single row, processed within PL/SQL block are classified as Single row implicit cursors. All DML statements and cursor FOR loops, which affect multiple rows fall under the category of multiple row implicit cursors.</p>
<p>Example Code [2]: The PL/SQL block below contains single SELECT statement which selects salary of a single employee. Since, it returns a single row output, it demonstrates the construction of single row implicit cursor.</p>
<div class="woo-sc-box normal   ">DECLARE<br />
L_SAL NUMBER;<br />
BEGIN<br />
SELECT SALARY<br />
INTO L_SAL<br />
FROM EMPLOYEES<br />
WHERE EMPLOYEE_ID=110;<br />
END;</div>
<p>Example Code [3]: In the PL/SQL block below, UPDATE statement recalculates the salary of all employees in the company. As the DML statement affects multiple rows, it demonstrates a multiple row implicit cursor.</p>
<div class="woo-sc-box normal   ">BEGIN<br />
UPDATE EMPLOYEES<br />
SET SALARY = SALARY + (COMM*SALARY);<br />
END;</div>
<h3>Explicit Cursor</h3>
<p>These cursors are explicitly declared in the DECLARE section of the block. They possess a specific name and a static SELECT statement attached to them. Explicit cursors are manually executed by the developers and follow complete execution cycle.</p>
<p>Explicit cursor information is also captured in cursor attributes, which are set during the cursor processing and reveal essential information about the cursors. These attributes, as listed below, are same as that in implicit cursors but specific to the cursors.</p>
<ul>
<li>CURSOR%ROWCOUNT</li>
<li>CURSOR%ISOPEN</li>
<li>CURSOR%FOUND</li>
<li>CURSOR%NOTFOUND</li>
</ul>
<h3>Cursor Execution Cycle</h3>
<p>The key steps in the cursor execution cycle are OPEN, FETCH and CLOSE. But it would be worth expanding the complete execution cycle for better understanding about the processing of a cursor. A cursor execution cycle refers to the stages which a cursor follows to process and execute the query. The phases of cursor execution are listed below.</p>
<p><img title="Introduction to Oracle 11g Cursors_img_2" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Introduction-to-Oracle-11g-Cursors_img_2-1024x221.jpg" alt="" width="672" height="134" /></p>
<p>I shall explain the activity carried out by the server in the key phases.</p>
<p><strong>OPEN stage</strong></p>
<ul>
<li>PGA memory allocation for cursor processing</li>
<li>Parsing of SELECT statement</li>
<li>Variable binding</li>
<li>SELECT Query execution</li>
<li>Move the record pointer to the first record</li>
</ul>
<p><strong>FETCH stage</strong></p>
<p>The record, to which the record pointer points, is pulled from the result set. The record pointer moves only in the forward direction. The FETCH phase lives until the last record is reached.</p>
<p><strong>CLOSE stage</strong></p>
<p>After the last record of the result set is reached, cursor is closed, and allocated memory is flushed off and released back to SGA. Even if an open cursor is not closed, oracle automatically closes it after the execution of its parent block.</p>
<h3>Setting of cursor attributes during cursor execution cycle</h3>
<p>The cursor attributes, listed above, are set at different stages of this cycle. The table below captures the stage wise value of the status flags.</p>
<p><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Introduction-to-Oracle-11g-Cursors_img_3.jpg"><img class="aligncenter size-full wp-image-705" title="Introduction to Oracle 11g Cursors_img_3" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Introduction-to-Oracle-11g-Cursors_img_3.jpg" alt="" width="616" height="188" /></a><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Introduction-to-Oracle-11g-Cursors_img_4.jpg"><img class="aligncenter size-full wp-image-706" title="Introduction to Oracle 11g Cursors_img_4" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Introduction-to-Oracle-11g-Cursors_img_4.jpg" alt="" width="622" height="167" /></a></p>
<h3>Syntax and illustration</h3>
<p><strong>Cursor definition</strong><br />
CURSOR [CURSOR NAME] IS<br />
[SELECT QUERY]</p>
<p><strong>Opening a Cursor</strong><br />
OPEN [CURSOR NAME]</p>
<p><strong>Fetching records from the cursor</strong><br />
FETCH [CURSOR NAME] INTO [LIST OF VARIABLES]</p>
<p><strong>Closing a cursor<br />
</strong>CLOSE [CURSOR NAME]</p>
<p>Example Code [4] – The PL/SQL block below declares a cursor, which select employee name, job id and salary for the employees with employee id 100. Note the opening, fetching and closing of the cursor. Here cursor returns a single record.</p>
<div class="woo-sc-box normal   ">DECLARE<br />
CURSOR C_EMP IS<br />
SELECT EMPLOYEE_NAME, JOB_ID, SALARY<br />
FROM EMPLOYEES<br />
WHERE EMPLOYEE_ID=100;<br />
L_ENAME VARCHAR2(100);<br />
L_JOBID VARCHAR2(10);<br />
L_SALARY NUMBER;<br />
BEGIN<br />
OPEN C_EMP;<br />
FETCH C_EMP INTO L_ENAME, L_JOBID, L_SALARY;<br />
DBMS_OUTPUT.PUT_LINE(&#8216;Employee &#8216;||L_ENAME||&#8217; with Job function of<br />
&#8216;||L_JOBID||&#8217; draws &#8216;||TO_CHAR(L_SALARY)||&#8217; per month&#8217;);<br />
CLOSE C_EMP;<br />
END;</div>
<div class="woo-sc-box normal   ">Employee JOHN with Job function of MGR draws 2300 per month<br />
PL/SQL procedure successfully completed.</div>
<p>Example Code [5]: When cursor result set contains multiple records, it has to be iterated to fetch each of them. The PL/SQL code below declares a cursor which selects employee details from department 10. A normal loop is used to iterate the result set and display the results.</p>
<div class="woo-sc-box normal   ">DECLARE<br />
CURSOR C_EMP IS<br />
SELECT EMPLOYEE_NAME, JOB_ID, SALARY<br />
FROM EMPLOYEES<br />
WHERE DEPARTMENT_ID=10;<br />
L_ENAME VARCHAR2(100);<br />
L_JOBID VARCHAR2(10);<br />
L_SALARY NUMBER;<br />
BEGIN<br />
OPEN C_EMP;<br />
LOOP<br />
FETCH C_EMP INTO L_ENAME, L_JOBID, L_SALARY;<br />
EXIT WHEN C_EMP%NOTFOUND;<br />
DBMS_OUTPUT.PUT_LINE(TO_CHAR(C_EMP%ROWCOUNT)||&#8217; Employee &#8216;||L_ENAME||&#8217;<br />
with Job function of &#8216;||L_JOBID||&#8217; draws &#8216;||TO_CHAR(L_SALARY)||&#8217; per month&#8217;);<br />
END LOOP;<br />
CLOSE C_EMP;<br />
END;<br />
/</div>
<div class="woo-sc-box normal   ">1 Employee JOHN with Job function of MGR draws 2300 per month<br />
2 Employee KATE with Job function of TECH draws 5500 per month<br />
PL/SQL procedure successfully completed.</div>
<h3>Cursor FOR loops</h3>
<p>Explicit cursor processing can also be done using cursor FOR Loops. Cursor FOR loops improvise upon the performance and code interactivity by their implicit actions. Implicitly, they create variables, which can be accessed through cursor index. Even, cursor execution steps are implicitly carried out by them.</p>
<p>Example Code [6]: The above example code [5] can be rewritten using cursor FOR loop as below.</p>
<div class="woo-sc-box normal   ">DECLARE<br />
CURSOR C_EMP IS<br />
SELECT EMPLOYEE_NAME, JOB_ID, SALARY<br />
FROM EMPLOYEES<br />
WHERE DEPARTMENT_ID=10;<br />
BEGIN<br />
FOR I IN C_EMP<br />
LOOP<br />
DBMS_OUTPUT.PUT_LINE(&#8216;Employee &#8216;||I.EMPLOYEE_NAME||&#8217; with Job function of<br />
&#8216;||I.JOB_ID||&#8217; draws &#8216;||TO_CHAR(I.SALARY)||&#8217; per month&#8217;);<br />
END LOOP;<br />
END;<br />
/</div>
<p>Employee JOHN with Job function of MGR draws 2300 per month<br />
Employee KATE with Job function of TECH draws 5500 per month<br />
PL/SQL procedure successfully completed.</p>
<h3>Dynamic Cursor FOR Loops</h3>
<p>Cursor FOR loops, as illustrated above, can be extended to include subqueries as dynamic cursors. This implies that the cursors would not be declared in the DECLARE section, but would be implicitly created when a subquery is attached to the FOR loop. I shall rewrite the cursor in Example Code [5] for loop as below.</p>
<p>Example Code [7]</p>
<div class="woo-sc-box normal   ">BEGIN<br />
FOR I IN (SELECT EMPLOYEE_NAME, JOB_ID, SALARY<br />
FROM EMPLOYEES WHERE DEPARTMENT_ID=10)<br />
LOOP<br />
DBMS_OUTPUT.PUT_LINE(&#8216;Employee &#8216;||I.EMPLOYEE_NAME||&#8217; with Job function of<br />
&#8216;||I.JOB_ID||&#8217; draws &#8216;||TO_CHAR(I.SALARY)||&#8217; per month&#8217;);<br />
END LOOP;<br />
END;</div>
<h3>Parameterized Cursors</h3>
<p>Hard coding of values in the application programming has never been the persistent mode of programming. If you analyze the cursors used in the above example codes for demonstration purpose,<br />
each one of them contains hardcoded value. Parameterized cursors provide cut to the problem by enabling programmer to pass parameter to the cursors. This reduces code redundancy, enhances code reusability and visibility in the program. The same cursor can be reopened for a different value and hence, different result set.</p>
<p>Example Code [8]: The cursor used in example code [5] can be redefined by introducing a<br />
parameter.</p>
<div class="woo-sc-box normal   ">DECLARE<br />
CURSOR C_EMP (P_DEPT NUMBER) IS<br />
SELECT EMPLOYEE_NAME, SALARY<br />
FROM EMPLOYEES<br />
WHERE DEPARTMENT_ID=P_DEPT;<br />
BEGIN<br />
FOR I IN C_EMP(10)<br />
LOOP<br />
DBMS_OUTPUT.PUT_LINE(&#8216;Employee &#8216;||I.EMPLOYEE_NAME||&#8217; draws<br />
&#8216;||TO_CHAR(I.SALARY)||&#8217; per month&#8217;);<br />
END LOOP;<br />
FOR I IN C_EMP(20)<br />
LOOP<br />
DBMS_OUTPUT.PUT_LINE(&#8216;Employee &#8216;||I.EMPLOYEE_NAME||&#8217; draws<br />
&#8216;||TO_CHAR(I.SALARY)||&#8217; per month&#8217;);<br />
END LOOP;<br />
END;<br />
/</div>
<div class="woo-sc-box normal   ">Employee JOHN draws 2300 per month<br />
Employee KATE draws 5500 per month<br />
Employee MILLER draws 4820 per month<br />
Employee NIC draws 4310 per month<br />
Employee YEN draws 9420 per month<br />
PL/SQL procedure successfully completed.</div>
<h3>Illustrations</h3>
<p><strong>Using FOR UPDATE clause in cursor</strong></p>
<p>In a multiple user application environment, application must be robust enough to overcome the locking scenarios. In Oracle, FOR UPDATE OF clause is used to lock a set of rows in a session. This concept can be used in explicit cursors also to impose exclusive row level lock on all the rows contained by the cursor query result set. These rows will remain locked until the session issues ROLLBACK or COMMIT.</p>
<p>FOR UPDATE OF allows a programmer to specify the column names which are more intend to change in other sessions. Nevertheless, the rows would be locked to protest updates against all the columns, but still OF list provides flexibility to make note of ‘update prone’ columns.</p>
<p>Oracle provides WHERE CURRENT OF clause to update or delete the rows which are locked by the FOR UPDATE OF cursor in the session. The clause identifies the row to be updated and thus, prevents coding for row identification from the cursor result set.</p>
<p>Example Code [9]: The PL/SQL block below updates the salary of all employees working in department 30.</p>
<div class="woo-sc-box normal   ">DECLARE<br />
CURSOR c1 IS<br />
SELECT SALARY<br />
FROM EMPLOYEES<br />
WHERE DEPARTMENT_ID = 30<br />
FOR UPDATE OF SALARY;<br />
L_SALARY NUMBER;<br />
BEGIN<br />
OPEN C1;<br />
LOOP<br />
FETCH C1 INTO L_SALARY;<br />
EXIT WHEN C1%NOTFOUND;<br />
UPDATE EMPLOYEES<br />
SET SALARY = SALARY + 1200<br />
WHERE CURRENT OF c1;<br />
END LOOP;<br />
CLOSE c1;<br />
END;</div>
<p><strong>Exceptions with cursors</strong></p>
<p>INVALID_CURSOR and CURSOR_ALREADY_OPEN are the two exceptions which are raised, when oracle optimizer encounters aberrant cursor.</p>
<p>The exception INVALID_CURSOR is raised when programmer attempts to operate a non allowed operation on the cursor. If the operation points to a cursor which does not exist, or which does not points to any SQL context area, the INVALID exception is raised.</p>
<p>Example Code [10a]: Demonstrating INVALID_CURSOR exception</p>
<div class="woo-sc-box normal   ">DECLARE<br />
CURSOR C_DEPT IS<br />
SELECT DEPARTMENT_NAME, LOCATION_ID<br />
FROM DEPARTMENTS<br />
WHERE DEPARTMENT_ID=20;<br />
L_DEPTNAME VARCHAR2(100),<br />
L_LOC NUMBER;<br />
BEGIN<br />
OPEN C_EMP;<br />
FETCH C_EMP INTO L_DEPTNAME, L_LOC;<br />
CLOSE C_EMP;<br />
DBMS_OUTPUT.PUT_LINE(L_DEPTNAME||’.’||L_LOC);<br />
END;<br />
/</div>
<div class="woo-sc-box normal   ">DECLARE<br />
*<br />
ERROR at line 1:<br />
ORA-01001: invalid cursor<br />
ORA-06512: at &#8220;SCOTT.C_EMP&#8221;, line 10<br />
ORA-06512: at line 1</div>
<p>Example Code [10b]: Demonstration of CURSOR_ALREADY_OPEN exception</p>
<div class="woo-sc-box normal   ">DECLARE<br />
CURSOR C_DEPT (P_DEPTID NUMBER) IS<br />
SELECT DEPARTMENT_NAME, LOCATION_ID<br />
FROM DEPARTMENTS<br />
WHERE DEPARTMENT_ID=P_DEPTID;<br />
L_DEPTNAME VARCHAR2(100),<br />
L_LOC NUMBER;<br />
BEGIN<br />
OPEN C_DEPT (10);<br />
FETCH C_DEPT INTO L_DEPTNAME, L_LOC;<br />
DBMS_OUTPUT.PUT_LINE(L_DEPTNAME||’.’||L_LOC);<br />
OPEN C_DEPT (20);<br />
FETCH C_DEPT INTO L_DEPTNAME, L_LOC;<br />
CLOSE C_DPET;<br />
DBMS_OUTPUT.PUT_LINE(L_DEPTNAME||’.’||L_LOC);<br />
END;</div>
<div class="woo-sc-box normal   ">DECLARE<br />
*<br />
ERROR at line 1:<br />
ORA-06511: PL/SQL: cursor already open<br />
ORA-06512: at line 3<br />
ORA-06512: at line 13</div>
<h3>Conclusion</h3>
<p>I have made a sincere effort to familiarize you all with the world of cursors, which would be justified with the interest of readers and visitors. The codes and explanations are based on self hands on and observations.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbanotes.com/database-development/introduction-to-oracle-11g-cursors/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Using Triggers and Compound Triggers in Oracle 11g</title>
		<link>http://www.dbanotes.com/database-development/using-triggers-and-compound-triggers-in-oracle-11g/</link>
		<comments>http://www.dbanotes.com/database-development/using-triggers-and-compound-triggers-in-oracle-11g/#comments</comments>
		<pubDate>Fri, 17 Jun 2011 01:35:42 +0000</pubDate>
		<dc:creator>Contributing Author</dc:creator>
				<category><![CDATA[Database Development]]></category>
		<category><![CDATA[Oracle Database]]></category>
		<category><![CDATA[Oracle11g]]></category>

		<guid isPermaLink="false">http://www.dbanotes.com/?p=645</guid>
		<description><![CDATA[In database terminology, triggers are the objects which demonstrate the logic of schedule and automation. Triggers are automatically invoked at a defined event and timing without any explicit calls. The logic embedded within the trigger and invocation must be well directed and synchronized to maintain database purity. Oracle 11g made remarkable enhancements in Database Triggers. [...]]]></description>
			<content:encoded><![CDATA[<p>In database terminology, triggers are the objects which demonstrate the logic of schedule and automation.</p>
<p>Triggers are automatically invoked at a defined event and timing without any explicit calls. The logic embedded within the trigger and invocation must be well directed and synchronized to maintain database purity.</p>
<p>Oracle 11g made remarkable enhancements in Database Triggers. These enhancements and additions have transformed triggers into a logical, stable, and comprehensive database platform. In the past versions, developers used to face issues under certain conditions as listed below.</p>
<ul>
<li>Multiple triggers for single timing</li>
<li>Mutating table confrontation</li>
<li>Control the trigger execution by enabling and disabling it</li>
</ul>
<p>Introduction of compound triggers which triggers different logic at different timings, guaranteed execution sequence of triggers and enable/disable functionalities make the PL/SQL a more efficient language and require less coding.</p>
<p>The article projects the transformations undergone by database triggers in 11g release of Oracle.</p>
<h3>Trigger Enhancements</h3>
<p><strong>Setting the Trigger order</strong></p>
<p>Earlier, if a DML event demands multiple triggering actions without altering the existing code, developers used to create multiple triggers for same timing and event. For example, a table EMPLOYEE can have two AFTER UPDATE OF EMPLOYEE FOR EACH ROW triggers.</p>
<p>Such activity was possible since Oracle 8i, but usually the trigger timing determines the order of its execution but the aforesaid baffling situation gives the complete privilege to the database server to determine the execution order of the triggers i.e. random execution. It remained a ‘crossed fingers’ situation for the developers to predict the execution order. Unsorted execution of DML triggers can produce unexpected results where setting or initializations of parameters are involved.</p>
<p>Now, oracle has released the flexibility to set the sequence of execution of triggers for the same triggering event and timing. Two new keywords FOLLOWS and PRECEDES have been introduced to force the triggers to follow set execution order.</p>
<p>Example Syntax [1]</p>
<div class="woo-sc-box normal   ">CREATE OR REPLACE TRIGGER [TRIGGER TO FOLLOW]<br />
[TIMING SPECIFICATION]<br />
[EVENT SPECIFICATION]<br />
FOLLOWS [TRIGGER TO BE FOLLOWED]</div>
<p>Example Code [1]: Demonstrate the use of FOLLOWS keyword</p>
<div class="woo-sc-box normal   ">CREATE OR REPLACE TRIGGER T_UPD_SAL<br />
AFTER UPDATE ON EMPLOYEES<br />
FOR EACH ROW<br />
BEGIN<br />
DBMS_OUTPUT.PUT_LINE(‘Executing T_UD_SAL’);<br />
INSERT INTO EMP_SAL_ARCHIVE<br />
VALUES (EMPLOYEE_ID, DEPARTMENT, SALARY, HIKE_PERC, HIKE_DATE)<br />
(:OLD.EMPLOYEE_ID,<br />
:OLD.DEPARTMENT_ID,<br />
:NEW.SALARY,<br />
((:NEW.SALARY-:OLD.SALARY)/:OLD.SALARY)*100,<br />
SYSDATE)<br />
END;</div>
<div class="woo-sc-box normal   ">CREATE OR REPLACE TRIGGER T_UPD_JOB<br />
AFTER UPDATE ON EMPLOYEES<br />
FOR EACH ROW<br />
FOLLOWS T_UPD_SAL<br />
BEGIN<br />
DBMS_OUTPUT.PUT_LINE(‘Executing T_UD_JOB’);<br />
INSERT INTO EMP_JOB_ARCHIVE<br />
VALUES(EMPLOYEE_ID, DEPARTMENT, OLD_JOB, NEW_JOB, PROM_DATE)<br />
(:OLD.EMPLOYEE_ID,<br />
:OLD.DEPARTMENT_ID,<br />
:OLD.JOB_ID,<br />
:NEW.JOB_ID,<br />
SYSDATE);<br />
END; </div>
<p>Now, the triggers would be executed in the set order. This ensures the logical and sorted execution of modular logic in the application.</p>
<h3>DISABLED Triggers</h3>
<p>Prior to Oracle 11g, by default all triggers used to get created in ENABLED state. In real time production systems, this behavior had rooted out reluctant and unavoidable issues. Suppose the database support team applies a production patch, which contains a new trigger script. Upon execution, the trigger script raises error due to some missing reference. If somehow the trigger could have been only created with compilation errors, but not on live association with the event [table], the error could be resolved out.</p>
<p>Oracle 11g resolves such scenarios by allowing a trigger to be created in DISABLED state. Note that state is not at all new for triggers. Earlier too, a trigger can be disabled using ALTER TRIGGER command. Oracle 11g has widened this feature by taking it at creation level. A disabled trigger can be enabled at any point of time in the program.</p>
<p>Example Code [2]: Demonstration of DISABLED trigger</p>
<div class="woo-sc-box normal   ">CREATE OR REPLACE TRIGGER T_CRT_DIS<br />
BEFORE INSERT ON ORDER<br />
FOR EACH ROW<br />
DISABLED<br />
BEGIN<br />
SELECT 1<br />
INTO L_EXIST<br />
FROM WAREHOUSE<br />
WHERE ITEM_CODE = :NEW.PROD_CODE;<br />
DBMS_OUTPUT.PUT_LINE(‘Product in stock: Go ahead’);<br />
EXCEPTION<br />
WHEN NO_DATA_FOUND THE RAISE_APPLICATION_ERROR(-20100, ‘Shortage of the product: No Order can be placed’);</div>
<h3>DML triggers are now faster</h3>
<p>DML Triggers in Oracle 11g are comparatively faster than their counterparts in earlier versions. The performance can be clearly measured by running a trigger separately in 10g and 11g and recording their execution time. I have executed a trigger T_CHECK_ORDER in Oracle 10g and 11g separately. Their execution time upon operation is recorded as 153</p>
<p><img title="Using Triggers and Compound Triggers in Oracle 11g_img_0" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Using-Triggers-and-Compound-Triggers-in-Oracle-11g_img_0.jpg" alt="" width="597" height="472" /><span style="font-size: small;"> </span></p>
<p style="text-align: left;">Figuire shows the reduction in execution time of the DML triggers in Oracle 11g.<img title="Using Triggers and Compound Triggers in Oracle 11g_img_1" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Using-Triggers-and-Compound-Triggers-in-Oracle-11g_img_1.jpg" alt="" width="358" height="303" /></p>
<p> </p>
<h3>New Language Features</h3>
<p> <strong>Compound Triggers</strong></p>
<p>Compound triggers are another new tool in the kit to support reduced coding and interactivity. It combines all four triggering events into a single piece of code. Besides the coding efficiency, it tackles some bigger issues in the picture.</p>
<ul>
<li>Mutating table (ORA-04091) scenarios</li>
<li>Suppose an EACH ROW triggers do some transaction in some other table using new values.</li>
</ul>
<p> Imagine the situation when dealing with millions of data and double transaction for each row through trigger action would cause huge losses to performance.</p>
<p>Earlier, workaround solutions do existed for the above problems, but with loads of complex coding using collections and multiple triggers. It used to become nightmare for developers to simulate and test such scenarios.</p>
<p>Compound triggers readily deal with all above scenarios in an efficient and interactive manner. The new trigger feature not only boosts up the performance during bulk operations, but also holds the state of its variables and member constructs till the execution of the statement. They are reset only at the beginning of new statement. Note that compound trigger is an optional feature. Separate DML triggers for different timing can still be created in earlier fashion.</p>
<p>On the lower side, compound triggers are only available for DML triggers. DDL and system level triggers still follow the old convention. In addition, condition based and autonomous compound triggers are not supported. An important point to mention here is the exception handling. It has to be handled explicitly in all the timing blocks, and not in the trigger body.</p>
<p><strong>Syntax</strong></p>
<p>The compound trigger syntax contains the man body and four blocks representing four timings associated with DML events. Note the COMPOUND TRIGGER keyword to differentiate with the other database triggers.</p>
<div class="woo-sc-box normal   ">CREATE OR REPLACE TRIGGER [TRIGGER NAME]<br />
FOR [DML] ON [TABLE NAME]<br />
COMPOUND TRIGGER<br />
&#8211; Initial section<br />
&#8211; Declarations<br />
&#8211; Subprograms<br />
&#8212;Optional section&#8212;<br />
BEFORE STATEMENT IS<br />
…;<br />
&#8212;Optional section&#8212;<br />
AFTER STATEMENT IS<br />
…;<br />
&#8212;Optional section&#8212;<br />
BEFORE EACH ROW IS<br />
…;<br />
&#8212;Optional section&#8212;<br />
AFTER EACH ROW IS<br />
…;<br />
END;<br />
For database views<br />
INSTEAD OF EACH ROW IS<br />
&#8230;;<br />
END;</div>
<h3><strong> </strong>Usage guidelines</h3>
<p> </p>
<ol>
<li>Each timing handler block must appear only once in the compound trigger body</li>
<li> All timing handler blocks are optional</li>
<li>Compound Trigger metadata can be captured in USER_TRIGGERS view. The new columns added are as below:</li>
</ol>
<p> </p>
<p><strong><span style="font-size: small;"><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Using-Triggers-and-Compound-Triggers-in-Oracle-11g_img_2.jpg"><img class="aligncenter size-full wp-image-658" title="Using Triggers and Compound Triggers in Oracle 11g_img_2" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Using-Triggers-and-Compound-Triggers-in-Oracle-11g_img_2.jpg" alt="" width="555" height="303" /></a> </span></strong></p>
<p>A new trigger type ‘COMPOUND’ would be updated for compound triggers. Based on availability of the timing block in the trigger body,</p>
<h3>Illustrations of Compound Triggers</h3>
<p> </p>
<p><strong> Compound trigger as performance savior</strong></p>
<p>I shall site a scenario where concurrent loading into a table is achieved through Compound trigger. Bulk loading uses an associative array to hold the data to be loaded. The loading is done after the statement execution completes. Refer the trigger code below</p>
<p>Example Code [3]: Compound trigger to implement bulk loading</p>
<div class="woo-sc-box normal   ">CREATE OR REPLACE TRIGGER TRG_INS_ORDER<br />
FOR INSERT ON ORDERS<br />
COMPOUND TRIGGER<br />
TYPE ORDER_T IS TABLE OF ORDER_ARCHIVE%ROWTYPE<br />
INDEX BY PLS_INTEGER;<br />
L_ORDERS ORDER_T;<br />
I NUMBER := 0;<br />
AFTER EACH ROW IS<br />
BEGIN<br />
I := I+1;<br />
L_ORDERS(I).ORD_ID := :NEW.ORD_ID;<br />
L_ORDERS(I).ORD_CODE := :NEW.ITEM_CODE;<br />
END AFTER EACH ROW;<br />
AFTER STATEMENT IS<br />
BEGIN<br />
DBMS_OUTPUT.PUT_LINE(&#8216;Statement level loading&#8217;);<br />
FORALL J IN 1..L_ORDERS.COUNT<br />
INSERT INTO ORDER_ARCHIVE VALUES L_ORDERS(J);<br />
L_ORDERS.DELETE;<br />
I := 0;<br />
END AFTER STATEMENT;<br />
END;<br />
/<br />
Trigger created.</div>
<p>&#8211;Inserting test data into ORDERS table<br />
<div class="woo-sc-box normal   ">INSERT INTO ORDERS(ORD_ID, ITEM_CODE)<br />
SELECT ORD_SEQ.NEXTVAL, &#8216;PROD &#8216;||LEVEL<br />
FROM DUAL<br />
CONNECT BY LEVEL &lt; 1000;<br />
Statement level loading<br />
999 rows created.</div></p>
<p>To be noticed, the simultaneous insertion process has been carried out in bulk. This pulls up the performance to a major extent. If the same insert operation have had used conventional row level trigger, it would have shrunk the performance by 1000 insert statements.</p>
<p><strong>Resolving Table mutation scenarios</strong></p>
<p>Mutating table scenarios have been hovering over the multi-user based applications for a long time. Several times, tedious workaround solutions and unreliability has forces the architects to modify the design, so as to avoid table mutation during parallel real time processing. Compound triggers in Oracle 11g provide concrete logic base to deal with such scenarios. The trigger example below shows how they handle and achieve such events.</p>
<p>Before moving to the solution, first I will simulate the table mutation scenario.</p>
<p>The row level trigger TRG_INS_ORDERS on ORDERS table will display the updated item code.</p>
<div class="woo-sc-box normal   ">CREATE OR REPLACE TRIGGER TRG_INS_ORDERS<br />
AFTER UPDATE OF ITEM_CODE ON ORDERS<br />
FOR EACH ROW<br />
DECLARE<br />
L_ITEM VARCHAR2(200);<br />
BEGIN<br />
SELECT ITEM_CODE INTO L_ITEM FROM ORDERS WHERE ORD_ID = :OLD.ORD_ID;<br />
DBMS_OUTPUT.PUT_LINE(&#8216;ITEM CODE CHANGED FROM &#8216;||:OLD.ITEM_CODE||&#8217; TO &#8216;||L_ITEM);<br />
* END;<br />
SQL&gt; /<br />
Trigger created.</div>
<div class="woo-sc-box normal   ">UPDATE ORDERS<br />
SET ITEM_CODE=&#8217;ITEM:&#8217;||ORD_ID<br />
WHERE ORD_ID=10;<br />
update orders<br />
*<br />
ERROR at line 1:<br />
ORA-04091: table SCOTT.ORDERS is mutating, trigger/function may not see it<br />
ORA-06512: at &#8220;SCOTT.TRG_INS_ORDERS &#8220;, line 4<br />
ORA-04088: error during execution of trigger &#8216;SCOTT.TRG_INS_ORDERS&#8217;</div>
<p>The table remains in the floating state, when the trigger TRG_INS_ORDERS tries to select and display the changed value. Such situations are well handled using compound triggers. Check the example below.</p>
<div class="woo-sc-box normal   ">CREATE OR REPLACE TRIGGER TRG_INS_ORDERS<br />
FOR UPDATE ON ORDERS<br />
COMPOUND TRIGGER<br />
TYPE ITEM_CODE_T IS TABLE OF ORDERS.ITEM_CODE%TYPE INDEX BY BINARY_INTEGER;<br />
L_ITEM_CODE ITEM_CODE_T;<br />
BEFORE STATEMENT IS<br />
CURSOR C IS<br />
SELECT ORD_ID, ITEM_CODE<br />
FROM ORDERS;<br />
BEGIN<br />
FOR I IN C<br />
LOOP<br />
L_ITEM_CODE(I.ORD_ID):=I.ITEM_CODE;<br />
END LOOP;<br />
END BEFORE STATEMENT;<br />
AFTER EACH ROW IS<br />
BEGIN<br />
DBMS_OUTPUT.PUT_LINE(&#8216;Item code changed from &#8216;||L_ITEM_CODE(:OLD.ORD_ID)||&#8217; to &#8216;||:NEW.ITEM_CODE);<br />
END AFTER EACH ROW;<br />
END;<br />
/</div>
<div class="woo-sc-box normal   ">UPDATE ORDERS<br />
SET ITEM_CODE = &#8216;Item Number:&#8217;||ORD_ID<br />
WHERE ORD_ID=100;<br />
Item code changed from Prod 99 to Item Number:100<br />
1 row updated.</div>
]]></content:encoded>
			<wfw:commentRss>http://www.dbanotes.com/database-development/using-triggers-and-compound-triggers-in-oracle-11g/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Oracle 11g R2 SQL Enhancements</title>
		<link>http://www.dbanotes.com/database-development/oracle-11g-r2-sql-enhancements/</link>
		<comments>http://www.dbanotes.com/database-development/oracle-11g-r2-sql-enhancements/#comments</comments>
		<pubDate>Sun, 05 Jun 2011 20:55:31 +0000</pubDate>
		<dc:creator>Contributing Author</dc:creator>
				<category><![CDATA[Database Development]]></category>
		<category><![CDATA[Oracle Database]]></category>
		<category><![CDATA[Oracle11g]]></category>

		<guid isPermaLink="false">http://www.dbanotes.com/?p=528</guid>
		<description><![CDATA[With each and every release of RDBMS, Oracle has achieved great commercial success and attained zeniths of exploration. The year 2007 saw the release of Oracle RDBMS version 11g (second grid computed version after Oracle 10g). First release of Oracle 11g facilitated the developers with multiple enhancements and language features. The introduction of advanced core [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/05/oracle11g-sql-enhancements.png"></a><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Oracle-11g-R2-SQL-Enhancements_img_5.jpg"></a>With each and every release of RDBMS, Oracle has achieved great commercial success and attained zeniths of exploration. The year 2007 saw the release of Oracle RDBMS version 11g (second grid computed version after Oracle 10g).</p>
<p>First release of Oracle 11g facilitated the developers with multiple enhancements and language features. The introduction of advanced core database concepts and language features has taken Oracle from instrumental to advisory level. With the market stake of more than 90% in database industry, Oracle provides a reliable, flexible and scalable database solution.</p>
<p>The article lists down the major SQL language additions and enhancements, which were inducted during 11g release. I hope my efforts would be justified with the note of thanks.</p>
<h3>New Additions</h3>
<p>I shall project some of the key additions in SQL side. The selection of these features out of many is based upon their relevance and level of criticality in a real time application environment.</p>
<h3>Read only tables</h3>
<p>Oracle 11g database categorizes tables based on their transactional behavior; they can be READ ONLY or READ WRITE. A READ ONLY table remains passive against all DML operations, selective DDL operations, and flashback activities. The permissible actions on a READ ONLY table includes selection, indexing, enforce constraints, rename, and dropping.</p>
<p>With the addition of this category, Oracle added another obvious category as READ WRITE. A table, which is open for all transactional activities, falls under this category. The category can be toggled over at any point of time in the session using ALTER TABLE command.</p>
<p>A table would be created in conventional manner but it can be altered to READ ONLY mode.</p>
<p>Example Syntax [1]</p>
<div class="woo-sc-box normal   "> ALTER TABLE [TABLE NAME] [READ ONLY | READ WRITE] </div>
<p>Example Code [1]</p>
<div class="woo-sc-box normal   ">SQL&gt; ALTER TABLE EMPLOYEES READ ONLY;<br />
Table altered.</div>
<p>The below ALTER TABLE statement switches back the table mode to READ WRITE.</p>
<div class="woo-sc-box normal   ">SQL&gt; ALTER TABLE EMPLOYEES READ WRITE;<br />
Table altered.</div>
<p>The behavior of READ ONLY table is illustrated in the below screen shot.</p>
<p style="text-align: center;"><img class="aligncenter size-large wp-image-539" title="oracle11g - sql enhancements" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/05/oracle11g-sql-enhancements-1024x769.png" alt="" width="611" height="586" /></p>
<p>READ ONLY tables are extremely useful in tightening the security at user level. Earlier, the same objective was achieved by a statement level DML trigger or a check constraint in ‘disable validate’ state. But READ ONLY table provides a simple and reliable technique to impose DML restriction on a table.</p>
<h3>SQL Result Cache</h3>
<p>Result caching is one of the most eye catching features in Oracle 11g. It has been introduced in both SQL and PL/SQL. In PL/SQL, it is practiced in stored functions. In SQL, a query result can be cached in the session server cache using a new optimizer hint RESULT_CACHE. Upon subsequent executions of the same query with same set of parameters, the result would be fetched directly from the cache and not by re-executing the query. Server Result Cache is the new component of SGA, whose sizing can be done based on MEMORY_TARGET (0.25%), SGA_TARGET (0.5%), or SHARED_POOL_SIZE (1%).</p>
<p>Four new initialization parameters are required to be set to enable result cache feature on the server side. The parameters are depicted in the below diagram.</p>
<div><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/oracle_result_cache_parms.jpg"></a></div>
<p><img class="aligncenter size-large wp-image-592" title="oracle_result_cache_parms" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/oracle_result_cache_parms-1024x407.jpg" alt="" width="707" height="345" /></p>
<div>If RESULT_CACHE_MAX_SIZE is zero, the caching feature is disabled. Therefore, it must be set to a definite value to allow server to cache the results.</div>
<div>These parameters can be set at SYSTEM or SESSION level as below.</div>
<div><img title="Oracle 11g R2 SQL Enhancements_img_11" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Oracle-11g-R2-SQL-Enhancements_img_11.jpg" alt="" width="426" height="237" /></div>
<p>Taking above parameters into consideration, we shall run a SQL query with RESULT_CACHE hint and generate the explain plan.</p>
<p>Example Code [2]</p>
<div class="woo-sc-box normal   ">SELECT /*+ RESULT_CACHE */ DEPARTMENT_ID, MAX(SALARY)<br />
FROM EMPLOYEES<br />
WHERE DEPARTMENT_ID = 10<br />
GROUP BY DEPARTMENT_ID;</div>
<p><img title="Oracle 11g R2 SQL Enhancements_img_2" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Oracle-11g-R2-SQL-Enhancements_img_2.jpg" alt="" width="705" height="300" /></p>
<p>The explain plan shows the RESULT CACHE operation with the CACHE ID ‘6pvpvvjg0kkcr67422t1kfyrgs6’. This cache id is a unique id to identify the cached result of the query. It can be queried in V$RESULT_CACHE_OBJECTS to check the status and the SELECT statement associated with it.</p>
<h3>Virtual columns</h3>
<p>In the earlier versions of Oracle, virtual columns used to exist but they were internally created and maintained by Oracle. The collection columns were categorized by Oracle server as Virtual Columns because of their data storage logic.</p>
<p>With 11g release, Oracle allows user to explicitly create virtual columns in a table. These virtual columns are associated with an expression, which always generate the value for the virtual column. The expression must be build using the non virtual columns of the same table or a stored function of deterministic type.</p>
<p>Example Syntax [2]</p>
<div class="woo-sc-box normal   ">[COLUMN NAME] [DATA TYPE] GENERATED ALWAYS AS (EXPRESSION) VIRTUAL (CONSTRAINT) </div>
<p>In the above syntax, the keyword GENERATED ALWAYS and VIRTUAL are optional, while AS is the mandatory one. The optional keywords improve the virtual column definition readability.</p>
<p>Note that the data type of the virtual column is also optional. If it is not explicitly specified, it attains the return data type of the expression.</p>
<p>Example Code [3]<br />
<div class="woo-sc-box normal   ">CREATE TABLE ORDERS (ORDER_ID NUMBER, ITEM_CODE VARCHAR2(10), SALES_DAY NUMBER, SALES_EST_MONTH AS (SALES * 30));<br />
Table created.</div></p>
<p>The virtual property of a column can be queried in VIRTUAL_COLUMN of USER_TAB_COLS table. During insertion also, the non virtual columns must be explicitly specified. Since virtual column value is generated during runtime, it has to be excluded during insertion; else it raises ORA-54013 exception which reads as ‘ORA-54013: INSERT operation disallowed on virtual columns’.</p>
<p>Update operations are not allowed on the virtual columns. Any attempt to do so would raise exception ORA-54017 which reads as ORA-54017: UPDATE operation disallowed on virtual columns&#8217;.</p>
<div>Example Code [4]</div>
<div><div class="woo-sc-box normal   ">INSERT INTO ORDERS (ORDER_ID, ITEM_CODE, SALES_DAY)<br />
VALUES (101, ‘HDD’, 50);<br />
1 row inserted.</div></div>
<div><div class="woo-sc-box normal   ">INSERT INTO ORDERS (ORDER_ID, ITEM_CODE, SALES_DAY)<br />
VALUES (102, ‘DVD’, 25);<br />
1 row inserted.</div></div>
<div><div class="woo-sc-box normal   ">INSERT INTO ORDERS (ORDER_ID, ITEM_CODE, SALES_DAY)<br />
VALUES (103, ‘CPU’, 15);<br />
1 row inserted.</div></div>
<div><div class="woo-sc-box normal   ">SELECT * FROM ORDERS;</div></div>
<div class="woo-sc-box normal   ">ORDER_ID ITEM_CODE SALES_DA SALES_EST_MONTH<br />
&#8212;&#8212;&#8211; &#8212;&#8212;&#8212; &#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212;&#8212;<br />
101 HDD 50 1500<br />
102 DVD 25 750<br />
103 CPU 15 450</div>
<h3>Creation of virtual columns using Deterministic functions</h3>
<p>If the virtual column expression has to contain a user defined function, it must be of DETERMINISTIC type. For other functions, oracle raises ORA-30553 exception which says ORA-30553: The function is not deterministic.</p>
<div>
<p>The example illustration below shows the creation of a deterministic function and its usage in virtual column expression. Behavior of virtual columns is same as normal columns. They are stored physically in the database. Like other columns, Oracle virtual columns can be indexed, constrained and even acts as partitioning key column.</p>
<p>Virtual columns optimize the use of disk space as their values are not stored on the server disk, but generated at runtime through the associated expression.</p>
<h3>Invisible indexes</h3>
<p>Oracle 11g has added a new dimensional feature to indexes, visibility. Index would fall in either of the category i.e. either VISIBLE or INVISIBLE. All indexes, which are created following conventional syntax, are created in VISIBLE mode. An index can now be created in invisible mode by specifying INVISIBLE keyword in the syntax.</p>
<p>Example Syntax [3a]</p>
<div class="woo-sc-box normal   ">CREATE INDEX [INDEX NAME] ON [TABLE NAME(COLUMN NAME)] [VISIBLE | INVISIBLE]</div>
<p>The indexes which already exist in database in visible state can be switched over to invisible mode using ALTER INDEX command.</p>
<p>Example Syntax [3b]</p>
<div class="woo-sc-box normal   ">ALTER INDEX [INDEX NAME] [VISIBLE | INVISIBLE]</div>
<p>Example Code [5a]</p>
<div class="woo-sc-box normal   ">SQL&gt; CREATE INDEX IDX_ORDERS_ID ON ORDERS(ORDER_ID) INVISIBLE;<br />
Index created.</div>
<div class="woo-sc-box normal   ">SQL&gt; ALTER INDEX IDX_SALES INVISIBLE;<br />
Index altered.</div>
<p>Based on their visibility modes, indexes take part in the query optimization. Optimizer ignores invisible indexes while generating explain plan of an SQL query. Actually, this action is governed by a new initialization parameter OPTMIZER_USE_INVISIBLE_INDEX. If its value is set as FALSE, then optimizer would follow logical action. If it is TRUE, optimizer would consider all the indexes irrespective of their visibility modes. The new parameter can be set at SYSTEM or SESSION level using ALTER SYSTEM command.</p>
<p>Example Code [5b]</p>
<div class="woo-sc-box normal   ">SQL&gt; ALTER SYSTEM SET OPTIMIZER_USE_INVISIBLE_INDEX=FALSE;<br />
System altered.</div>
<p>Subsequently, usage of an index in query optimization process is based on two criteria, firstly, the visibility mode of the index, and secondly, the value of initialization parameter. Based on these conditions, below matrix can be generated which shows the favorable condition for an index to be used in a query.</p>
<p>The table shows the four cases based on above listed parameters. Note the ‘Alternate’ column, which is included to specify any alternate step available to enable index usage.</p>
<p><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Oracle-11g-R2-SQL-Enhancements_img_12.jpg"><img class="aligncenter size-full wp-image-634" title="Oracle 11g R2 SQL Enhancements_img_12" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Oracle-11g-R2-SQL-Enhancements_img_12.jpg" alt="" width="597" height="98" /></a></p>
<p>Dictionary view for Indexes i.e. USER_INDEXES has been altered to include VISIBILITY column. The column reveals the current visibility mode of the index on a column in the table.</p>
<p>Example Code [5c]</p>
<div class="woo-sc-box normal   ">SQL&gt; SELECT INDEX_NAME, TABLE_NAME, VISIBILITY FROM USER_INDEXES WHERE INDEX_NAME = ‘IDX_ORDERS&#8217;;</div>
<div class="woo-sc-box normal   ">INDEX_NAME TABLE_NAME VISIBILIT<br />
&#8212;&#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;<br />
IDX_ORDERS ORDERS INVISIBLE</div>
<h3>Regular expressions</h3>
<p>A new function REGEXP_COUNT has been inducted into regular expression family from Oracle 11g onwards. The function is efficient to count the occurrences of a pattern in the source string. It returns the count as the numeric output. If the pattern is not found in the source string, the function returns zero.</p>
<p>Example Syntax [4]</p>
<div class="woo-sc-box normal   ">REGEXP_COUNT (SOURCE STRING, PATTERN [,POSITION [, MATCH PARAMETERS]])</div>
<p>Below matching parameters control the search type</p>
<p>. I (ignore case)<br />
. c – Case Sensitive<br />
. m – Allows source string as multiple lines<br />
. n – Allows period.<br />
. x – Ignore white space characters</p>
<p>Example Code [6a]</p>
<p>The SQL query below counts the occurrences of alphabet‘s’ into the source string.</p>
<div class="woo-sc-box normal   ">SQL&gt; WITH C AS (SELECT &#8216;http://sbhoracle.wordpress.com&#8217; str from dual)select regexp_count(str,&#8217;s') from c;</div>
<div class="woo-sc-box normal   ">REGEXP_COUNT(STR,&#8217;S')<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
3</div>
<p>The SQL query below counts the occurrences of alphabet‘s’ into the source string. Note the case use of sensitive parameter ‘I’.</p>
<p>Example Code [6b]</p>
<div class="woo-sc-box normal   ">SQL&gt; WITH C AS (SELECT &#8216;http://Sbhoracle.wordpress.com&#8217; str from dual )select regexp_count(str,&#8217;s',1,&#8217;i') from c<br />
/</div>
<div class="woo-sc-box normal   ">REGEXP_COUNT(STR,&#8217;S',1,&#8217;I')<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
3</div>
<p>The case sensitive match parameter is removed in the below SQL query. The output is the count of only lower case alphabet.</p>
<p>Example Code [6c]</p>
<div class="woo-sc-box normal   ">SQL&gt; WITH C AS (SELECT &#8216;http://Sbhoracle.wordpress.com&#8217; str from dual) select regexp_count(str,&#8217;s') from c<br />
/</div>
<div class="woo-sc-box normal   ">REGEXP_COUNT(STR,&#8217;S')<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
2</div>
<h3>Analytic functions</h3>
<p>In Oracle 11g, LISTAGG and NTH_VALUE are the fresh additions in database analytic family.</p>
<p>LISTAGG ends up a long time crunch of database developers to format multiple rows into single column, while NTH_VALUE extends from FIRST_VALUE and LAST_VALUE functions to accommodate random row number.</p>
<p>Example Syntax [5]</p>
<div class="woo-sc-box normal   ">LISTAGG (measure_expr [, 'delimiter_expr']) WITHIN GROUP (ORDER BY clause) [OVER PARTITION BY clause] NTH_VALUE ( measure_expr,n)[FROM {FIRST | LAST}][{RESPECT | IGNORE } NULLS] OVER (analytic_clause)</div>
<p>Example Code [7]</p>
<p><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Oracle-11g-R2-SQL-Enhancements_img_5.jpg"><img class="aligncenter size-full wp-image-601" title="Oracle 11g R2 SQL Enhancements_img_5" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Oracle-11g-R2-SQL-Enhancements_img_5.jpg" alt="" width="639" height="175" /></a></p>
<p style="text-align: center;">Fig: Usage of LISTAGG analytic function</p>
<p><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Oracle-11g-R2-SQL-Enhancements_img_6.jpg"><img class="aligncenter size-full wp-image-602" title="Oracle 11g R2 SQL Enhancements_img_6" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Oracle-11g-R2-SQL-Enhancements_img_6.jpg" alt="" width="643" height="287" /></a></p>
<p style="text-align: center;">Fig: Usage of NTH_VALUE analytic function</p>
<h3>Language Usability Enhancements</h3>
<h3>DATABASE_ROLE constant for SYS_CONTEXT</h3>
<p>SYS_CONTEXT function is used to retrieve one of the database attributes in a context. Oracle 11g adds one more database property, DATABASE_ROLE to be retrieved using SYS_CONTEXT function in USERENV context.</p>
<p><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Oracle-11g-R2-SQL-Enhancements_img_13.jpg"><img class="aligncenter size-full wp-image-637" title="Oracle 11g R2 SQL Enhancements_img_13" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/06/Oracle-11g-R2-SQL-Enhancements_img_13.jpg" alt="" width="557" height="168" /></a></p>
<h3>Mixed notation for function parameters</h3>
<p>Oracle 11g now allows the function parameters to be passed in mixed format instead of following Named or Positional notation. This enhancement feature eases the code building and customization.</p>
<p>Example Code [8]</p>
<div class="woo-sc-box normal   ">SQL&gt; SELECT FUNC_DBA(P_A =&gt; 10, 20) FROM DUAL;</div>
<h3>SKIP LOCKED clause</h3>
<p>Real time applications often encounter the locking scenarios when working with multiple user session. The deadlock occurs when the table rows locked by one session are queried in another session. Prior to 11g, SELECT FOR UPDATE clause was available to check if the rows are locked for update by any other session. But in cases like explicitly and exclusive locks, SELECT FOR UPDATE used to raise his hands.</p>
<p>Oracle 11g tries to bypass this situation by selecting only the free rows. A new clause SKIP LOCKED has been introduced to select only those rows which are not locked by any of the connected sessions.</p>
<p>Example Code [9]</p>
<div class="woo-sc-box normal   ">SELECT *<br />
FROM EMPLOYEES<br />
FOR UPDATE SKIP LOCKED</div>
<h3>Conclusion</h3>
<div>The codes, explanations and screen dumps posted in the documents are based on my personal works and hands on with Oracle database.</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.dbanotes.com/database-development/oracle-11g-r2-sql-enhancements/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using EXISTS in Oracle SQL Queries</title>
		<link>http://www.dbanotes.com/database-development/using-exists-in-oracle-sql-queries/</link>
		<comments>http://www.dbanotes.com/database-development/using-exists-in-oracle-sql-queries/#comments</comments>
		<pubDate>Sun, 15 May 2011 00:48:07 +0000</pubDate>
		<dc:creator>Contributing Author</dc:creator>
				<category><![CDATA[Database Development]]></category>
		<category><![CDATA[Oracle Database]]></category>
		<category><![CDATA[Oracle11g]]></category>

		<guid isPermaLink="false">http://www.dbanotes.com/?p=526</guid>
		<description><![CDATA[By definition, an operator works with the data items (known as operands) and returns a result. Oracle provides multiple operators under various categories which can be used in queries to filter the result set. In SQL, EXISTS is an operator which can be used in WHERE clause to validate an &#8220;IT EXISTS&#8221; condition. In the [...]]]></description>
			<content:encoded><![CDATA[<p>By definition, an operator works with the data items (known as operands) and returns a result. Oracle provides multiple operators under various categories which can be used in queries to filter the result set. In SQL, EXISTS is an operator which can be used in WHERE clause to validate an &#8220;IT EXISTS&#8221; condition. In the current article, we shall discuss the usage of EXISTS operator and explore the scenarios of tuning with EXISTS.</p>
<h3>Introduction: The EXISTS operator</h3>
<p>EXISTS is a Comparison operator, which is used to check and match records between two queries on correlation basis and returns a BOOLEAN output (TRUE or FALSE). The two queries are designated as the Outer or Parent query and the Sub query.</p>
<p>Note: NOT EXISTS is the negation format of EXISTS.</p>
<p>Example Syntax [1]</p>
<div class="woo-sc-box normal   "><span style="color: #ff0000;">SELECT &lt;columns list&gt; </span><span style="color: #ff0000;"><br />
FROM &lt;Table Name&gt; </span><br />
<span style="color: #ff0000;">WHERE</span> [NOT] EXISTS <span style="color: #339966;">(subquery)</span>;<br />
</div>
<p>Legends: Parent Query in <span style="color: #ff0000;">RED</span>, Subquery in <span style="color: #339966;">GREEN</span>.</p>
<p>Illustration: Consider a scenario where only those employees have to be listed who enjoy the membership of Company Club. Employee and Company Club are two separate entities and are connected through an attribute ‘Employee Id’. The above scenario can be read as the ‘Employees who exist in Company Club’. Practically, it can be done in multiple ways with varying performance stats and scope of extension. The Oracle EXISTS operator can suitably fit into such scenarios which require the check for existence of a parent query record in a subquery.</p>
<p>Example Code [1] achieves it with the use of EXISTS operator.</p>
<p><strong>Example Code [1]</strong></p>
<p><span style="color: #000000;"><div class="woo-sc-box normal   ">SELECT EMPNO, ENAME, DEPARTMENT_ID</span><br />
<span style="color: #000000;"> FROM EMPLOYEE E</span><br />
<span style="color: #000000;"> WHERE EXISTS (SELECT 1 FROM EMP_CLUB WHERE EMPNO = E.EMPNO)</div></span></p>
<h3>Examples</h3>
<p><strong>Example Code [2]: SELECT using EXISTS</strong></p>
<p>Scenario: Display the employee details who are working in New York area.</p>
<p><span style="color: #000000;"><div class="woo-sc-box normal   ">SELECT EMPNO, ENAME, SALARY, DEPARTMENT_ID</span><br />
<span style="color: #000000;"> FROM EMPLOYEES E</span><br />
<span style="color: #000000;"> WHERE EXISTS (SELECT 1</span><br />
<span style="color: #000000;"> FROM DEPARTMENTS D, LOCATIONS L</span><br />
<span style="color: #000000;"> WHERE D.DEPARTMENT_ID = L.DEPARTMENT_ID</span><br />
<span style="color: #000000;"> AND D.DEPARTMENT_ID = E.DEPARTMENT_ID</span><br />
<span style="color: #000000;"> AND L.LOCATION_CODE = ‘NY’)</div></span></p>
<p><strong>Example Code [3]: UPDATE using EXISTS</strong></p>
<p>Scenario: Update the commission of black listed employees to zero.</p>
<div class="woo-sc-box normal   ">UPDATE EMPLOYEES E<br />
SET COMM = 0<br />
WHERE EXISTS (SELECT 1<br />
FROM EMPLOYEES<br />
WHERE EMPNO = E.EMPNO<br />
AND EMP_STATUS = ‘B’)</div>
<p><strong>Example Code [4]: DELETE using EXISTS</strong></p>
<p>Scenario: Delete the employee details from EMP_ARCHIVE table whose age has crossed 60.</p>
<div class="woo-sc-box normal   ">DELETE FROM EMPLOYEES E<br />
WHERE EXISTS (SELECT 1<br />
FROM EMPLOYEES<br />
WHERE EMPNO = E.EMPNO<br />
AND (TO_CHAR(SYSDATE,’YYYY’) – TO_CHAR(EMP_DOB,’YYYY’)) &gt; 60</div>
<p><strong>Example Code [5]: INSERT using EXISTS</strong></p>
<p>Scenario: Add employee details to EMP_ARCHIVE table who are working in New York area.</p>
<div class="woo-sc-box normal   ">INSERT INTO EMP_ARCHIVE (EMPNO, ENAME, SALARY, DEPARTMENT_ID,<br />
JOB_CODE)</div>
<div class="woo-sc-box normal   ">SELECT EMPNO, ENAME, SALARY, DEPARTMENT_ID, JOB_CODE<br />
FROM EMPLOYEES<br />
WHERE EXISTS (SELECT 1<br />
FROM DEPARTMENTS D, LOCATIONS L<br />
WHERE L.DEPARTMENT_ID = D.DEPARTMENT_ID<br />
AND D.DEPARTMENT_ID = E.DEPARTMENT_ID<br />
AND LOCATION_CODE = ‘NY’)</div>
<h3>Performance guidelines with EXISTS operator</h3>
<p>Amazingly, even operator use in SQL statement makes difference in performance of the query. [NOT] EXISTS operator gives best performance when the subquery i.e. driven query contains huge volume of data. The reason is that it follows the principle of ‘At least found’ in queries. It is set to TRUE, if at least one record is found in the subquery correlating with the main driving query, and stops further scanning of the table. Unlike other comparison operators like [NOT] IN, LIKE and others, which returns data for comparison, [NOT] EXISTS return BOOLEAN output.</p>
<p>Illustration: We have ORDERS and PREV_ANN_ORDERS table, which contains current month orders and cumulative previous years’ orders respectively. PREV_ANN_ORDERS contains millions of sales records. We shall try to query the ORDERS which are not yet moved to previous years’ sales data.</p>
<p>Refer to the Example Code [6a] and [6b]</p>
<p>Example Code [6a]</p>
<div class="woo-sc-box normal   ">SELECT COUNT(*)<br />
FROM ORDERS P<br />
WHERE NOT EXISTS (SELECT 1<br />
FROM PREV_ANN_ORDERS<br />
WHERE ORD_ID=P.ID);</div>
<p>Execution Plan<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/05/Using-EXISTS-in-Oracle-SQL-Queries_img_001.jpg"><img class="aligncenter size-large wp-image-567" title="Using EXISTS in Oracle SQL Queries_img_001" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/05/Using-EXISTS-in-Oracle-SQL-Queries_img_001-1024x181.jpg" alt="" width="628" height="111" /></a></p>
<p>If the same query would have used NOT IN operator to achieve the same result, Explain Plan would<br />
reflect the bite in performance as shown in Example Code [6b].</p>
<p>Example Code [6b]</p>
<div class="woo-sc-box normal   ">SELECT COUNT(*)<br />
FROM ORDERS P<br />
WHERE ID NOT IN (SELECT ORD_ID<br />
FROM PREV_ANN_ORDERS);</div>
<p>Execution Plan<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/05/Using-EXISTS-in-Oracle-SQL-Queries_img_01.jpg"><img class="aligncenter size-large wp-image-568" title="Using EXISTS in Oracle SQL Queries_img_01" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/05/Using-EXISTS-in-Oracle-SQL-Queries_img_01-1024x225.jpg" alt="" width="638" height="140" /></a></p>
<p>&nbsp;</p>
<p>Explanation: The EXPLAIN PLAN in Example Code [6a] and [6b] shows quite big difference in ‘Cost’ and ‘Bytes’. The query in Example Code [6a] uses [NOT] EXISTS operator consumes less cost (in step 0) and is relatively faster than the query in Example Code [6b]. In addition, note the difference in the ‘bytes’ returned in step 4 of the Execution Plans. Since EXISTS returns Boolean value, it shows 8 bytes in</p>
<p>Explain Plan [6a], while the IN query returns 893648 bytes of data in Explain Plan [6b].</p>
<h3>A Comparative Study: IN versus EXISTS</h3>
<p>Oracle IN operator and EXISTS operator work for the same purpose i.e. they both check for record correlation between the main query and the sub query. Often, database professionals get interested in debating over the performance of two operators in various scenarios. In this section, we shall compare the working of IN and EXISTS operator.</p>
<p>Before coming on comparative note, we shall have quick walkthrough on IN operator. IN operator can be used in SQL queries in two ways. Firstly, as an INLIST operator, this provides list of fixed values for comparison. Secondly, as a subquery comparator, this uses a subquery to check for record correlation.</p>
<p>Now, we shall execute a simple SQL query in Oracle 9i version and check the difference in their Execution Plans. The query in Example Code [7] and [8] displays the Employee details who are Active member of Company Club.</p>
<p>Example Code [7]</p>
<div class="woo-sc-box normal   ">SQL&gt; SET AUTOTRACE ON<br />
SQL&gt; SELECT EMPNO, ENAME, SALARY<br />
FROM EMPLOYEE<br />
WHERE EMPNO IN (SELECT EMPNO<br />
FROM EMP_CLUB);</div>
<p>Fig 1: Explain plan for Example Code [7]</p>
<p><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/05/Using-EXISTS-in-Oracle-SQL-Queries_img_1.jpg"></a><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/05/Using-EXISTS-in-Oracle-SQL-Queries_img_1.jpg"></a><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/05/Using-EXISTS-in-Oracle-SQL-Queries_img_1.jpg"><img class="aligncenter size-large wp-image-565" title="Using EXISTS in Oracle SQL Queries_img_1" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/05/Using-EXISTS-in-Oracle-SQL-Queries_img_1-1024x255.jpg" alt="" width="667" height="166" /></a></p>
<p>Example Code [8]</p>
<div class="woo-sc-box normal   ">SQL&gt; SET AUTOTRACE ON<br />
SQL&gt; SELECT EMPNO, ENAME, SALARY<br />
FROM EMPLOYEE<br />
WHERE EMPNO EXISTS (SELECT EMPNO<br />
FROM EMP_CLUB);</div>
<p>Fig 2: Explain plan for Example Code [8]</p>
<p><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/05/Using-EXISTS-in-Oracle-SQL-Queries_img_0.jpg"><img class="aligncenter size-full wp-image-564" title="Using EXISTS in Oracle SQL Queries_img_0" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/05/Using-EXISTS-in-Oracle-SQL-Queries_img_0.jpg" alt="" width="627" height="231" /></a></p>
<p>Note the difference between the Explain Plans in Fig (1) and (2) in ‘Consistent gets’ head. Prior to the introduction of CBO (Cost Based Optimizer), Oracle server which used Rule Based Optimizer, used to identify considerable difference between IN and EXISTS operator.</p>
<p>Usually it is worth mentioning as thumb rule that when subquery does the major filtering, IN is more efficient. In other cases, when outer query does the major filtering, EXISTS enhances the query performance.</p>
<p>With the introduction of CBO, the difference has been significantly reduced. The performance orientation with IN operator has been strengthened to match up with EXISTS operator. In major cases, EXISTS and IN show the same TKPROF and EXPLAIN PLAN results. The SQL queries, which use table of huge data volume, are the only candidate to mark the difference between the two.</p>
<p>Now, we shall execute the above queries in Oracle 11g R2 and observe the difference.</p>
<p>Example Code [9]</p>
<div class="woo-sc-box normal   ">SELECT EMPNO, ENAME, SAL<br />
FROM EMPLOYEE<br />
WHERE EMPNO IN (SELECT EMPNO<br />
FROM EMP_CLUB)</div>
<p>Fig 3: Explain plan for Example Code [9]</p>
<p><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/05/Using-EXISTS-in-Oracle-SQL-Queries_img_3.jpg"></a><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/05/Using-EXISTS-in-Oracle-SQL-Queries_img_31.jpg"><img class="aligncenter size-full wp-image-575" title="Using EXISTS in Oracle SQL Queries_img_3" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/05/Using-EXISTS-in-Oracle-SQL-Queries_img_31.jpg" alt="" width="565" height="250" /></a></p>
<p>Example Code [10]</p>
<div class="woo-sc-box normal   ">SELECT EMPNO, ENAME, SAL<br />
FROM EMPLOYEE E<br />
WHERE EXISTS (SELECT 1<br />
FROM EMP_CLUB<br />
WHERE EMPNO = E.EMPNO)</div>
<p>Fig 4: Explain plan for Example Code [10]</p>
<p><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/05/Using-EXISTS-in-Oracle-SQL-Queries_img_4.jpg"><br />
</a><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/05/Using-EXISTS-in-Oracle-SQL-Queries_img_4.jpg"></a><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/05/Using-EXISTS-in-Oracle-SQL-Queries_img_41.jpg"><img class="aligncenter size-full wp-image-576" title="Using EXISTS in Oracle SQL Queries_img_4" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/05/Using-EXISTS-in-Oracle-SQL-Queries_img_41.jpg" alt="" width="559" height="260" /></a></p>
<p>Explain Plan for the two queries shows no difference at all.</p>
<p>Above analysis puts forth the point that optimizer is decisive over the performance in the SQL statements which use IN or EXISTS operator.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbanotes.com/database-development/using-exists-in-oracle-sql-queries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Oracle 11g Sequences</title>
		<link>http://www.dbanotes.com/database-development/using-oracle-11g-sequences/</link>
		<comments>http://www.dbanotes.com/database-development/using-oracle-11g-sequences/#comments</comments>
		<pubDate>Fri, 01 Apr 2011 03:38:51 +0000</pubDate>
		<dc:creator>Contributing Author</dc:creator>
				<category><![CDATA[Database Development]]></category>
		<category><![CDATA[Oracle Database]]></category>
		<category><![CDATA[Oracle11g]]></category>

		<guid isPermaLink="false">http://www.dbanotes.com/?p=482</guid>
		<description><![CDATA[Oracle Sequences have efficiently fulfilled the requirement of generation of unique numbers in a table. They can be casted as Primary Key of a table. In the current article, we shall note the applications of a Sequence, its features and behavior in various scenarios. Introduction Oracle introduced Sequences in its sixth release (Oracle 6) to [...]]]></description>
			<content:encoded><![CDATA[<p>Oracle Sequences have efficiently fulfilled the requirement of generation of unique numbers in a table. They can be casted as Primary Key of a table. In the current article, we shall note the applications of a Sequence, its features and behavior in various scenarios.</p>
<h3>Introduction</h3>
<p>Oracle introduced Sequences in its sixth release (Oracle 6) to serve the purpose of auto generation of continuous numbers in database.</p>
<p>It properly fits into the situations where an entity has to be uniquely identified with a numeric id. For instance, a real time billing process must recognize a unique Bill Id.</p>
<p>Here, manual assignment of Bill Numbers might end up in deadlock and confusion by carrying high risk of id duplication and replication. Oracle Sequences efficiently resolves these situations by generating non recurring numbers in defined order and limit.</p>
<p>Note that it can generate only numeric values. Applications using alphanumeric ids have to embed their own business logic to generate the same.</p>
<h3>Auto generation process: Flashback</h3>
<p>We shall take a small tour of how the things worked out before Oracle introduced Sequences.</p>
<p>For generating record numbers,</p>
<p>Example Code [1]:</p>
<pre><div class="woo-sc-box normal   ">INSERT INTO ORDERS (ID, ORDER_CODE, ORDER_DATE, ORDER_QTY)
VALUES ((SELECT MAX (ID) + 1 FROM ORDERS), ‘DBA’, SYSDATE, 10);</div></pre>
<p>Above INSERT statement shows the generation of ID column values in the ORDERS table. It first selects the maximum ID in ORDERS table and adds 1 to it to generate ID value for the current record.</p>
<p>It is not commendable method where multiple ongoing transactions are involved. This method carries high risk of locking in simultaneous sessions and gap in ID values. IDs for uncommitted transactions would be skipped as unconsidered for henceforth records, thus leading to duplication of ID values.</p>
<h3>The Oracle Sequence: Creation and Usage of Object</h3>
<p>A sequence can be created following the below Example Syntax [1].</p>
<p>Example Syntax [1]</p>
<div class="woo-sc-box normal   ">CREATE SEQUENCE [SEQUENCE NAME]<br />
[INCREMENT BY n]<br />
[START WITH n]<br />
[{MAXVALUE n | NOMAXVALUE}]<br />
[{MINVALUE n | NOMINVALUE}]<br />
[{CYCLE | NOCYCLE}]<br />
[{CACHE n | NOCACHE}]<br />
[{ORDER n | NOORDER}]; </div>
<p>As a pre-requisite, a user must possess CREATE SEQUENCE system privilege to create a sequence. If user is required to create sequence for another user, he must have CREATE ANY SEQUENCE system privilege. These privileges must be granted from the DBA to the user.</p>
<p>Note that unlike other database object definitions, no REPLACE option available for a sequence.</p>
<p>I shall explain the clauses used in the syntax as below.</p>
<ul>
<li>[SEQUENCE NAME] – The Name of the sequence. It shares its namespace with Tables, normal and materialized views, synonyms, procedures, functions, packages, and object types. None of the mentioned objects can carry the same name.</li>
<li>[START WITH n] – This clause specifies the starting point of the sequence. This clause can be used as the minimum value of the sequence. But interestingly, it can also specify a point of start between minimum and maximum value of the sequence. It can contain any value within the limit of 1.0000E+27.</li>
<li>[INCREMENT BY n] – This clause specifies the incremental difference between the two numbers. It can be any definite value except zero. By default, Oracle server treats its value as 1. It can contain any value within the limit of 1.0000E+28.</li>
<li>[MAXVALUE n] – This clause specifies the maximum value attainable by the sequence. It must be greater than MINVALUE and START WITH values.</li>
<li>[NOMAXVALUE] – This clause is the default specification for Maximum value of the sequence. If the clause is specified, the maximum value of a sequence is 1.0000E+28.</li>
<li>[MINVALUE n] – The clause specifies the minimum value of a sequence. It cannot exceed the START WITH value and MAXVALUE.</li>
<li>[NOMINVALUE] – This clause is the default specification of Minimum value of the sequence.</li>
<li>[CYCLE | NOCYCLE] – This clause adds cyclic behavior to a sequence. The sequence recycles the values once the MAXVALUE is reached. It is least relevant if sequence is used as Primary key generator. NOCYCLE is the default behavior.</li>
</ul>
<p>Note: For a cyclic sequence, the sequence must be capable to generate more values than the cache count specified.</p>
<p>Example Code [2]</p>
<div class="woo-sc-box normal   ">SQL&gt; create sequence seq_tst<br />
start with 1<br />
maxvalue 10<br />
cycle<br />
cache 15;</div>
<div class="woo-sc-box normal   ">SQL&gt; /<br />
create sequence seq_tst<br />
*</div>
<p>ERROR at line 1: ORA-04013: number to CACHE must be less than one cycle.</p>
<div class="woo-sc-box normal   ">SQL&gt; create sequence seq_tst<br />
start with 1<br />
maxvalue 10<br />
cycle<br />
cache 8</p>
<p>Sequence created.</div>
<p>In addition, CYCLE avoids run out conditions in sequences by providing roll over support.</p>
<p>[CACHE n| NOCACHE] – This clause directs Oracle server to cache ‘n’ values of a sequence. Its value is 20 by default. NOCACHE is the default behavior of the sequence.</p>
<p>[{ORDER n | NOORDER}] – This clause ensures that sequence values are generated in order. Generally, it is least usable clause in sequence definition but they are helpful in applications which use sequence as timestamp value. All sessions using same sequence share the same cache to fetch the values. NOORDER is the default behavior of the sequence.</p>
<p>All the clauses specified above are optional clauses.</p>
<p>Examples and illustrations</p>
<p>Example Code [3]: Creation of a sequence SEQ_TST. Note that it is the simplest workable non-cyclic sequence whose start value is 1 and moves forward with the increment of 1.</p>
<div class="woo-sc-box normal   ">SQL&gt; create sequence seq_tst;</div>
<p>Sequence created.</p>
<p>Example Code [4]: The sequence below shows that a sequence can maximum generate values up to 1.0000E+28. Further generation of numbers from the sequence leads to Run Out condition. Note that the sequence is created with NOCYCLE option.</p>
<div class="woo-sc-box normal   ">SQL&gt;create sequence seq_tst start with 1000000000000000000000000000</div>
<p>Sequence created.</p>
<div class="woo-sc-box normal   ">SQL&gt; select stt.nextval from dual;</div>
<div class="woo-sc-box normal   ">select stt.nextval from dual</div>
<p>*</p>
<p>ERROR at line 1:</p>
<p>ORA-08004: sequence STT.NEXTVAL exceeds MAXVALUE and cannot be instantiated</p>
<h3>Applications of Sequences</h3>
<p>Auto generation of numbers is the primary objective of a Sequence. It meets the below goals in an application.</p>
<p><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/02/Using-Oracle-11g-Sequences.jpg"></a></p>
<p><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/02/Using-Oracle-11g-Sequences.jpg"><img class="aligncenter size-full wp-image-494" title="Using Oracle 11g Sequences" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/02/Using-Oracle-11g-Sequences.jpg" alt="" width="598" height="366" /></a></p>
<p>Note that if a row is inserted into a table using the sequence generator and the transaction is rolled back, the sequence number would be lost and cannot be retrieved back. This is known as sequence gapping.</p>
<h3>Referencing Sequence in PL/SQL</h3>
<p>In Oracle PL/SQL, NEXTVAL and CURRVAL are the two pseudo columns in Oracle which are used to access the sequence values. NEXTVAL generates the new value of the sequence while CURRVAL displays the current value of the sequence.</p>
<p>Example Syntax [2]:</p>
<div class="woo-sc-box normal   ">Sequence.NEXTVAL<br />
Sequence.CURRVAL</div>
<p>Note that each call to NEXTVAL generates a new value of the sequence while CURRVAL can be called multiple numbers of times as it returns the current value of the sequence without modifying the sequence structure.</p>
<p>In SQL *Plus, they can be selected using SELECT statement to get the inline or current value of the sequence. In PL/SQL block, Oracle 11g made considerable modifications in accessing a sequence.</p>
<h3>Sequence Enhancements in Oracle 11g</h3>
<p>Prior to 11g release, a sequence value must be fetched through a SELECT statement in a memory variable as shown in Example code [5]</p>
<p>Example Code [5]</p>
<div class="woo-sc-box normal   ">DECLARE P_SEQ_VAL NUMBER;<br />
BEGIN<br />
SELECT L_SEQ.NEXTVAL<br />
INTO P_SEQ_VAL<br />
FROM DUAL;<br />
DBMS_OUTPUT.PUT_LINE(‘Sequence Value’||TO_CHAR(P_SEQ_VAL);<br />
SELECT L_SEQ.CURRVAL<br />
INTO P_SEQ_VAL<br />
FROM DUAL;<br />
DBMS_OUTPUT.PUT_LINE(‘Current Value’||TO_CHAR(P_SEQ_VAL);<br />
END;</div>
<p>Oracle 11g allows using NETXVAL and CURRVAL as PL/SQL construct. Refer the example code [6] as below</p>
<p>Example Code [6]</p>
<div class="woo-sc-box normal   ">DECLARE<br />
P_SEQ_VAL NUMBER;<br />
BEGIN<br />
P_SEQ_VAL := L_SEQ.NEXTVAL;<br />
DBMS_OUTPUT.PUT_LINE(‘Sequence Value’||TO_CHAR(P_SEQ_VAL);<br />
P_SEQ_VAL := L_SEQ.CURRVAL;<br />
DBMS_OUTPUT.PUT_LINE(‘Current Value’||TO_CHAR(P_SEQ_VAL);<br />
END;</div>
<h3>Sequence Usage Notes</h3>
<p> In a database session, CURRVAL function cannot be the operated before NEXTVAL as first operation on the sequence. This implies that first operation on a sequence in a session must be NEXTVAL. CURRVAL returns the last cached (generated) value of the sequence by the current session. Once, NEXTVAL fetches the sequence value in a session, CURRVAL is ready for use. Refer the Example Code [7] to illustrate above point.</p>
<p>Example Code [7]</p>
<div class="woo-sc-box normal   ">SQL&gt; CREATE SEQUENCE SQ_CUSTOMERS<br />
START WITH 1<br />
INCREMENT BY 1;</div>
<p>Sequence created.</p>
<div class="woo-sc-box normal   ">SQL&gt; SELECT SQ_CUSTOMERS.CURRVAL FROM DUAL;</div>
<div class="woo-sc-box normal   ">select sq_customers.currval from dual;</div>
<p>*ORA-08002: sequence sq_customers.CURRVAL is not yet defined in this session</p>
<div class="woo-sc-box normal   ">SQL&gt; SELECT SQ_CUSTOMERS.NEXTVAL FROM DUAL;<br />
1</div>
<div class="woo-sc-box normal   ">SQL&gt; SELECT SQ_CUSTOMERS.CURRVAL FROM DUAL;<br />
1 </div>
<p>A Sequence can be referenced in INSERT and UPDATE statements using CURRVAL and NEXTVAL pseudo columns. Refer the Example Code [8].</p>
<p>Example Code [8]</p>
<div class="woo-sc-box normal   ">SQL&gt; INSERT INTO CUSTOMERS<br />
(CUSTOMER_ID, CUSTOMER_NAME, CUSTOMER_CODE, SALES_DATE)<br />
VALUES<br />
(SQ_CUSTOMERS.NEXTVAL,’DBA’,’PUBLICH’, SYSDATE);</div>
<p>1 row inserted.</p>
<div class="woo-sc-box normal   ">SQL&gt; UPDATE ORDERS<br />
SET ORDER_ID = SEQ_ORDERS.NEXTVAL<br />
WHERE TRUNC(ORDER_DATE) = TRUNC(SYSDATE);</div>
<p>10 rows updated.</p>
<p> NEXTVAL generates a new number from the sequence only once for the current row. For multiple subsequent references of the NEXTVAL operation on the same sequence in the same record, it returns same number. Refer the Example Code [9] below.</p>
<p>Example Code [9]</p>
<div class="woo-sc-box normal   ">SQL&gt; CREATE SEQUENCE SEQ_EX START WITH 100;</div>
<div class="woo-sc-box normal   ">SQL&gt; select seq_tst.nextval a1, seq_tst.nextval a2, seq_tst.currval a3, seq_tst.nextval a4<br />
from dual;</div>
<p>A1 A2 A3 A4<br />
&#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;-<br />
101 101 101 101</p>
<p> A Sequence cannot be used in Static statement queries. Static queries include subqueries, view definitions, SELECT statements with DISTINCT, GROUP BY or ORDER BY clause, and queries using SET operators. Additionally, it can also be not used in WHERE clause, CHECK constraints, and DEFAULT value specifications.</p>
<p>Example Code [10]</p>
<p><div class="woo-sc-box normal   ">SQL&gt; create table seqtab (id number default seq_tst.nextval)</div><br />
*<br />
ERROR at line 1: ORA-00984: column not allowed here</p>
<h3>Modifying the Sequence behavior</h3>
<p>Except the START WITH value, all the clause specifications in a sequence definition are subject to change at any moment. A user can ALTER the sequence definition only if he owns the sequence or enjoys ALTER ANY SEQUENCE system privilege. The Example Syntax [3] shows the modifiable clauses of a sequence in ALTER.</p>
<p>Example Syntax [3]</p>
<div class="woo-sc-box normal   ">ALTER SEQUENCE [sequence name]<br />
[INCREMENT BY n]<br />
[MAXVALUE n]<br />
[{MINVALUE n]<br />
[CYCLE | NOCYCLE]<br />
[CACHE n | NOCACHE]<br />
[ORDER n | NOORDER];</div>
<p>Example Code [11]</p>
<p>A sequence SEQ_TST is created with default Minimum and Maximum value. A user can alter the sequence to modify the minimum and maximum value for the sequence.</p>
<p><div class="woo-sc-box normal   ">SQL&gt; CREATE SEQUENCE SEQ_TST START WITH 1;</div><br />
Sequence created.</p>
<p>SQL&gt; SELECT MIN_VALUE, MAX_VALUE, LAST_NUMBER FROM USER_SEQUENCES WHERE SEQUENCE_NAME = &#8216;SEQ_TST&#8217;;</p>
<p>MIN_VALUE MAX_VALUE LAST_NUMBER<br />
&#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;&#8211;<br />
1 1.0000E+28 1</p>
<div class="woo-sc-box normal   ">SQL&gt; ALTER SEQUENCE SEQ_TST MAXVALUE 10;</div>
<p>Sequence altered.</p>
<div class="woo-sc-box normal   ">SQL&gt; SELECT MIN_VALUE, MAX_VALUE, LAST_NUMBER FROM USER_SEQUENCES WHERE SEQUENCE_NAME = &#8216;SEQ_TST&#8217;;</div>
<p>MIN_VALUE MAX_VALUE LAST_NUMBER<br />
&#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;&#8211;<br />
1 10 1</p>
<h3>Dropping the sequence</h3>
<p>A sequence can be dropped from the database using DROP command. DROP is a DDL command which is used to remove database objects from the schema.</p>
<p>Example Syntax [4]</p>
<div class="woo-sc-box normal   ">DROP SEQUENCE [sequence name]</div>
<p>A user dropping a sequence in his schema required DROP SEQUENCE system privilege. To drop a sequence owned by another user, a user must possess DROP ANY SEQUENCE system privilege.</p>
<h3>Sequence Cache</h3>
<p>To achieve better performance in database applications, sequence values can be cached in SGA for faster generation and retrieval of numbers. By default, Oracle server caches 20 values of an Oracle sequence. CACHE option in a sequence definition enables caching of specified number (n) of sequence values.</p>
<p>The ALTER command in Example Code [11] increases the cache size of the sequence to 100. Oracle server allocates 100 sequence values in cache. Once the cache flushes out all the values, it is repopulated with new set of 100 sequence numbers.</p>
<p>Example Code [12]</p>
<div class="woo-sc-box normal   ">SQL&gt; ALTER SEQUENCE SEQ_EX CACHE 100;<br />
Sequence altered.<br />
</div>
<h3>Sequence Metadata</h3>
<p>Oracle server maintains sequence metadata in [ALL | USER] _SEQUENCES data dictionary views. While USER_SEQUENCES stores the metadata only for the sequences, which can be accessed by the specific user, ALL_SEQUENCES maintains the data about all the sequences accessed by the user.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbanotes.com/database-development/using-oracle-11g-sequences/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Oracle 11g New Features for Developers</title>
		<link>http://www.dbanotes.com/database-development/oracle-11g-new-features-for-developers/</link>
		<comments>http://www.dbanotes.com/database-development/oracle-11g-new-features-for-developers/#comments</comments>
		<pubDate>Thu, 03 Feb 2011 02:15:37 +0000</pubDate>
		<dc:creator>Contributing Author</dc:creator>
				<category><![CDATA[Database Development]]></category>
		<category><![CDATA[Oracle11g]]></category>

		<guid isPermaLink="false">http://www.dbanotes.com/?p=433</guid>
		<description><![CDATA[With each and every release, Oracle has tried to provide best database services to the users across the world. Over the period of time and releases, it has become more intelligent, efficient, strong, reliable, flexible and secure. Introduction Oracle 11g Release 2 is the latest release of Oracle in 11g series. Unlike the last release [...]]]></description>
			<content:encoded><![CDATA[<p>With each and every release, Oracle has tried to provide best database services to the users across the world. Over the period of time and releases, it has become more intelligent, efficient, strong, reliable, flexible and secure.</p>
<h3>Introduction</h3>
<p>Oracle 11g Release 2 is the latest release of Oracle in 11g series. Unlike the last release 10g which was more stable and bug free version of 9i, 11g was focused on fresh features, coding enhancements and advanced performance features. Understanding these features is equally important for Oracle professionals for below reasons:</p>
<ol>
<li>Analyze the impact of new features in current database installations</li>
<li>Formulate and implement new coding enhancements to replace workaround solutionsEnhance efficiency of database systems in terms of performance, security, and data storage and estimate future management strategies</li>
<li>Enhance efficiency of database systems in terms of performance, security, and data storage and estimate future management strategies</li>
</ol>
<h3>Oracle 11g: A tour</h3>
<p>To the surprise of Database professionals, Oracle 11g no longer keeps PL/SQL as a pure procedural language. Now PL/SQL is efficient to implement Object Oriented Concepts, thus making it comparable to other programming languages like C++ and JAVA. Similarly, it appears amazing to discover the change in code compilation technique from Interpreted to Native.</p>
<p>Other notable changes is the deprecation of SQL Plus, numerous Enterprise Manager enhancements, code performance enhancements, and adherence to the latest coding standards which make Oracle 11g a uniquely Developer friendly product.</p>
<p>Oracle 11g introduced new features and enhancements in below areas:</p>
<ul>
<li>Performance Improvements</li>
<li>Enhancements to improvise the usability and compatibility of PL/SQL as a language</li>
<li>Include earlier workaround implementations as language features</li>
</ul>
<p>I shall make a fair effort to describe some of these features which are necessary from a Developer’s perception and are relatively, important part of applications.</p>
<h3>Introductory Enhancements</h3>
<p>Deprecation of SQL Plus – Oracle has deprecated the use of SQL Plus (isqlplus and sqlplusw) since Oracle 11g. Besides SQL *Plus, Oracle Workflow, Oracle Enterprise Manager JAVA console, and Oracle Data Mining Scoring Engine are also part of deprecated components from Oracle 11g. Nevertheless, Oracle 11g supports SQL plus through command line and recommends the use of SQL Developer.</p>
<p>Compiler enhancements (Real Native Compilation) &#8211; Oracle 11g PL/SQL compiler is no more dependent on third part C compiler but it can use PL/SQL source code to directly generate the native code. This improves compilation time and results in faster execution. The newly added</p>
<p>PLSQL_CODE_TYPE parameter must be set for native compilation. It can be set as INTERPRETED or COMPILER system or object level. Refer the Example code (1) to switch to NATIVE compiler.</p>
<div class="woo-sc-box normal   ">Example code: (1)<br />
SQL&gt; ALTER SYSTEM SET PLSQL_CODE_TYPE=NATIVE SCOPE=SPFILE;</div>
<p>An object can natively compiled using ALTER command at object level. Refer Example code (2).</p>
<div class="woo-sc-box normal   ">
Example code: (2)<br />
SQL&gt; ALTER PROCEDURE MY_PROC COMPILE PLSQL_CODE_TYPE=NATIVE; </div>
<p>In terms of performance, it is twice as fast as C native compiler.</p>
<p>Case sensitive Passwords – Passwords are made case sensitive with Oracle 11g. They introduced two additional parameters SEC_CASE_SENSITIVE_LOGON, SEC_MAX_FAILED_LOGIN_ATTEMPTS to strengthen the database password security.</p>
<h3>Fresh Additional Features</h3>
<p>Read Only Tables – In Oracle 11g, a table can be set READ ONLY mode to restrict write operations on the table. A table can be altered to toggle over READ ONLY and READ WRITE modes. Refer Example code (3) and (4).</p>
<p>Example code: (3)</p>
<div class="woo-sc-box normal   ">SQL&gt; ALTER TABLE EMP READ ONLY;</div>
<p>Example code: (4)</p>
<div class="woo-sc-box normal   ">SQL&gt; ALTER TABLE EMP READ WRITE;</div>
<p>Invisible Indexes &#8211; Oracle 11g provides flexibility in query performance testing by introducing Invisible Indexes. An Invisible Index can be created to check its effect on the query performance. It can be converted to VISIBLE mode for auto consideration by the optimizer, if it makes major performance impact. An initialization parameter OPTIMIZER_USE_INVISIBLE_INDEXES must be set to TRUE in the session to direct optimizer to use an Invisible Index. Alternatively, using INDEX hint, it can be enforced in the execution plan and query performance can be tested. Example code (5)creates an Invisible Index and SQL query in Example code (6) uses it through a hint to fetch the data.</p>
<p>Example code: (5)</p>
<div class="woo-sc-box normal   ">CREATE INDEX IDX_EMP_NAME ON EMP (ENAME) INVISIBLE;</div>
<p>Example code: (6)</p>
<div class="woo-sc-box normal   ">SELECT /*+ index (ENAME IDX_EMP_NAME) */<br />
FROM EMP<br />
WHERE ENAME LIKE ‘%DBA%’;</div>
<p>If the index usage makes considerable impact on the query performance, the invisible index can be altered to VISIBLE mode. Refer Example code (7).</p>
<p>Example code: (7)</p>
<div class="woo-sc-box normal   ">ALTER INDEX IDX_EMP_NAME VISIBLE;</div>
<p>A VISIBLE index can be switched back to INVISIBLE mode using the ALTER statement as shown in Example code (8)</p>
<p>Example code: (8)</p>
<div class="woo-sc-box normal   ">ALTER INDEX IDX_EMP_NAME INVISIBLE;</div>
<p>Virtual Columns &#8211; Oracle 11g allows a user to create virtual columns in a table whose values are derived automatically from other actual columns of the same table. They show same behavior as other columns in the table in terms of indexing and statistics. Currently, Oracle does not support LOB and RAW values in virtual columns.</p>
<p>Example Syntax: (1)</p>
<div class="woo-sc-box normal   ">column [datatype] [GENERATED ALWAYS] AS (<br />
)<br />
[VIRTUAL] [( inline_constraint [,...] )]</div>
<p>Here, GENERATED ALWAYS and VIRTUAL are optional keywords, but included for more clarity.</p>
<p>A table ORDERS is created with ORDER_VAL_ANN as virtual column, whose value is derived from ORDER_VAL column of the ORDERS table. Refer Example code (9).</p>
<p>Example code: (9)</p>
<div class="woo-sc-box normal   ">CREATE TABLE ORDERS<br />
(ORDER_ID NUMBER PRIMARY KEY,<br />
ORDER_VAL NUMBER<br />
ORDER_VAL_ANN AS (ORDER_VAL*12));</div>
<p>Result Cache in SQL and PL/SQL &#8211; Oracle 11g has introduced a new SGA component (Shared Pool) as Result Cache to retain SQL and PL/SQL results for same set of inputs.</p>
<p>For subsequent executions of the same function, Oracle server directly fetches the result set contained in Result Cache rather than undergoing complete execution process. Logically caching of frequent queries and their result set saves execution time and results in better performance.</p>
<p>Note that it gets invalidated if function definition, or any dependent object undergoes a change.</p>
<p><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/02/oracle11gR2-graph1.jpg"></a></p>
<p style="text-align: center;"><img class="aligncenter" title="Oracle11gR2" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/02/oracle11gR2-graph1.jpg" alt="" width="493" height="306" /></p>
<h6 style="text-align: center;">Fig (1): Graphical comparison of performance upgrade due to Result Caching feature in Oracle 11g</h6>
<p> </p>
<p>Bar chart in Fig (1) shows the impact of Query performance comparison between Oracle 10g and Oracle 11g. Note that Query result caching has reported 25% growth in performance.</p>
<p>Size of result cache is determined by RESULT_CACHE_MAX_SIZE parameter whose value depends on MEMORY_TARGET (0.25%), SGA_TARGET (0.5%), and SHARED_POOL_SIZE (1%) parameters. It can be increased at SYSTEM level but cannot exceed 75% of the shared pool.</p>
<p>Result Cache Mode: Result Cache feature operates in two modes namely, MANUAL (default mode) and FORCE. In MANUAL operation mode, RESULT_CACHE has to be explicitly specified for Oracle to cache the results. In FORCE operation mode, all query result sets are forcibly cached in shared pool until NO_RESULT_CACHE hint is used in the query.</p>
<p>Result Cache in SQL: In SQL, Result cache can be done using a new hint RESULT_CACHE. The SQL statement in Example code (10) returns average salary of each department and caches the result set.</p>
<p>Example code: (10)</p>
<div class="woo-sc-box normal   ">SELECT /*+ result_cache */ DEPARTMENT_ID, AVG(SALARY)<br />
FROM EMP<br />
GROUP BY DEPARTMENT_ID;</div>
<p>Result Cache in PL/SQL: In PL/SQL functions, Result Cache can be achieved by including an additional RESULT_CACHE clause in the function definition. It is optionally followed by RELIES_ON to specify the dependent tables.</p>
<p>The function F_GET_SAL in Example code (11) returns the salary of an employee, whose employee id is passed as a parameter. Note that the return value would be retained by the cache memory for the same set of input i.e. employee id.</p>
<p>Example code: (11)</p>
<div class="woo-sc-box normal   ">CREATE OR REPLACE FUNCTION F_GET_SAL (P_EMPID NUMBER)<br />
RETURN VARCHAR2<br />
RESULT_CACHE RELIES_ON(EMP)<br />
IS<br />
L_SAL NUMBER;<br />
BEGIN<br />
SELECT SALARY<br />
INTO L_SAL<br />
FROM EMP<br />
WHERE EMPLOYEE_ID = P_EMPID;<br />
END;</div>
<p>Compound Trigger &#8211; Oracle 11g introduces Compound Triggers to deal with multiple problems. Being only a DML triggers, it not only it saves lot of code writing, but also resolves the issue where same set of session variables share common data and the famous mutating table error(ORA-04091). In compound trigger logic, all timing point logics are clubbed in one single body. As shown in the<br />
below syntax, order of timing points must be retained.</p>
<p>Example Syntax: (2)</p>
<div class="woo-sc-box normal   ">CREATE TRIGGER trigger_name<br />
FOR [INSERT | UPDATE | DELETE] OF [COLUMN] ON [TABLE]<br />
COMPOUND TRIGGER<br />
BEFORE STATEMENT IS<br />
BEGIN<br />
&#8230;<br />
END BEFORE STATEMENT;<br />
AFTER STATEMENT IS<br />
BEGIN<br />
&#8230;<br />
END AFTER STATEMENT;<br />
BEFORE EACH ROW IS<br />
BEGIN<br />
&#8230;<br />
END BEFORE EACH ROW;<br />
AFTER EACH ROW IS<br />
BEGIN<br />
&#8230;<br />
END AFTER EACH ROW;<br />
END trigger_name;</div>
<p>An additional timing point INSTEAD OF EACH ROW can be included for view triggers.</p>
<p>Set trigger firing order using FOLLOWS &#8211; Oracle 11g enables user to control the order of trigger execution. If multiple triggers are created for the same timing point and event on the same table, it order of execution can be set using FOLLOWS clause. FOLLOWS clause in a trigger specifies that the current trigger would follow the execution of specified triggers.</p>
<p>Example Syntax: (3)</p>
<div class="woo-sc-box normal   ">CREATE [OR REPLACE] TRIGGER TRIGGER_NAME<br />
BEFORE [INSERT | UPDATE | DELETE] ON [TABLE NAME]<br />
FOLLOWS [TRIGGER1, TRIGGER2…]<br />
WHEN</div>
<p>Creating a trigger in DISABLED mode- Prior to Oracle 11g, a trigger can be created in ENABLED mode only. Oracle 11g provides flexibility to create a Trigger in DISABLED mode also. They remain deactivated until they are enabled.</p>
<p>Example Syntax: (4)</p>
<div class="woo-sc-box normal   ">CREATE TRIGGER [TRIGGER NAME]<br />
BEFORE [INSERT | UPDATE | DELETE] ON [TABLE]<br />
DISABLED<br />
WHEN &#8230;</div>
<p>Secure Files to handle Large Objects- Handling of Large Objects has always been an unbounded area in Oracle. Oracle 11g has brought major changes by calling LOB storage as Secure Files. These are completely different from previous LOB data which would be now categorized under Basic Files. SecureFile(s) primarily focuses on performance, space consumption and security of objects. This provides storage scalability and object organization manageability. SecureFile usage policy can be enabled by setting DB_SECUREFILE parameter at SYSTEM level as shown in Example Syntax (5).</p>
<p>Example Syntax: (5)</p>
<div class="woo-sc-box normal   ">ALTER SYSTEM SET DB_SECUREFILE = [PERMITTED | FORCE | ALWAYS |<br />
IGNORE | NEVER]</div>
<p>Example Syntax (6) shows how to store LOBs as SecureFile.</p>
<p>Example Syntax: (6)</p>
<div class="woo-sc-box normal   ">CREATE TABLE employees<br />
( [COLUMN] BLOB )<br />
TABLESPACE tools<br />
LOB ([COLUMN]) STORE AS SECUREFILE<br />
(LOB storage parameters);</div>
<p>Storage parameters are CHUNK, [ENABLE | DISABLE] STORAGE IN ROW, [CACHE |NOCACHE], RETENTION, PCTVERSION, and [LOGGING | NOLOGGING].</p>
<p>Oracle 11g also introduces additional advanced features exclusively for SecureFile(s). These features are Deduplication, Compression and Encryption. These features can be applied individually or independently, but Oracle server follows the hierarchy as Deduplication, Compression and Encryption.</p>
<p>Partitioning Enhancements &#8211; Partitioning was first introduced in Oracle 8 release to achieve scalability and effective data maintenance. Over the period of time, it has emerged as one of the strongest feature for Large Scale Data Warehouses. In earlier version of Oracle, the most common type of Partitioning method used was Range Partitioning. Each Oracle release brings a considerable enhancement in Table Partitioning methods and features.</p>
<p>Oracle 11g introduces below additional partitioning strategies.</p>
<ul>
<li> Extended composite partitioning strategies &#8211; Imposing multiple partitioning methods likeList-Range combination</li>
<li>Virtual column based partitioning &#8211; Partition based on Virtual Column is known as Virtual Colum Based Partitioning</li>
<li>Interval Partitioning &#8211; Extension of Range Partitioning.</li>
<li>REF Partitioning &#8211; The Child table follows the same Partitioning scheme as specified for the parent node through PK-FK.</li>
</ul>
<p>Program Inlining (A new PLSQL_OPTIMIZE_LEVEL) &#8211; Program inlining refers to replacing of the program call with a copy of the program. There can be selective scenarios in cumbersome applications where subprogram inlining improves performance. Prior to Oracle 11g, PLSQL_OPTIMIZE_LEVEL initialization parameter had 1 and 2 as admissible values to make decision over optimizer level. Oracle 11g introduces additional value ‘3’ in the bracket, which directs the optimizer to inline the subprograms at high priority. Note that optimizer does not performs any inlining at level 1, while logical inlining of subprograms at level 2. At level 3, optimizer inlines all the subprograms calls.</p>
<p>A new pragma PRAGMA INLINE has been introduced to specify whether a subprogram call has to be inlines or not. It intakes two parameters namely, subprogram name and [YES | NO].</p>
<p>Regular Expression enhancement REGEXP_COUNT – Oracle 11g adds REGEXP_COUNT as the latest member in the regular expression family. It is used to count the occurrence of a character or string expression in another string.</p>
<p>New Analytic Functions &#8211; Below new Analytic functions were introduced</p>
<ul>
<li>LISTAGG – Prior to Oracle 11g, conversion of rows into columns using a delimiter was done by<br />
workaround solution using XMLAGG or DECODE function. Now, Oracle 11g has introduced</li>
<li>LISTAGG analytic function to aggregate the result set in multiple rows into one single column.. NTH_VALUE – The nth value range in a column can be determined using NTH_VALUE function.</li>
</ul>
<h3>Coding Enhancements</h3>
<p>Fast DML triggers – In Oracle 11g, DML triggers have shown performance upgrade by 25%.</p>
<p>Default Value in Table ALTER command – In the Oracle version earlier than 11g, if a table has to be altered to add a column, the very next step was to update the existent rows to some default value.</p>
<p>Oracle 11g allows providing DEFAULT value for a column during table alteration. This has resolved the overhead of updating column with default value.</p>
<p>Example Syntax: (7)</p>
<div class="woo-sc-box normal   ">ALTER TABLE [TABLE NAME]<br />
ADD [COLUMN] [DATA TYPE] [NOT NULL]<br />
DEFAULT [DEFAULT VALUE]</div>
<p>Sequence Assignment – Prior to Oracle 11g, sequence assignment to a number variable could be done through a SELECT statement only. This was the gray area which could have degraded performance due to context switching from PL/SQL engine to SQL engine. Oracle 11g has transformed this feature of Sequence assignment to a PL/SQL construct. Refer the Example code (12) which demonstrates the Sequence assignment as a PL/SQL construct.</p>
<p>Example code: (12)</p>
<div class="woo-sc-box normal   ">DECLARE<br />
L_ID NUMBER;<br />
BEGIN<br />
L_ID:= TEST_SEQ.NEXTVAL;<br />
END;</div>
<p>Functions in SQL-Named Notation – In Oracle 11g, functions can now be called using Named, Positional and Mixed notation while calling from SQL SELECT statement. For example,</p>
<p>A function F_SUMNUM in Example code (13) accepts two parameters to add them and print the result. Note that it uses Mixed notation of parameter passing in the Function call.</p>
<p>Example code: (13)</p>
<div class="woo-sc-box normal   ">SQL&gt; SELECT F_SUMNUM (P_A =&gt; 10, 20) FROM DUAL;</div>
<p>CONTINUE in FOR LOOP – Prior to Oracle 11g, if a value in an iterating loop has to be ignored,<br />
NULL operation was assigned. Refer the code snippet in Example code (14a)</p>
<p>Example code: (14a)</p>
<div class="woo-sc-box normal   ">…<br />
FOR I IN 100..200<br />
LOOP<br />
IF I IN (100,200) THEN<br />
NULL;<br />
ELSE<br />
SUM:= SUM + I;<br />
END IF;<br />
END LOOP;<br />
…</div>
<p>Oracle 11g identified it as bad code practice to assign NULL operation to the compiler. CONTINUE<br />
statement can be used to direct the pointer to continue its iteration if it matches the ignore condition.<br />
Refer the Example code (14b).</p>
<p>Example code: (14b)</p>
<div class="woo-sc-box normal   ">…<br />
FOR I IN 100..200<br />
LOOP<br />
IF I IN (100,200) THEN<br />
CONTINUE;<br />
ELSE<br />
SUM := SUM + I;<br />
END IF;<br />
END LOOP;<br />
…</div>
<p>WHEN OTHERS compile time warning – Oracle 11g discourages the use of WHEN OTHERS generic exception as it suppresses the important exceptions in the program. In oracle 11g, such code would raise a warning PLW-06009. Note that this is a PL/SQL warning and not an exception. Program continues the execution but traces the coding standard failure.</p>
<p>New data types– Oracle 11g has designed a new data type SIMPLE_INTEGER, SIMPLE_FLOAT, and SIMPLE_DOUBLE keeping in view the hardware requirements and expectations with an Integer value. They are compatible with the native compilation feature of Oracle 11g, which makes supports their faster implementation.</p>
<p>SIMPLE_INTEGER restricts NULL values and provide number range from -2147483648 to 2147483647. Similarly, the other two data types avoid NULL check and data overflow checks, thereby enhancing performance to a notable extent.</p>
<p>Native Dynamic SQL enhancements – Oracle 11g saw through multiple changes in Dynamic SQL<br />
implementation. Few of them are listed below.</p>
<ul>
<li>EXECUTE IMMEDIATE, DBMS_SQL.PARSE() and Ref Cursors can accept String SELECT statements as CLOB. This lifts the 32kb sizing restrictions from SQL statements to be dynamically executed.</li>
<li>DBMS_SQL cursor and a Ref cursor are inter convertible</li>
</ul>
<p>SKIP LOCKED for locked tables – Oracle 11g introduced SKIP LOCKED clause to query the records from the table which are not locked in any other active session of the database. This looks quite similar to exclusive mode of locking. The SQL statement in Example code (15) queries the unlocked records from EMP table</p>
<p>Example code: (15)</p>
<div class="woo-sc-box normal   ">SELECT * FROM EMP FOR UPDATE SKIP LOCKED </div>
<p>IGNORE_ROW_ON_DUPKEY_INDEX Hint for INSERT Statements – In Oracle 11g, the INSERT statements which use other table to load the data can make use of the hint IGNORE_ROW_ON_DUPKEY_INDEX to avoid the unique key conflict with the existing row. It ignores the unique key violation during insertion. It is similar to handling of DUP_VAL_ON_INDEX exception, but comparatively it is slower than a single INSERT statement and carries the overhead of creating a PL/SQL block.</p>
<p>DATABASE_ROLE constant for SYS_CONTEXT – A new parameter is introduced in USERENV namespace which returns the database role currently used by the Oracle server. Possible values of DATABASE_ROLE constant are PRIMARY, PHYSICAL STANDBY, LOGICAL STANDBY, and SNAPSHOT STANDBY.</p>
<p>Example code: (16)</p>
<div class="woo-sc-box normal   ">SELECT sys_context(&#8216;USERENV&#8217;, &#8216;DATABASE_ROLE&#8217;) FROM dual;</div>
<p>Recursive common table expressions – In Oracle 11g, recursive common table expression (CTE) algorithm can be used for multiple utilities on hierarchical data. It can be used as number generator, data of bills of material, chasing many to many relationship data and interestingly Sudoku puzzle.</p>
<p>CTE algorithm is as below.</p>
<ol>
<li> Split the CTE expression into anchor and recursive members.</li>
<li>Run the anchor member(s) creating the first invocation or base result set (T0).</li>
<li>Run the recursive member(s) with Ti as an input and Ti+1 as an output.</li>
<li>Repeat step 3 until an empty set is returned.</li>
<li>Return the result set. This is a UNION ALL of T0 to Tn.</li>
</ol>
<p>NO_DATA_NEEDED new exception – For parallel access and pipelined table functions, ORA-06528 exception was included in predefined exception list as NO_DATA_NEEDED.</p>
<p>Encrypted Tablespace – Encryption of Tablespace was introduced with Oracle 10g version but was deprecated due to multiple existing issues. Tablespace encryption in Oracle 11g extends the concept of Transparent Data Encryption and resolves the limitations of range scan and primary key issues. A new tablespace can be created in Encrypted form, with all of its tables and indexes in Encrypted form.</p>
<p>Available Encryption algorithms are:</p>
<ul>
<li>AES192 Advanced Encryption Standard (the default).</li>
<li>3DES168 Triple Data Encryption Standard 168-bit encryption</li>
<li>AES128(Default) Advanced Encryption Standard 128-bit encryption</li>
<li>AES256 Advanced Encryption Standard 256-bit encryption</li>
</ul>
<p>Example Syntax: (8)</p>
<div class="woo-sc-box normal   ">CREATE TABLESPACE<br />
&#8230;<br />
[ENCRYPTION [USING ]]<br />
DEFAULT STORAGE(ENCRYPT)</div>
<p>Tablespace specification for GTT – Oracle 11g provides provision to specify tablespace for Global Temporary tables. In earlier versions, GTT used to consume current user’s default temporary tablespace.</p>
<p>In Example code (16), a global temporary table G_ORDERS is created on GTT_TEMP tablespace.</p>
<p>Example code: (16)</p>
<div class="woo-sc-box normal   ">CREATE GLOBAL TEMPORARY TABLE G_ORDERS<br />
(ORDER_ID NUMBER,<br />
ORDER_DATE DATE,<br />
ORDER_QTY NUMBER)<br />
ON COMMIT PRESERVE ROWS<br />
TABLESPACE GTT_TEMP;</div>
<h3>More areas of Miscellaneous Interest</h3>
<p>Restore Points in Database – In Oracle 11g, similar to SAVEPOINT in TCL commands, a RESTORE POINT can be created in the Database for a particular SCN or till a timestamp. Example code (17) and (18) show creation of RESTORE POINTS by SCN and TIMESTAMP</p>
<p>Example code: (17)</p>
<div class="woo-sc-box normal   ">SQL&gt; CREATE RESTORE POINT RP_ID AS OF SCN 310000</div>
<p>Example code: (18)</p>
<div class="woo-sc-box normal   ">SQL&gt; CREATE RESTORE POINT RP_ID AS OF TIMESTAMP TO_TIMESTAMP(&#8217;23-JAN-2011&#8242;)</div>
<p>Fine Grained Dependency Tracking – Starting from Oracle 11g Release 1, concept of dependency is enhanced to a much granular level by magnifying logical dimension of the referenced object. If the changes to the referenced object make no consequence on the dependent object, the status of dependent object would remain VALID. This saves time which was earlier consumed in compiling the INVALID units after making any change in the referenced object. In 11g, this feature is majorly implemented for Views and Triggers.</p>
<p>Advanced Compression Option – Oracle 11g can now efficiently compress Structured/Unstructured data, back up data (RMAN), Data pump export files, and network transport data. Having first introduced in Oracle 9i, data compression feature shows major impact on costs, storage system, and memory usage. Oracle 11g takes ahead this feature by aiming to reduce the space occupied by data for OLTP as well as warehouse databases. The graph in Fig (2) demonstrates the differences between Oracle 10g and Oracle 11g on Advanced Compression.</p>
<p><img class="aligncenter" title="Oracle11g Comparison" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/02/Oracle11gR2-graph2.jpg" alt="" width="634" height="355" /></p>
<h6 style="text-align: center;">Fig (2) Graphical comparison of Storage, Query Time, CPU overhead between Oracle 10g and Oracle 11g</h6>
<p> </p>
<p>Compression can be achieved for tablespaces, tables, partitions by associating [NOCOMPRESS |COMPRESS], COMPRESS FOR DIRECT LOAD OPERATIONS, and COMPRESS FOR ALL OPERATIONS options with the definition.</p>
<p>Example Syntax: (9)</p>
<div class="woo-sc-box normal   ">CREATE TABLE [TABLE NAME] COMPRESS FOR ALL OPERATIONS;</div>
<div class="woo-sc-box normal   ">CREATE TABLESPACE [TABLESPACE NAME] DEFAULT COMPRESS FOR ALL<br />
OPERATIONS;</div>
<p>Apart from storage and cost advantages, compression also leaves an impact on performance by reducing disk I/O and buffer cache memory, thereby speeding up table scans. But on the other hand, it also carries a minimal overhead on CPU which less than 3%.</p>
<h3>Conclusion</h3>
<p>I hope my effort to familiarize the Developer’s world with Oracle 11g is satisfactory. We shall discuss above features in detail in my upcoming articles on Oracle 11g, with more code snippets, help texts and descriptions.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbanotes.com/database-development/oracle-11g-new-features-for-developers/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>How do I get a Record Set from a Stored Procedure in Oracle</title>
		<link>http://www.dbanotes.com/database-development/how-do-i-get-a-record-set-from-a-stored-procedure-in-oracle/</link>
		<comments>http://www.dbanotes.com/database-development/how-do-i-get-a-record-set-from-a-stored-procedure-in-oracle/#comments</comments>
		<pubDate>Sat, 30 May 2009 19:48:20 +0000</pubDate>
		<dc:creator>Michael Ritacco</dc:creator>
				<category><![CDATA[Database Development]]></category>
		<category><![CDATA[Oracle Database]]></category>

		<guid isPermaLink="false">http://www.dbanotes.com/?p=259</guid>
		<description><![CDATA[Developers that are familiar with using MS SQL Server eventually get the opportunity to work on a project that is Oracle based. This opportunity sometimes becomes an extremely frustrating time due to the philosophical differences in the approach to database development. I believe it is hard for most developers to transition between the two database platforms, not [...]]]></description>
			<content:encoded><![CDATA[<p>Developers that are familiar with using MS SQL Server eventually get the opportunity to work on a project that is Oracle based. This opportunity sometimes becomes an extremely frustrating time due to the philosophical differences in the approach to database development. I believe it is hard for most developers to transition between the two database platforms, not because one is necessarily better or worse, just because it is too hard for many people to change the way they solve problems once proven methodologies have been established.</p>
<p>These are a few questions that are just about guaranteed to come up during the initial stages of the project:</p>
<p><strong>How do I get a record set from Oracle using a stored procedure?</strong></p>
<blockquote><p>Using a <a href="http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370.pdf">REF_CURSOR</a> you can return a record set/cursor from a stored procedure.</p></blockquote>
<p><strong>Why don&#8217;t stored procedure work the same as in SQL Server?</strong></p>
<blockquote><p>In most cases you just use straight SQL and do not need a stored procedure. In Oracle, using cursors and adhoc SQL is the way. In SQL Server, using cursors and adhoc SQL is to be avoided (generally speaking, there are no absolutes).  Why you need to use a stored procedure for a SQL statement in Oracle must be fully explored. I am not saying you don&#8217;t need one, but the reason is not because that is the way you do it in SQL Server.</p></blockquote>
<p>Please do not even start coding until you have read the following documents:</p>
<ul>
<li><a href="http://www.oracle.com/pls/db111/to_pdf?pathname=server.111/b28318.pdf">Oracle Concepts</a></li>
<li><a href="http://www.oracle.com/pls/db111/to_pdf?pathname=appdev.111/b28843.pdf">2 Day Developer’s Guide</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.dbanotes.com/database-development/how-do-i-get-a-record-set-from-a-stored-procedure-in-oracle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

