<?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</title>
	<atom:link href="http://www.dbanotes.com/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>Thu, 05 Apr 2012 13:26:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Master Advanced PL/SQL concepts with “Oracle Advanced PL/SQL Developer Professional Guide”</title>
		<link>http://www.dbanotes.com/announcements-news/master-advanced-plsql-concepts-with-oracle-advanced-plsql-developer-professional-guide/</link>
		<comments>http://www.dbanotes.com/announcements-news/master-advanced-plsql-concepts-with-oracle-advanced-plsql-developer-professional-guide/#comments</comments>
		<pubDate>Tue, 03 Apr 2012 01:15:36 +0000</pubDate>
		<dc:creator>Michael Ritacco</dc:creator>
				<category><![CDATA[Announcements & News]]></category>
		<category><![CDATA[Database Development]]></category>

		<guid isPermaLink="false">http://www.dbanotes.com/?p=938</guid>
		<description><![CDATA[The Oracle Advanced PL/SQL Developer Professional Guide helps you to master the advanced PL/SQL concepts in Oracle 11g. The book aims to be a sure selection for the Associate level Oracle professionals aspiring for Professional level. The topics covered and demonstrated are in line with the Oracle University prescription for Oracle Professional certification, which justify the [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft" style="border-style: initial; border-color: initial; border-width: 0px;" src="http://www.dbanotes.com/wp/wp-content/uploads/2012/04/7225EN_mockupcover_normal-243x300.jpg" alt="" width="155" height="192" />The <strong>Oracle Advanced PL/SQL Developer Professional Guide</strong> helps you to master the advanced PL/SQL concepts in Oracle 11g.</p>
<p>The book aims to be a sure selection for the Associate level Oracle professionals aspiring for Professional level. The topics covered and demonstrated are in line with the Oracle University prescription for Oracle Professional certification, which justify the version updates to be advanced and not complex. The book is under publication from Packt publishers and all set for its release in May, 2012.</p>
<p>The OCP 1Z0-146 certification is the second milestone for the Associate level Oracle professionals. The journey from Associate to Professional level enhances your reliability and credibility with the Oracle technology, catalyzes your employability, and job effectiveness.</p>
<p>Apart from focusing the certification preparation, the book contains ample demonstrations and best programming practices, which can be employed in day-to-day assignments.</p>
<p>The book aims to cover the advanced features of PL/SQL, which are required to design and optimize the PL/SQL code. The recapitulation of PL/SQL programming and advanced features like collections, external procedures, server side result caching, implementing VPD to enforce row level security, handling large objects and SecureFiles build up a concrete platform for a PL/SQL professional. Apart from the programming, the book makes instrumental recommendations on the usage of development tool SQL Developer, employing best practices in database environments and safeguarding the vulnerable areas in PL/SQL code to avoid code injection.</p>
<p>The book gives a deeper insight to transform the readers from mid-level programmers to professional database designers. The advanced concepts covered through this book would surely agitate the readers to dig upon and explore more on the topics.</p>
<p>The book is on pre sales on Packt’s website, Amazon and all leading technical book distributors. Book details are as below:</p>
<p>ISBN(10): 1849687226<br />
ISBN(13): 978-1-84968-722-5</p>
<p>Place your order from the below links</p>
<p><a title="Buy from Packt Publishing" href="http://www.packtpub.com/oracle-advanced-pl-sql-developer-professional-guide/book">Buy from Packt Publishing</a></p>
<p><a title="Buy from Amazon" href="http://www.amazon.com/Oracle-Advanced-Developer-Professional-Guide/dp/1849687226">Buy from Amazon</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbanotes.com/announcements-news/master-advanced-plsql-concepts-with-oracle-advanced-plsql-developer-professional-guide/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<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 manage and deliver [...]]]></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 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>Looking forward to SQL Server 2012</title>
		<link>http://www.dbanotes.com/sqlserver-database/looking-forward-to-sql-server-2012/</link>
		<comments>http://www.dbanotes.com/sqlserver-database/looking-forward-to-sql-server-2012/#comments</comments>
		<pubDate>Sun, 01 Jan 2012 20:15:44 +0000</pubDate>
		<dc:creator>Michael Ritacco</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL 2012]]></category>

		<guid isPermaLink="false">http://www.dbanotes.com/?p=880</guid>
		<description><![CDATA[I finally got around to installing SQL Server 2012 RC 0 on VMware Fusion 4 yesterday. Like a kid on Christmas, I started looking for the enhancements that do not get much marketing attention, but will improve my development workflow or put an end to some administration pains. This is what I found so far: [...]]]></description>
			<content:encoded><![CDATA[<p>I finally got around to installing SQL Server 2012 RC 0 on VMware Fusion 4 yesterday. Like a kid on Christmas, I started looking for the enhancements that do not get much marketing attention, but will improve my development workflow or put an end to some administration pains.</p>
<p>This is what I found so far:</p>
<ul>
<li>LocalDB</li>
<li>Sequences</li>
<li>SQL users without Instance logins</li>
<li>File Tables</li>
<li>THROW statement</li>
<li>Support for up to 15,000 partitions</li>
<li>Columnstore indexes</li>
<li>User-defined server roles</li>
<li>Default schemas for a Windows NT Group</li>
<li>ad-hoc query paging for SELECT statements</li>
<li>Support for importing and exporting Spatial data types natively using the SSMS Import/Export utility. For those of you wondering, this is a SSMS client enhancement and in my testing export/import of spatial tables worked between two SQL 2008 R2 databases where it would error on any table containing a spatial data type using the SSMS 2008 R2 client. Thank you SQL Dev Team.</li>
</ul>
<h3>New Functions:</h3>
<div>
<p>Conversion functions</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/hh213316(v=SQL.110).aspx">PARSE (Transact-SQL)</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/hh230993(v=SQL.110).aspx">TRY_CONVERT (Transact-SQL)</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/hh213126(v=SQL.110).aspx">TRY_PARSE (Transact-SQL)</a></li>
</ul>
<p>Date and time functions</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/hh213228(v=SQL.110).aspx">DATEFROMPARTS (Transact-SQL)</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/hh213312(v=SQL.110).aspx">DATETIME2FROMPARTS (Transact-SQL)</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/hh213233(v=SQL.110).aspx">DATETIMEFROMPARTS (Transact-SQL)</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/hh231077(v=SQL.110).aspx">DATETIMEOFFSETFROMPARTS (Transact-SQL)</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/hh213020(v=SQL.110).aspx">EOMONTH (Transact-SQL)</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/hh213396(v=SQL.110).aspx">SMALLDATETIMEFROMPARTS (Transact-SQL)</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/hh213398(v=SQL.110).aspx">TIMEFROMPARTS (Transact-SQL)</a></li>
</ul>
<p>Logical functions</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/hh213019(v=SQL.110).aspx">CHOOSE (Transact-SQL)</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/hh213574(v=SQL.110).aspx">IIF (Transact-SQL)</a></li>
</ul>
<p>String functions</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/hh231515(v=SQL.110).aspx">CONCAT (Transact-SQL)</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/hh213505(v=SQL.110).aspx">FORMAT (Transact-SQL)</a></li>
</ul>
</div>
<div>Analytic functions</div>
<div>
<table>
<tbody>
<tr>
<td><a href="http://msdn.microsoft.com/en-us/library/hh231078(v=SQL.110).aspx">CUME_DIST (Transact-SQL)</a></td>
<td><a href="http://msdn.microsoft.com/en-us/library/hh231517(v=SQL.110).aspx">LAST_VALUE (Transact-SQL)</a></td>
<td><a href="http://msdn.microsoft.com/en-us/library/hh231327(v=SQL.110).aspx">PERCENTILE_DISC (Transact-SQL)</a></td>
</tr>
<tr>
<td><a href="http://msdn.microsoft.com/en-us/library/hh213018(v=SQL.110).aspx">FIRST_VALUE (Transact-SQL)</a></td>
<td><a href="http://msdn.microsoft.com/en-us/library/hh213125(v=SQL.110).aspx">LEAD (Transact-SQL)</a></td>
<td><a href="http://msdn.microsoft.com/en-us/library/hh213573(v=SQL.110).aspx">PERCENT_RANK (Transact-SQL)</a></td>
</tr>
<tr>
<td><a href="http://msdn.microsoft.com/en-us/library/hh231256(v=SQL.110).aspx">LAG (Transact-SQL)</a></td>
<td><a href="http://msdn.microsoft.com/en-us/library/hh231473(v=SQL.110).aspx">PERCENTILE_CONT (Transact-SQL)</a></td>
<td></td>
</tr>
</tbody>
</table>
</div>
<div></div>
<h3>Still wishing for:</h3>
<div>
<ul>
<li>ALTER TYPE &#8211; Am I the only one that uses TVPs? Changing the database schema when using TVPs is a dependency nightmare and a mess to deploy the change. VS Ultimate helps, but I will always have reservations with making a change to objects, e.g., all the stored procedures dependent on the TVP, that are not actually having a code change. Please SQL Dev Team, consider prioritizing a usability enhancement for TVPs in the first service pack or R2.</li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.dbanotes.com/sqlserver-database/looking-forward-to-sql-server-2012/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introduction to Oracle Exadata V2</title>
		<link>http://www.dbanotes.com/general/introduction-to-oracle-exadata/</link>
		<comments>http://www.dbanotes.com/general/introduction-to-oracle-exadata/#comments</comments>
		<pubDate>Sat, 01 Oct 2011 02:11:08 +0000</pubDate>
		<dc:creator>Michael Ritacco</dc:creator>
				<category><![CDATA[Database Administration]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Oracle Database]]></category>
		<category><![CDATA[Exadata]]></category>
		<category><![CDATA[Oracle11g]]></category>

		<guid isPermaLink="false">http://www.dbanotes.com/?p=862</guid>
		<description><![CDATA[This post came out of the difficulty to find the information needed to prepare myself for a week long Exadata proof of concept I have scheduled next month at the Oracle Technology Center  in Menlo Park. The topics listed below should confirm your suspicion that there is significant learning and study required to understand Exadata. [...]]]></description>
			<content:encoded><![CDATA[<p>This post came out of the difficulty to find the information needed to prepare myself for a week long Exadata proof of concept I have scheduled next month at the Oracle Technology Center  in Menlo Park.</p>
<p>The topics listed below should confirm your suspicion that there is significant learning and study required to understand Exadata. Outside of the Oracle Database software (which is the same) there is a lot more complexity to operate an Exadata Machine over a tradtional database server running on Linux, UNIX, Windows. Now I know why Oracle had to change the Exadata marketing from an &#8220;appliance&#8221; to a &#8220;machine&#8221;.</p>
<p>I plan to update these notes once the proof of concept is complete and I fully understand all the nuances of Exadata. Until then, consider this a list of topics and source of suggested resources for further study.</p>
<h3>Exadata Infrastructure Components</h3>
<ul>
<li>Database Servers</li>
<li>Storage Servers</li>
<li>InfiniBand</li>
<li>Flash Cache</li>
<li>CELLBOOT USB Flash Drive</li>
</ul>
<h3>Exadata Software Components</h3>
<ul>
<li>Oracle Automatic Storage Management (ASM)</li>
<li>Oracle Real Application Clusters (RAC). Not required but sales will say it is.</li>
<li>Oracle Database</li>
<li>Linux Logical Volume Manager (LVM)</li>
</ul>
<h3>Connectivity</h3>
<ul>
<li>Database Servers connect to Storage Servers using the Intelligent Database protocol (iDB) implementing the “function shipping” architecture.</li>
<li>iDB use the Reliable Datagram Sockets (RDS) protocol. RDS is designed for low latency and low overhead using less significantly less CPU when compared to UDP and TCP.</li>
<li>iDB is based on libskgxp.</li>
</ul>
<h3>Exadata Database Servers</h3>
<ul>
<li>No storage devices are presented to the OS on the Exadata database servers.</li>
</ul>
<h3>Exadata Storage Servers</h3>
<ul>
<li>Storage Indexes contain min and max values for up to eight columns.</li>
<li>Storage Indexes are 1MB (default) units. Identify locations where the data is not “Reverse Index”. Best for sorted data.</li>
</ul>
<h3>Exadata Smart Scan (Offloading)</h3>
<ul>
<li>Column Projection</li>
<li>Predicate Filtering</li>
<li>Storage Indexes</li>
<li>Bloom Filters</li>
<li>SQL Functions (most single row functions can be offloaded)</li>
<li>Compression and Decompression</li>
<li>Encryption/Decryption</li>
</ul>
<p>Smart Scans not available on:</p>
<ul>
<li>Clustered tables</li>
<li>Index Organized Tabes (IOTs)</li>
<li>When ROWDEPENDENCIES is enabled</li>
</ul>
<h3>Compression Types</h3>
<p><strong>Basic</strong></p>
<ul>
<li>Compression unit is a single Oracle block. 0% PCTFREE</li>
</ul>
<p><strong>OLTP (Advanced Compression)</strong></p>
<ul>
<li>Compression same as basic but uses symbol table to replace repeating values. 10 % PCTFREE for updates</li>
</ul>
<p><strong>Hybrid Columnar Compression (Exadata Storage Only)</strong></p>
<ul>
<li>QUERY LOW uses LZO compression (4x)</li>
<li>QUERY HIGH uses ZLIB compression (6x)</li>
<li>ARCHIVE LOW uses ZLIP compression (7x)</li>
<li>ARCHIVE HIGH uses bzip2 compression (12x)</li>
</ul>
<p>Compression should not be used on tables or partitions where data is updated due to contention.</p>
<h3>Exadata Backup and Recovery</h3>
<ul>
<li>RMAN incremental backups benefit from the storage servers filtering out unchanged blocks.</li>
</ul>
<h3>Recommended Reading:</h3>
<ul>
<li><a href="http://www.amazon.com/gp/product/1430233923/ref=as_li_tf_tl?ie=UTF8&amp;tag=oraclenotescombo&amp;linkCode=as2&amp;camp=217145&amp;creative=399373&amp;creativeASIN=1430233923">Expert Oracle Exadata</a><img style="border: none !important; margin: 0px !important;" src="http://www.assoc-amazon.com/e/ir?t=oraclenotescombo&amp;l=as2&amp;o=1&amp;a=1430233923&amp;camp=217145&amp;creative=399373" alt="" width="1" height="1" border="0" /></li>
<li><a href="http://www.amazon.com/gp/product/0071752595/ref=as_li_tf_tl?ie=UTF8&amp;tag=oraclenotescombo&amp;linkCode=as2&amp;camp=217145&amp;creative=399381&amp;creativeASIN=0071752595">Achieving Extreme Performance with Oracle Exadata (Osborne ORACLE Press Series)</a><img style="border: none !important; margin: 0px !important;" src="http://www.assoc-amazon.com/e/ir?t=oraclenotescombo&amp;l=as2&amp;o=1&amp;a=0071752595&amp;camp=217145&amp;creative=399381" alt="" width="1" height="1" border="0" /></li>
<li><a title="Technical Overview of Oracle Exadata" href="http://http://www.oracle.com/technetwork/database/exadata/exadata-technical-whitepaper-134575.pdf">A Technical Overview of the Oracle Exadata Database Machine and Exadata Storage Server </a></li>
<li><a title="Oracle Exadata Price List" href="http://www.oracle.com/us/corporate/pricing/exadata-pricelist-070598.pdf">Oracle Exadata Price List</a></li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbanotes.com/general/introduction-to-oracle-exadata/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>Google Malware Warning</title>
		<link>http://www.dbanotes.com/announcements-news/google-malware-warning/</link>
		<comments>http://www.dbanotes.com/announcements-news/google-malware-warning/#comments</comments>
		<pubDate>Sun, 04 Sep 2011 21:50:03 +0000</pubDate>
		<dc:creator>Michael Ritacco</dc:creator>
				<category><![CDATA[Announcements & News]]></category>

		<guid isPermaLink="false">http://www.dbanotes.com/wp/?p=755</guid>
		<description><![CDATA[The dbanotes.com site was a recent victim of a published security vulnerability found in the framework our WordPress theme leverages, and as a result, may have been advertising malware to visitors. While we applied the security patch as quickly as possible, we were unfortunately attacked prior to the security patch being published. However, we take [...]]]></description>
			<content:encoded><![CDATA[<p>The dbanotes.com site was a recent victim of a published security vulnerability found in the framework our WordPress theme leverages, and as a result, may have been advertising malware to visitors. While we applied the security patch as quickly as possible, we were unfortunately attacked prior to the security patch being published.</p>
<p>However, we take security very seriously and have performed the necessary response to protect our visitors.</p>
<p>At this time we have notified Google of our actions, and are waiting for Google to perform another scan to give dbanotes.com a clean bill of health.</p>
<p style="text-align: left;">As of Sunday, Sept. 4, 2011, if you get the following browser malware warning you may safely choose to ignore it.</p>
<p style="text-align: left;"><a href="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/googlewarning.png"><img class="alignnone size-full wp-image-756" title="googlewarning" src="http://www.dbanotes.com/wp/wp-content/uploads/2011/09/googlewarning.png" alt="" width="566" height="271" /></a></p>
<p style="text-align: left;"><strong>What was our response to the Security Exploit </strong>?<br />
We rebuilt the entire dbanotes.com site from scratch. New database, new WordPress installation, new Theme installation, and a clean import of all content from backup.</p>
<p>If you still feel you are at risk of getting malware from visiting dbanotes.com, I encourage you to wait until Google removes the official malware warning.</p>
<p>Thank you for your continued support.</p>
<p>Regards,<br />
dbanotes.com</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbanotes.com/announcements-news/google-malware-warning/feed/</wfw:commentRss>
		<slash:comments>2</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>6</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>
	</channel>
</rss>

