<?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>ViralPatel.net &#187; Database</title> <atom:link href="http://viralpatel.net/blogs/category/database/feed" rel="self" type="application/rss+xml" /><link>http://viralpatel.net/blogs</link> <description>Tutorials, Java, J2EE, Struts, AJAX, JavaScript, CSS, Web 2.0, MySQL, Articles</description> <lastBuildDate>Tue, 24 Jan 2012 13:45:10 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <item><title>How To Reset MySQL Autoincrement Column</title><link>http://viralpatel.net/blogs/2011/12/reseting-mysql-autoincrement-column.html</link> <comments>http://viralpatel.net/blogs/2011/12/reseting-mysql-autoincrement-column.html#comments</comments> <pubDate>Thu, 22 Dec 2011 07:31:38 +0000</pubDate> <dc:creator>Viral Patel</dc:creator> <category><![CDATA[Database]]></category> <category><![CDATA[MySQL]]></category> <category><![CDATA[database indexes]]></category> <category><![CDATA[How-To]]></category> <category><![CDATA[mysqldump]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2473</guid> <description><![CDATA[MySQL database provides a wonderful feature of Autoincrement Column index. Your database table can define its primary key as Autoincrement number and MySQL will take care of its unique value while inserting new rows. Each time you add a new row, MySQL increments the value automatically and persist it to table. But sometime you may [...]]]></description> <content:encoded><![CDATA[<p><img src="http://img.viralpatel.net/mysql-logo.png" alt="mysql-logo" title="mysql-logo" width="187" height="118" class="alignright size-full wp-image-669" />MySQL database provides a wonderful feature of <a href="http://viralpatel.net/blogs/2008/12/get-autoincrement-value-after-insert-query-in-mysql.html">Autoincrement Column</a> index. Your database table can define its primary key as Autoincrement number and MySQL will take care of its unique value while inserting new rows.</p><p>Each time you add a new row, MySQL increments the value automatically and persist it to table. But sometime you may want to reset the Autoincrement column value to 1. Say you writing a sample application and you have inserted few rows already in the table. Now you want to delete these rows and reset the autoincrement column to 1 so that new row which you insert will have primary key value 1.</p><p>There are few methods to achieve this.</p><h2>1. Directly Reset Autoincrement Value</h2><p>Alter table syntax provides a way to reset autoincrement column. Take a look at following example.</p><pre class="brush: sql; gutter: false; title: ; notranslate">
ALTER TABLE table_name AUTO_INCREMENT = 1;
</pre><p>Note that you cannot reset the counter to a value less than or equal to any that have already been used. For MyISAM, if the value is less than or equal to the maximum value currently in the AUTO_INCREMENT column, the value is reset to the current maximum plus one. For InnoDB, if the value is less than the current maximum value in the column, no error occurs and the current sequence value is not changed.</p><h2>2. Truncate Table</h2><p>Truncate table automatically reset the Autoincrement values to 0.</p><pre class="brush: sql; gutter: false; title: ; notranslate">
TRUNCATE TABLE table_name;
</pre><p>Use this with caution. When Truncation is used, it resets any AUTO_INCREMENT counter to zero. From MySQL 5.0.13 on, the AUTO_INCREMENT counter is reset to zero by TRUNCATE TABLE, regardless of whether there is a foreign key constraint.</p><p>Once TRUNCATE is fired, the table handler does not remember the last used AUTO_INCREMENT value, but starts counting from the beginning. This is true even for MyISAM and InnoDB, which normally do not reuse sequence values.</p><h2>3. Drop &#038; Recreate Table</h2><p>This is another way of reseting autoincrement index. Although not very desirable.</p><pre class="brush: sql; gutter: false; title: ; notranslate">
DROP TABLE table_name;
CREATE TABLE table_name { ... };
</pre><p>All these techniques are value techniques to reset autoincrement column number. Use whatever suits your requirement.</p><p><strong>Disclaimer:</strong> The above commands can delete all your data! Be very very cautious.</p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2009/01/mysql-database-backup-mysql-mysqldump-backup-command.html" title="MySQL Database Backup using mysqldump command.">MySQL Database Backup using mysqldump command.</a></li><li><a href="http://viralpatel.net/blogs/2009/04/full-text-search-using-mysql-full-text-search-capabilities.html" title="Full-Text Search using MySQL: Full-Text Search Capabilities">Full-Text Search using MySQL: Full-Text Search Capabilities</a></li><li><a href="http://viralpatel.net/blogs/2008/12/how-to-reset-mysql-root-password.html" title="How to: Reset MySQL root password">How to: Reset MySQL root password</a></li><li><a href="http://viralpatel.net/blogs/2008/12/get-autoincrement-value-after-insert-query-in-mysql.html" title="Get Autoincrement value after INSERT query in MySQL">Get Autoincrement value after INSERT query in MySQL</a></li><li><a href="http://viralpatel.net/blogs/2008/11/mysql-change-root-password.html" title="MySQL Change root Password">MySQL Change root Password</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-many-to-many-annotation-mapping-tutorial.html" title="Hibernate Many To Many Annotation Mapping Tutorial">Hibernate Many To Many Annotation Mapping Tutorial</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-many-to-many-xml-mapping-example.html" title="Hibernate Many To Many XML Mapping Tutorial">Hibernate Many To Many XML Mapping Tutorial</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2011/12/reseting-mysql-autoincrement-column.html/feed</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Hibernate One To One Mapping Tutorial (XML Mapping)</title><link>http://viralpatel.net/blogs/2011/11/hibernate-one-to-one-mapping-tutorial-xml-mapping.html</link> <comments>http://viralpatel.net/blogs/2011/11/hibernate-one-to-one-mapping-tutorial-xml-mapping.html#comments</comments> <pubDate>Tue, 15 Nov 2011 08:10:56 +0000</pubDate> <dc:creator>Viral Patel</dc:creator> <category><![CDATA[Hibernate]]></category> <category><![CDATA[MySQL]]></category> <category><![CDATA[hibernate-configuration]]></category> <category><![CDATA[maven]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2200</guid> <description><![CDATA[Let us understand how One-to-one mapping works in Hibernate. Following is a simply yet concept building example where we will understand One-to-one mapping in Hibernate framework using XML Mappings. We will use two tables &#8220;employee&#8221; and &#8220;employeedetail&#8221; which exhibits one-to-one relationship. Using Hibernate we will implement this relationship. Tools and technologies used in this article: [...]]]></description> <content:encoded><![CDATA[<p>Let us understand how One-to-one mapping works in Hibernate. Following is a simply yet concept building example where we will understand One-to-one mapping in Hibernate framework using XML Mappings. We will use two tables &#8220;employee&#8221; and &#8220;employeedetail&#8221; which exhibits one-to-one relationship. Using Hibernate we will implement this relationship.<br /><style>#hibernate_tutorial_list{background-color:#EF9;padding:5px;border-radius:10px;color:#222;width:98%;font-size:90%}#hibernate_tutorial_list ul
li{padding:3px
0px}#hibernate_tutorial_list ul li
li{padding:2px
0px}</style><div id="hibernate_tutorial_list"><h3>Hibernate Tutorial Series</h3><ul><li><a href="http://viralpatel.net/blogs/2011/11/introduction-to-hibernate-framework-architecture.html">Introduction to Hibernate Framework</a></li><li><a href="http://viralpatel.net/blogs/2011/11/hibernate-maven-mysql-hello-world-example-xml-mapping.html">Hibernate Maven MySQL Hello World example (XML Mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/11/hibernate-hello-world-example-annotation.html">Hibernate Maven MySQL Hello World example (Annotation)</a></li><li>Understanding Relationship Mapping<ul><li><a href="http://viralpatel.net/blogs/2011/11/hibernate-one-to-one-mapping-tutorial-xml-mapping.html">One To One Mapping example (XML Mapping)</a></li><li><a href="http://viralpatel.net/blogs/2214/hibernate-one-to-one-mapping-tutorial-using-annotation">One To One Mapping example (Annotation)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-one-to-many-xml-mapping-tutorial.html">One To Many Mapping example (XML Mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-one-to-many-annotation-tutorial.html">One To Many Mapping example (Annotation)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-many-to-many-xml-mapping-example.html">Many To Many Mapping example (XML Mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-many-to-many-annotation-mapping-tutorial.html">Many To Many Mapping example (Annotation)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-self-join-annotations-one-to-many-mapping.html">Self-Join One To Many Annotations Mapping example</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-self-join-annotation-mapping-many-to-many-example.html">Self-Join Many To Many Annotations Mapping example</a></li></ul></li><li>Inheritance in Hibernate<ul><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-inheritence-table-per-hierarchy-mapping.html">One Table Per Class Hierarchy (Annotation & XML mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-inheritance-table-per-subclass-annotation-xml-mapping.html">One Table Per Subclass (Annotation & XML mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-inheritance-table-per-concrete-class-annotation-xml-mapping.html">One Table Per Concrete Class (Annotation & XML mapping)</a></li></ul></li></ul></div></p><p>Tools and technologies used in this article:</p><ol><li>Java JDK 1.5 above</li><li>MySQL 5 above</li><li>Eclipse 3.2 above</li><li>Hibernate 3 above</li><li>Maven 3 above</li></ol><h2>1. Create Database</h2><p>We will use MySQL in our example. Create two tables &#8220;employee&#8221; and &#8220;employeedetail&#8221; with One-to-one relationship. Following is the SQL script for same.</p><pre class="brush: sql; title: ; notranslate">
/* EMPLOYEE table */
CREATE TABLE `employee` (
	`employee_id` BIGINT(10) NOT NULL AUTO_INCREMENT,
	`firstname` VARCHAR(50) NULL DEFAULT NULL,
	`lastname` VARCHAR(50) NULL DEFAULT NULL,
	`birth_date` DATE NOT NULL,
	`cell_phone` VARCHAR(15) NOT NULL,
	PRIMARY KEY (`employee_id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT
AUTO_INCREMENT=216

/* EMPLOYEEDETAIL table */
CREATE TABLE `employeedetail` (
	`employee_id` BIGINT(20) NOT NULL AUTO_INCREMENT,
	`street` VARCHAR(50) NULL DEFAULT NULL,
	`city` VARCHAR(50) NULL DEFAULT NULL,
	`state` VARCHAR(50) NULL DEFAULT NULL,
	`country` VARCHAR(50) NULL DEFAULT NULL,
	PRIMARY KEY (`employee_id`),
	CONSTRAINT `FKEMPL` FOREIGN KEY (`employee_id`) REFERENCES `employee` (`employee_id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT
AUTO_INCREMENT=216
</pre><p>Note that a one-to-one relationships occurs when one entity is related to exactly one occurrence in another entity. Thus, there will be one primary key which will be mapped with both the entities.</p><h2>2. Hibernate Maven dependency</h2><p>Following dependencies we will use in Maven which will add Hibernate support.</p><p><i>File: /pom.xml</i></p><pre class="brush: xml; title: ; notranslate">
&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot;&gt;
	&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
	&lt;groupId&gt;net.viralpatel.hibernate&lt;/groupId&gt;
	&lt;artifactId&gt;HibernateHelloWorldXML&lt;/artifactId&gt;
	&lt;packaging&gt;jar&lt;/packaging&gt;
	&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
	&lt;name&gt;HibernateHelloWorldXML&lt;/name&gt;
	&lt;url&gt;http://maven.apache.org&lt;/url&gt;
	&lt;dependencies&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;mysql&lt;/groupId&gt;
			&lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
			&lt;version&gt;5.1.10&lt;/version&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.hibernate&lt;/groupId&gt;
			&lt;artifactId&gt;hibernate&lt;/artifactId&gt;
			&lt;version&gt;3.2.6.ga&lt;/version&gt;
		&lt;/dependency&gt;
	&lt;/dependencies&gt;
&lt;/project&gt;
</pre><p><br/></p><h2>3. Hibernate Model class</h2><p>For this example we will create two Model class: Employee.java and EmployeeDetail.java. Add following in your project.</p><p><i>File: /src/main/java/net/viralpatel/hibernate/Employee.java</i></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.hibernate;

import java.sql.Date;

public class Employee {

	private Long employeeId;
	private String firstname;
	private String lastname;
	private Date birthDate;
	private String cellphone;
	private EmployeeDetail employeeDetail;

	public Employee() {

	}

	public Employee(String firstname, String lastname, Date birthdate,
			String phone) {
		this.firstname = firstname;
		this.lastname = lastname;
		this.birthDate = birthdate;
		this.cellphone = phone;
	}

	// Getter and Setter methods
}
</pre><p><br/><br /> <i>File: /src/main/java/net/viralpatel/hibernate/EmployeeDetail.java</i></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.hibernate;

public class EmployeeDetail {

	private Long employeeId;
	private String street;
	private String city;
	private String state;
	private String country;

	private Employee employee;

	public EmployeeDetail() {

	}

	public EmployeeDetail(String street, String city, String state, String country) {
		this.street = street;
		this.city = city;
		this.state = state;
		this.country = country;
	}

	// Getter and Setter methods	

}
</pre><p>Note that in above model classes, employeeId is common. This is the primary key of Employee table that exhibits One-to-one relationship with EmployeeDetail table.</p><h2>4. Hibernate XML Mapping (HBM)</h2><p>Add following hibernate mapping (hbm) files <code>Employee.hbm.xml</code> and <code>EmployeeDetail.hbm.xml</code> for the model classes created in above steps.</p><p><i>File: /src/main/java/net/viralpatel/hibernate/Employee.hbm.xml</i></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE hibernate-mapping PUBLIC
        &quot;-//Hibernate/Hibernate Mapping DTD 3.0//EN&quot;
        &quot;http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&quot;&gt;

&lt;hibernate-mapping package=&quot;net.viralpatel.hibernate&quot;&gt;

	&lt;class name=&quot;Employee&quot; table=&quot;EMPLOYEE&quot;&gt;
		&lt;id name=&quot;employeeId&quot; column=&quot;EMPLOYEE_ID&quot;&gt;
			&lt;generator class=&quot;native&quot; /&gt;
		&lt;/id&gt;
		&lt;one-to-one name=&quot;employeeDetail&quot; class=&quot;net.viralpatel.hibernate.EmployeeDetail&quot;
			cascade=&quot;save-update&quot;&gt;&lt;/one-to-one&gt;

		&lt;property name=&quot;firstname&quot; /&gt;
		&lt;property name=&quot;lastname&quot; column=&quot;lastname&quot; /&gt;
		&lt;property name=&quot;birthDate&quot; type=&quot;date&quot; column=&quot;birth_date&quot; /&gt;
		&lt;property name=&quot;cellphone&quot; column=&quot;cell_phone&quot; /&gt;

	&lt;/class&gt;
&lt;/hibernate-mapping&gt;
</pre><p><i>File: /src/main/java/net/viralpatel/hibernate/EmployeeDetail.hbm.xml</i></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE hibernate-mapping PUBLIC
        &quot;-//Hibernate/Hibernate Mapping DTD 3.0//EN&quot;
        &quot;http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&quot;&gt;

&lt;hibernate-mapping package=&quot;net.viralpatel.hibernate&quot;&gt;

    &lt;class name=&quot;EmployeeDetail&quot; table=&quot;EMPLOYEEDETAIL&quot;&gt;

 		&lt;id name=&quot;employeeId&quot; type=&quot;java.lang.Long&quot;&gt;
			&lt;column name=&quot;EMPLOYEE_ID&quot; /&gt;
			&lt;generator class=&quot;foreign&quot;&gt;
				&lt;param name=&quot;property&quot;&gt;employee&lt;/param&gt;
			&lt;/generator&gt;
		&lt;/id&gt;
		&lt;one-to-one name=&quot;employee&quot; class=&quot;net.viralpatel.hibernate.Employee&quot;
			constrained=&quot;true&quot;&gt;&lt;/one-to-one&gt;

        &lt;property name=&quot;street&quot; column=&quot;STREET&quot;/&gt;
        &lt;property name=&quot;city&quot; column=&quot;CITY&quot;/&gt;
        &lt;property name=&quot;state&quot; column=&quot;STATE&quot;/&gt;
        &lt;property name=&quot;country&quot; column=&quot;COUNTRY&quot;/&gt;
	&lt;/class&gt;

&lt;/hibernate-mapping&gt;
</pre><p>Note that in above hibernate mapping we are implementing One-to-one relationship. For both the model classes we are using a single primary key EmployeeId. In EmployeeDetail hbm file we have defined a foreign identifier generator so that primary it uses primary key of Employee table.</p><h2>5. Hibernate Configuration</h2><p>Following is the hibernate configuration hibernate.cfg.xml file. Add this in your project.</p><p><i>File: /src/main/resources/hibernate.cfg.xml</i></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version='1.0' encoding='utf-8'?&gt;
&lt;!DOCTYPE hibernate-configuration PUBLIC
        &quot;-//Hibernate/Hibernate Configuration DTD 3.0//EN&quot;
        &quot;http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd&quot;&gt;

&lt;hibernate-configuration&gt;
    &lt;session-factory&gt;
        &lt;property name=&quot;connection.driver_class&quot;&gt;com.mysql.jdbc.Driver&lt;/property&gt;
        &lt;property name=&quot;connection.url&quot;&gt;jdbc:mysql://localhost:3306/tutorial&lt;/property&gt;
        &lt;property name=&quot;connection.username&quot;&gt;root&lt;/property&gt;
        &lt;property name=&quot;connection.password&quot;&gt;&lt;/property&gt;

        &lt;property name=&quot;connection.pool_size&quot;&gt;1&lt;/property&gt;
        &lt;property name=&quot;dialect&quot;&gt;org.hibernate.dialect.MySQLDialect&lt;/property&gt;
        &lt;property name=&quot;current_session_context_class&quot;&gt;thread&lt;/property&gt;
        &lt;property name=&quot;cache.provider_class&quot;&gt;org.hibernate.cache.NoCacheProvider&lt;/property&gt;
        &lt;property name=&quot;show_sql&quot;&gt;true&lt;/property&gt;
        &lt;property name=&quot;hbm2ddl.auto&quot;&gt;validate&lt;/property&gt;

        &lt;mapping resource=&quot;net/viralpatel/hibernate/EmployeeDetail.hbm.xml&quot;/&gt;
        &lt;mapping resource=&quot;net/viralpatel/hibernate/Employee.hbm.xml&quot;/&gt;

    &lt;/session-factory&gt;
&lt;/hibernate-configuration&gt;
</pre><p><br/></p><h2>6. Hibernate Utility class</h2><p><i>File:/src/main/java/net/viralpatel/hibernate/HibernateUtil.java</i></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.hibernate;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

    private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            return new Configuration()
            		.configure()
                    .buildSessionFactory();
        } catch (Throwable ex) {
            System.err.println(&quot;Initial SessionFactory creation failed.&quot; + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}
</pre><p></br></p><h2>7. Main class to test One-to-one mapping</h2><p>Add following Main.java class in your project to test One-to-one relationship mapping functionality.</p><p><i>File:/src/main/java/net/viralpatel/hibernate/Main.java</i></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.hibernate;

import java.sql.Date;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

public class Main {

	public static void main(String[] args) {

		SessionFactory sf = HibernateUtil.getSessionFactory();
		Session session = sf.openSession();
		session.beginTransaction();

		EmployeeDetail employeeDetail = new EmployeeDetail(&quot;10th Street&quot;, &quot;LA&quot;, &quot;San Francisco&quot;, &quot;U.S.&quot;);

		Employee employee = new Employee(&quot;Nina&quot;, &quot;Mayers&quot;, new Date(121212),
				&quot;114-857-965&quot;);
		employee.setEmployeeDetail(employeeDetail);
		employeeDetail.setEmployee(employee);

		session.save(employee);

		List&lt;Employee&gt; employees = session.createQuery(&quot;from Employee&quot;).list();
		for (Employee employee1 : employees) {
			System.out.println(employee1.getFirstname() + &quot; , &quot;
					+ employee1.getLastname() + &quot;, &quot;
					+ employee1.getEmployeeDetail().getState());
		}

		session.getTransaction().commit();
		session.close();

	}
}
</pre><p><br/></p><h2>8. Review Project Structure</h2><p>Below is the final project structure with all the source files.</p><p><img src="http://img.viralpatel.net/2011/11/hibernate-one-to-one-example-project-structure.png" alt="hibernate-one-to-one-example-project-structure" title="hibernate-one-to-one-example-project-structure" width="290" height="376" class="aligncenter size-full wp-image-2201" /></p><p><br/></p><h2>8. Execute the example</h2><p>Execute the Main class. Hibernate will insert a row in Employee and EmployeeDetail table.</p><p><i>Output:</i></p><pre class="brush: xml; title: ; notranslate">
Hibernate: insert into EMPLOYEE (firstname, lastname, birth_date, cell_phone) values (?, ?, ?, ?)
Hibernate: insert into EMPLOYEEDETAIL (STREET, CITY, STATE, COUNTRY, EMPLOYEE_ID) values (?, ?, ?, ?, ?)
Hibernate: select employee0_.EMPLOYEE_ID as EMPLOYEE1_1_, employee0_.firstname as firstname1_, employee0_.lastname as lastname1_, employee0_.birth_date as birth4_1_, employee0_.cell_phone as cell5_1_ from EMPLOYEE employee0_
Hibernate: select employeede0_.EMPLOYEE_ID as EMPLOYEE1_0_0_, employeede0_.STREET as STREET0_0_, employeede0_.CITY as CITY0_0_, employeede0_.STATE as STATE0_0_, employeede0_.COUNTRY as COUNTRY0_0_ from EMPLOYEEDETAIL employeede0_ where employeede0_.EMPLOYEE_ID=?
Nina , Mayers, San Francisco
</pre><h2>That&#8217;s All Folks</h2><p>Today we saw how to write Hibernate program and implements One-to-one relationship mapping using XML mappings. We used Maven to generate Java project and added Hibernate dependencies into it.</p><h2>Download Source</h2><p><b><a href="http://viralpatel.net/blogs/download/hibernate/Hibernate-One-to-one-tutorial-XML-Mapping.zip">Hibernate-One-to-one-tutorial-XML-Mapping.zip (9 kb)</a></b><br /> <br/></p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2011/11/hibernate-maven-mysql-hello-world-example-xml-mapping.html" title="Hibernate Maven MySQL Hello World example (XML Mapping)">Hibernate Maven MySQL Hello World example (XML Mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-many-to-many-annotation-mapping-tutorial.html" title="Hibernate Many To Many Annotation Mapping Tutorial">Hibernate Many To Many Annotation Mapping Tutorial</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-many-to-many-xml-mapping-example.html" title="Hibernate Many To Many XML Mapping Tutorial">Hibernate Many To Many XML Mapping Tutorial</a></li><li><a href="http://viralpatel.net/blogs/2214/hibernate-one-to-one-mapping-tutorial-using-annotation" title="Hibernate One To One Annotation Mapping Tutorial">Hibernate One To One Annotation Mapping Tutorial</a></li><li><a href="http://viralpatel.net/blogs/2011/11/hibernate-hello-world-example-annotation.html" title="Hibernate Hello World example using Annotation">Hibernate Hello World example using Annotation</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-inheritance-table-per-subclass-annotation-xml-mapping.html" title="Hibernate Inheritance: Table Per Subclass (Annotation &#038; XML mapping)">Hibernate Inheritance: Table Per Subclass (Annotation &#038; XML mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-one-to-many-annotation-tutorial.html" title="Hibernate One To Many Annotation tutorial">Hibernate One To Many Annotation tutorial</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2011/11/hibernate-one-to-one-mapping-tutorial-xml-mapping.html/feed</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Hibernate Maven MySQL Hello World example (XML Mapping)</title><link>http://viralpatel.net/blogs/2011/11/hibernate-maven-mysql-hello-world-example-xml-mapping.html</link> <comments>http://viralpatel.net/blogs/2011/11/hibernate-maven-mysql-hello-world-example-xml-mapping.html#comments</comments> <pubDate>Tue, 08 Nov 2011 06:33:39 +0000</pubDate> <dc:creator>Viral Patel</dc:creator> <category><![CDATA[Hibernate]]></category> <category><![CDATA[MySQL]]></category> <category><![CDATA[hibernate-architecture]]></category> <category><![CDATA[hibernate-configuration]]></category> <category><![CDATA[maven]]></category> <category><![CDATA[xml]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2190</guid> <description><![CDATA[In this tutorial, we will try to write a small hello world program using Hibernate, MySQL and Maven. We will create a Java project using Maven and will then try to add Hibernate on it. Following are the tools and technologies used in this project. Java JDK 5 or above Eclipse IDE 3.2 or above [...]]]></description> <content:encoded><![CDATA[<p>In this tutorial, we will try to write a small hello world program using Hibernate, MySQL and Maven. We will create a Java project using Maven and will then try to add Hibernate on it.<br /><style>#hibernate_tutorial_list{background-color:#EF9;padding:5px;border-radius:10px;color:#222;width:98%;font-size:90%}#hibernate_tutorial_list ul
li{padding:3px
0px}#hibernate_tutorial_list ul li
li{padding:2px
0px}</style><div id="hibernate_tutorial_list"><h3>Hibernate Tutorial Series</h3><ul><li><a href="http://viralpatel.net/blogs/2011/11/introduction-to-hibernate-framework-architecture.html">Introduction to Hibernate Framework</a></li><li><a href="http://viralpatel.net/blogs/2011/11/hibernate-maven-mysql-hello-world-example-xml-mapping.html">Hibernate Maven MySQL Hello World example (XML Mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/11/hibernate-hello-world-example-annotation.html">Hibernate Maven MySQL Hello World example (Annotation)</a></li><li>Understanding Relationship Mapping<ul><li><a href="http://viralpatel.net/blogs/2011/11/hibernate-one-to-one-mapping-tutorial-xml-mapping.html">One To One Mapping example (XML Mapping)</a></li><li><a href="http://viralpatel.net/blogs/2214/hibernate-one-to-one-mapping-tutorial-using-annotation">One To One Mapping example (Annotation)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-one-to-many-xml-mapping-tutorial.html">One To Many Mapping example (XML Mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-one-to-many-annotation-tutorial.html">One To Many Mapping example (Annotation)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-many-to-many-xml-mapping-example.html">Many To Many Mapping example (XML Mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-many-to-many-annotation-mapping-tutorial.html">Many To Many Mapping example (Annotation)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-self-join-annotations-one-to-many-mapping.html">Self-Join One To Many Annotations Mapping example</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-self-join-annotation-mapping-many-to-many-example.html">Self-Join Many To Many Annotations Mapping example</a></li></ul></li><li>Inheritance in Hibernate<ul><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-inheritence-table-per-hierarchy-mapping.html">One Table Per Class Hierarchy (Annotation & XML mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-inheritance-table-per-subclass-annotation-xml-mapping.html">One Table Per Subclass (Annotation & XML mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-inheritance-table-per-concrete-class-annotation-xml-mapping.html">One Table Per Concrete Class (Annotation & XML mapping)</a></li></ul></li></ul></div></p><p>Following are the tools and technologies used in this project.</p><ol><li>Java JDK 5 or above</li><li>Eclipse IDE 3.2 or above</li><li>Maven 3.0 or above</li><li>Hibernate 3.0 or above</li><li>MySQL 5.0 or above</li></ol><h2>1. Database Creation</h2><p>For this tutorial, we will create a simple table &#8220;employe&#8221; in MySQL. Use following script to create the table.</p><pre class="brush: sql; title: ; notranslate">
CREATE TABLE `employee` (
	`id` BIGINT(10) NOT NULL AUTO_INCREMENT,
	`firstname` VARCHAR(50) NULL DEFAULT NULL,
	`lastname` VARCHAR(50) NULL DEFAULT NULL,
	`birth_date` DATE NOT NULL,
	`cell_phone` VARCHAR(15) NOT NULL,
	PRIMARY KEY (`id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT
AUTO_INCREMENT=606
</pre><p>Thus, following will be the connection string to connect with MySQL.</p><pre>
Connection URL:	jdbc:mysql://localhost:3306/tutorial
DB Username:	root
DB Password:	<your mysql password>
</pre><h2>2. Generate Maven Java project compatible with Eclipse</h2><p>Open a command prompt and execute following code to generate a Maven Java project.</p><pre class="brush: java; title: ; notranslate">
mvn archetype:generate \
	-DgroupId=net.viralpatel.hibernate \
	-DartifactId=HibernateHelloWorldXML \
	-DarchetypeArtifactId=maven-archetype-quickstart \
	-DinteractiveMode=false
</pre><p>Once you execute above command, a project &#8220;HibernateHelloWorldXML&#8221; is created. Note that this is a Java project which already has folder structures compatible to Maven.</p><p>Once this is done, we will convert it to be compatible with Eclipse. For that executes following command on command prompt.</p><pre class="brush: java; title: ; notranslate">
mvn eclipse:eclipse
</pre><h2>3. Import project in Eclipse</h2><p>Open Eclipse and import the above Java project.</p><pre>
File > Import... > General > Existing Projects into Workspace > Choose above Java project
</pre><p>Once imported, the folder structure will look like following:</p><p><img src="http://img.viralpatel.net/2011/11/hibernate-maven-blank-folder-structure.png" alt="hibernate-maven-blank-folder-structure" title="hibernate-maven-blank-folder-structure" width="240" height="308" class="aligncenter size-full wp-image-2191" /></p><h4>Important:</h4><p>In case you get following error after importing project in Eclipse:<br /> <img src="http://img.viralpatel.net/2011/11/hibernate-maven-repo-error.png" alt="hibernate-maven-repo-error" title="hibernate-maven-repo-error" width="604" height="110" class="aligncenter size-full wp-image-2194" /></p><p>If you are getting this Hibernate Maven Repo error, then you need to define <strong>M2_REPO</strong> environment variable in eclipse pointing to your local maven repository.</p><p>Goto Window > Preferences&#8230; > Java > Build Path > Classpath Variables > Define new variable M2_REPO pointing to your local maven repository.<br /> <img src="http://img.viralpatel.net/2011/11/eclipse-maven-repo-environment-variable.png" alt="eclipse-maven-repo-environment-variable" title="eclipse-maven-repo-environment-variable" width="569" height="368" class="aligncenter size-full wp-image-2193" /></p><p>Once you will define this variable and rebuild the project, the above error will go.</p><h2>4. Add Hibernate Dependency to Maven pom.xml</h2><p>Add following dependencies to Maven pom.xml.</p><pre class="brush: xml; title: ; notranslate">
&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
  xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot;&gt;
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  &lt;groupId&gt;net.viralpatel.hibernate&lt;/groupId&gt;
  &lt;artifactId&gt;HibernateHelloWorldXML&lt;/artifactId&gt;
  &lt;packaging&gt;jar&lt;/packaging&gt;
  &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
  &lt;name&gt;HibernateHelloWorldXML&lt;/name&gt;
  &lt;url&gt;http://maven.apache.org&lt;/url&gt;
  &lt;dependencies&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;mysql&lt;/groupId&gt;
      &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
      &lt;version&gt;5.1.10&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
      &lt;artifactId&gt;hibernate&lt;/artifactId&gt;
      &lt;version&gt;3.2.6.ga&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;junit&lt;/groupId&gt;
      &lt;artifactId&gt;junit&lt;/artifactId&gt;
      &lt;version&gt;3.8.1&lt;/version&gt;
      &lt;scope&gt;test&lt;/scope&gt;
    &lt;/dependency&gt;
  &lt;/dependencies&gt;
&lt;/project&gt;
</pre><p>Once we have added these dependencies, we will execute following command so that maven will download required Jar files and add the same to eclipse classpath.</p><pre class="brush: java; title: ; notranslate">
mvn eclipse:eclipse
</pre><p>The above step is not mandatory. If you have Maven plugin for Eclipse installed in your IDE (Latest eclipse comes with this plugin built-in) you can just enable Maven dependencies by doing<br /> Right click on project > Maven > Enable Dependency Management.</p><h2>5. Add Hibernate Configuration XML</h2><p>Now our project setup is ready. We will add following Hibernate configuration xml file in <b>/src/main/resources</b> folder. Note that this folder is not present in your project structure.</p><p>Create a source folder:<br /> Right click on Project > New > Source Folder > Give folder name &#8220;/src/main/resources/&#8221; and click Finish.</p><p>Copy following file in your project.</p><p><i>File: /src/main/resources/hibernate.cfg.xml</i></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version='1.0' encoding='utf-8'?&gt;
&lt;!DOCTYPE hibernate-configuration PUBLIC
        &quot;-//Hibernate/Hibernate Configuration DTD 3.0//EN&quot;
        &quot;http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd&quot;&gt;

&lt;hibernate-configuration&gt;
    &lt;session-factory&gt;
        &lt;!-- Database connection settings --&gt;
        &lt;property name=&quot;connection.driver_class&quot;&gt;com.mysql.jdbc.Driver&lt;/property&gt;
        &lt;property name=&quot;connection.url&quot;&gt;jdbc:mysql://localhost:3306/tutorial&lt;/property&gt;
        &lt;property name=&quot;connection.username&quot;&gt;root&lt;/property&gt;
        &lt;property name=&quot;connection.password&quot;&gt;&lt;/property&gt;

        &lt;!-- JDBC connection pool (use the built-in) --&gt;
        &lt;property name=&quot;connection.pool_size&quot;&gt;1&lt;/property&gt;

        &lt;!-- SQL dialect --&gt;
        &lt;property name=&quot;dialect&quot;&gt;org.hibernate.dialect.MySQLDialect&lt;/property&gt;

        &lt;!-- Enable Hibernate's automatic session context management --&gt;
        &lt;property name=&quot;current_session_context_class&quot;&gt;thread&lt;/property&gt;

        &lt;!-- Disable the second-level cache  --&gt;
        &lt;property name=&quot;cache.provider_class&quot;&gt;org.hibernate.cache.NoCacheProvider&lt;/property&gt;

        &lt;!-- Echo all executed SQL to stdout --&gt;
        &lt;property name=&quot;show_sql&quot;&gt;false&lt;/property&gt;

        &lt;property name=&quot;hbm2ddl.auto&quot;&gt;validate&lt;/property&gt;

        &lt;mapping resource=&quot;net/viralpatel/hibernate/Employee.hbm.xml&quot;/&gt;

    &lt;/session-factory&gt;
&lt;/hibernate-configuration&gt;
</pre><p>One thing we need to make sure in Eclipse is that the Java build path must reflect **/*.xml.<br /> Right click on project > Properties > Java Build Path > Source > Add **/*.xml as follow:<br /> <img src="http://img.viralpatel.net/2011/11/hibernate-java-build-path-include-xml.png" alt="hibernate-java-build-path-include-xml" title="hibernate-java-build-path-include-xml" width="523" height="374" class="aligncenter size-full wp-image-2195" /></p><h2>6. Add Java source code</h2><p><i>File: /src/main/java/net/viralpatel/hibernate/Employee.java</i></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.hibernate;

import java.sql.Date;

public class Employee {

	private Long id;

	private String firstname;

	private String lastname;

	private Date birthDate;

	private String cellphone;

	public Employee() {

	}

	public Employee(String firstname, String lastname, Date birthdate, String phone) {
		this.firstname = firstname;
		this.lastname = lastname;
		this.birthDate = birthdate;
		this.cellphone = phone;

	}

	// Getter and Setter methods

}
</pre><p>Above is the Employee POJO class that we will use to fetch data from Employee table. This Java class will be mapped by Hiberate with Employee table. Note that we have define two constructors first default and second with arguements. The second constructor is optional. But note that you must define a default (No-arguement) constructor in your mapping class.</p><p><i>File: /src/main/java/net/viralpatel/hibernate/HibernateUtil.java</i></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.hibernate;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

    private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            return new Configuration()
            		.configure()
                    .buildSessionFactory();
        } catch (Throwable ex) {
            System.err.println(&quot;Initial SessionFactory creation failed.&quot; + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}
</pre><p>As discussed in previous article <a href="http://viralpatel.net/blogs/2011/11/introduction-to-hibernate-framework-architecture.html" target="_new">Introduction to Hibernate framework</a>, we have to create SessionFactory instance in order to communicate with Database in Hibernate. We will use a Utility class called HibernateUtil to instantiate SessionFactory.</p><p><i>File: /src/main/java/net/viralpatel/hibernate/Employee.hbm.xml</i></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE hibernate-mapping PUBLIC
        &quot;-//Hibernate/Hibernate Mapping DTD 3.0//EN&quot;
        &quot;http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&quot;&gt;

&lt;hibernate-mapping package=&quot;net.viralpatel.hibernate&quot;&gt;

    &lt;class name=&quot;Employee&quot; table=&quot;EMPLOYEE&quot;&gt;
 		&lt;id name=&quot;id&quot; column=&quot;ID&quot;&gt;
            &lt;generator class=&quot;native&quot;/&gt;
        &lt;/id&gt;
        &lt;property name=&quot;firstname&quot; /&gt;
        &lt;property name=&quot;lastname&quot; column=&quot;lastname&quot;/&gt;
        &lt;property name=&quot;birthDate&quot; type=&quot;date&quot; column=&quot;birth_date&quot;/&gt;
        &lt;property name=&quot;cellphone&quot; column=&quot;cell_phone&quot;/&gt;
	&lt;/class&gt;

&lt;/hibernate-mapping&gt;
</pre><h2>7. CRUD operations in Hibernate</h2><p>Let us see the basic CRUD operation in Hibernate. We will use Employee table for this.</p><h4>7.1 Writing (Create) data in Hibernate</h2><p>Following is the code snippet that insert a row in database.</p><pre class="brush: java; title: ; notranslate">
private static Employee save(Employee employee) {
	SessionFactory sf = HibernateUtil.getSessionFactory();
	Session session = sf.openSession();
	session.beginTransaction();

	Long id = (Long) session.save(employee);
	employee.setId(id);

	session.getTransaction().commit();

	session.close();

	return employee;
}

...
...
...

// Call the save() method to insert a record in database.
System.out.println(&quot;******* WRITE *******&quot;);
Employee empl = new Employee(&quot;Jack&quot;, &quot;Bauer&quot;, new Date(System.currentTimeMillis()), &quot;911&quot;);
empl = save(empl);
</pre><h4>7.2 Reading (Read) data in Hibernate</h2><p>Below code snippet demos read functionality in Hibernate. Note that there are two methods one to list all the employees and other to read details about just one.</p><pre class="brush: java; title: ; notranslate">
private static List list() {
	SessionFactory sf = HibernateUtil.getSessionFactory();
	Session session = sf.openSession();

	List employees = session.createQuery(&quot;from Employee&quot;).list();
	session.close();
	return employees;
}
private static Employee read(Long id) {
	SessionFactory sf = HibernateUtil.getSessionFactory();
	Session session = sf.openSession();

	Employee employee = (Employee) session.get(Employee.class, id);
	session.close();
	return employee;
}
</pre><h4>7.3 Updating (Update) data in Hibernate</h2><p>Following is the code snippet to update a record in Hibernate.</p><pre class="brush: java; title: ; notranslate">
private static Employee update(Employee employee) {
	SessionFactory sf = HibernateUtil.getSessionFactory();
	Session session = sf.openSession();

	session.beginTransaction();

	session.merge(employee);

	session.getTransaction().commit();

	session.close();
	return employee;

}
</pre><h4>7.4 Remove (Delete) data in Hibernate</h2><p>Following is code snippet to remove a record in Hibernate.</p><pre class="brush: java; title: ; notranslate">
private static void delete(Employee employee) {
	SessionFactory sf = HibernateUtil.getSessionFactory();
	Session session = sf.openSession();

	session.beginTransaction();

	session.delete(employee);

	session.getTransaction().commit();

	session.close();
}
</pre><p>We have created a file Main.java which will test all these functionality. Following is the complete source code of Main.java.<br /> <i>File: /src/main/java/net/viralpatel/hibernate/Main.java</i></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.hibernate;

import java.sql.Date;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

public class Main {

	public static void main(String[] args) {

		// Read
		System.out.println(&quot;******* READ *******&quot;);
		List employees = list();
		System.out.println(&quot;Total Employees: &quot; + employees.size());

		// Write
		System.out.println(&quot;******* WRITE *******&quot;);
		Employee empl = new Employee(&quot;Jack&quot;, &quot;Bauer&quot;, new Date(System.currentTimeMillis()), &quot;911&quot;);
		empl = save(empl);
		empl = read(empl.getId());
		System.out.printf(&quot;%d %s %s \n&quot;, empl.getId(), empl.getFirstname(), empl.getLastname());

		// Update
		System.out.println(&quot;******* UPDATE *******&quot;);
		Employee empl2 = read(1l); // read employee with id 1
		System.out.println(&quot;Name Before Update:&quot; + empl2.getFirstname());
		empl2.setFirstname(&quot;James&quot;);
		update(empl2);	// save the updated employee details

		empl2 = read(1l); // read again employee with id 1
		System.out.println(&quot;Name Aftere Update:&quot; + empl2.getFirstname());

		// Delete
		System.out.println(&quot;******* DELETE *******&quot;);
		delete(empl);
		Employee empl3 = read(empl.getId());
		System.out.println(&quot;Object:&quot; + empl3);
	}

	private static List list() {
		SessionFactory sf = HibernateUtil.getSessionFactory();
		Session session = sf.openSession();

		List employees = session.createQuery(&quot;from Employee&quot;).list();
		session.close();
		return employees;
	}
	private static Employee read(Long id) {
		SessionFactory sf = HibernateUtil.getSessionFactory();
		Session session = sf.openSession();

		Employee employee = (Employee) session.get(Employee.class, id);
		session.close();
		return employee;
	}
	private static Employee save(Employee employee) {
		SessionFactory sf = HibernateUtil.getSessionFactory();
		Session session = sf.openSession();

		session.beginTransaction();

		Long id = (Long) session.save(employee);
		employee.setId(id);

		session.getTransaction().commit();

		session.close();

		return employee;
	}

	private static Employee update(Employee employee) {
		SessionFactory sf = HibernateUtil.getSessionFactory();
		Session session = sf.openSession();

		session.beginTransaction();

		session.merge(employee);

		session.getTransaction().commit();

		session.close();
		return employee;

	}

	private static void delete(Employee employee) {
		SessionFactory sf = HibernateUtil.getSessionFactory();
		Session session = sf.openSession();

		session.beginTransaction();

		session.delete(employee);

		session.getTransaction().commit();

		session.close();
	}

}
</pre><h2>8. Final project structure</h2><p>Once you have created all these source files, your project structure should look like following. Note that we have removed the default App.java and AppTest.java generated by Maven as we dont these files.<br /> <img src="http://img.viralpatel.net/2011/11/hibernate-maven-final-project-structure.png" alt="hibernate-maven-final-project-structure" title="hibernate-maven-final-project-structure" width="263" height="307" class="aligncenter size-full wp-image-2196" /></p><h2>9. Execute project</h2><p>Execute the Main.java class and see output.</p><pre class="brush: xml; title: ; notranslate">
******* READ *******
Total Employees: 200
******* WRITE *******
201 Jack Bauer
******* UPDATE *******
Name Before Update:Paula
Name Aftere Update:James
******* DELETE *******
Object:null
</pre><h2>That&#8217;s All Folks</h2><p>Today we saw how to write our first Hibernate hello world example using XML Configuration. We used Maven to generate Java project and added Hibernate dependencies into it. Also we saw how to do different CRUD operations in Hibernate.</p><h2> Download Source</h2><p><b><a href="http://viralpatel.net/blogs/download/hibernate/HibernateHelloWorldXML.zip">HibernateHelloWorldXML.zip (8 kb)</a></b></p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2011/11/hibernate-one-to-one-mapping-tutorial-xml-mapping.html" title="Hibernate One To One Mapping Tutorial (XML Mapping)">Hibernate One To One Mapping Tutorial (XML Mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-inheritance-table-per-concrete-class-annotation-xml-mapping.html" title="Hibernate Inheritance: Table Per Concrete Class (Annotation &#038; XML mapping)">Hibernate Inheritance: Table Per Concrete Class (Annotation &#038; XML mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-inheritance-table-per-subclass-annotation-xml-mapping.html" title="Hibernate Inheritance: Table Per Subclass (Annotation &#038; XML mapping)">Hibernate Inheritance: Table Per Subclass (Annotation &#038; XML mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-many-to-many-annotation-mapping-tutorial.html" title="Hibernate Many To Many Annotation Mapping Tutorial">Hibernate Many To Many Annotation Mapping Tutorial</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-many-to-many-xml-mapping-example.html" title="Hibernate Many To Many XML Mapping Tutorial">Hibernate Many To Many XML Mapping Tutorial</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-one-to-many-annotation-tutorial.html" title="Hibernate One To Many Annotation tutorial">Hibernate One To Many Annotation tutorial</a></li><li><a href="http://viralpatel.net/blogs/2214/hibernate-one-to-one-mapping-tutorial-using-annotation" title="Hibernate One To One Annotation Mapping Tutorial">Hibernate One To One Annotation Mapping Tutorial</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2011/11/hibernate-maven-mysql-hello-world-example-xml-mapping.html/feed</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Oracle 11G new feature: Virtual Column</title><link>http://viralpatel.net/blogs/2011/02/oracle-11g-new-feature-virtual-column.html</link> <comments>http://viralpatel.net/blogs/2011/02/oracle-11g-new-feature-virtual-column.html#comments</comments> <pubDate>Wed, 23 Feb 2011 09:07:22 +0000</pubDate> <dc:creator>Anuj Parashar</dc:creator> <category><![CDATA[Database]]></category> <category><![CDATA[Featured]]></category> <category><![CDATA[Oracle]]></category> <category><![CDATA[oracle-11g]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2158</guid> <description><![CDATA[Oracle 11g introduced the concept of &#8216;Virtual Column&#8217; within a table. Virtual Columns are similar to normal table&#8217;s columns but with the following differences: They are defined by an expression. The result of evaluation of this expression becomes the value of the column. The values of the virtual column are not stored in the database. [...]]]></description> <content:encoded><![CDATA[<p><img src="http://img.viralpatel.net/2010/06/oracle-logo.jpg" alt="" width="268" height="41" class="alignright size-full wp-image-2070" /> Oracle 11g introduced the concept of &#8216;Virtual Column&#8217; within a table. Virtual Columns are similar to normal table&#8217;s columns but with the following differences:</p><ul><li>They are defined by an expression. The result of evaluation of this expression becomes the value of the column.</li><li>The values of the virtual column are not stored in the database. Rather, it&#8217;s computed at run-time when you query the data.</li><li>You can&#8217;t update (in SET clause of update statement) the values of virtual column. These are read only values, that are computed dynamically and any attempt to modify them will result into oracle error.</li></ul><p>The syntax for defining a virtual column is:</p><pre class="brush: sql; title: ; notranslate">
column_name [datatype] [GENERATED ALWAYS] AS [expression] [VIRTUAL]
</pre><p>where the parameters within [] are optional and can be omitted. If you don&#8217;t mention the datatype, Oracle will decide it based on the result of the expression.</p><p>Excepting the above points, a virtual column, exists just like any other column of a normal table and the following points apply to it:</p><ol><li>Virtual columns can be used in the WHERE clause of UPDATE and DELETE statement but they can&#8217;t be modified by DML.</li><li>Statistics can be collected on them.</li><li>They can be used as a partition key in virtual column based partitioning.</li><li>Indexes can be created on them. As you might have guessed, oracle would create function based indexes as we create on normal tables.</li><li>Constraints can be created on them.</li></ol><h2>Create table with Virtual Column</h2><p>For creating a virtual column, use the syntax mentioned above. Consider the following example:</p><pre class="brush: sql; title: ; notranslate">
CREATE TABLE EMPLOYEE
(
	empl_id        NUMBER,
	empl_nm        VARCHAR2(50),
	monthly_sal    NUMBER(10,2),
	bonus          NUMBER(10,2),
	total_sal      NUMBER(10,2) GENERATED ALWAYS AS (monthly_sal*12 + bonus)
);
</pre><p>Here we have defined a virtual column &#8220;total_sal&#8221; whose value would be dynamically calculated using the expression provided after the &#8220;generated always as&#8221; clause. Please note that this declaration is different than using &#8220;default&#8221; clause for a normal column as you can&#8217;t refer column names with &#8220;default&#8221; clause.</p><p>Lets check the data dictionary view:</p><pre class="brush: sql; title: ; notranslate">
SELECT column_name, data_type, data_length, data_default, virtual_column
  FROM user_tab_cols
 WHERE table_name = 'EMPLOYEE';

COLUMN_NAME | DATA_TYPE | DATA_LENGTH | DATA_DEFAULT             | VIRTUAL_COLUMN
EMPL_ID     | NUMBER    | 22          | null                     | NO
EMPL_NM     | VARCHAR2  | 50          | null                     | NO
MONTHLY_SAL | NUMBER    | 22          | null                     | NO
BONUS       | NUMBER    | 22          | null                     | NO
TOTAL_SAL   | NUMBER    | 22          | &quot;MONTHLY_SAL&quot;*12+&quot;BONUS&quot; | YES
</pre><p>The value &#8220;YES&#8221; for the column &#8220;virtual_column&#8221; tells us that this is a virtual column. Another optional keyword &#8220;VIRTUAL&#8221; can also be added to make it syntactically complete.</p><pre class="brush: sql; title: ; notranslate">
DROP TABLE EMPLOYEE PURGE;

CREATE OR REPLACE FUNCTION get_empl_total_sal ( p_monthly_sal   NUMBER,
                                                p_bonus         NUMBER)
   RETURN NUMBER
DETERMINISTIC
IS
BEGIN
   RETURN p_monthly_sal * 12 + p_bonus;
END;

CREATE TABLE EMPLOYEE
(empl_id     NUMBER,
 empl_nm     VARCHAR2(50),
 monthly_sal NUMBER(10,2),
 bonus       NUMBER(10,2),
 total_sal   NUMBER(10,2) AS (get_empl_total_sal(monthly_sal, bonus)) VIRTUAL
);
</pre><p>We have included the &#8220;VIRTUAL&#8221; clause in the table definition. Please note that instead of using an expression, I have used a deterministic function. A deterministic function, when passed certain inputs, will always return the exact same output. &#8220;DETERMINISTIC&#8221; keyword is needed in order to mark a function as a candidate to be used in a function based index.</p><p>You can also create indexes on the virtual columns. Here is an example:</p><pre class="brush: sql; title: ; notranslate">
CREATE INDEX idx_total_sal ON employee(total_sal);

SELECT index_name, index_type
  FROM user_indexes
 WHERE table_name = 'EMPLOYEE';

INDEX_NAME     INDEX_TYPE
IDX_TOTAL_SAL  FUNCTION-BASED NORMAL
</pre><p>Note that even this function is used as part of table definition, you can still drop it. But this in turn will make the table inaccessible.</p><pre class="brush: sql; title: ; notranslate">
DROP FUNCTION get_empl_total_sal;

SELECT * FROM employee;
*
Error at line 0
ORA-00904: &quot;schema&quot;.&quot;GET_EMPL_TOTAL_SAL&quot;: invalid identifier
</pre><p>You can alter the table with virtual column as you would modify a table with normal columns. Lets add the same column using the ALTER command:</p><pre class="brush: sql; title: ; notranslate">
DROP TABLE EMPLOYEE PURGE;

CREATE TABLE EMPLOYEE
(empl_id     NUMBER,
 empl_nm     VARCHAR2(50),
 monthly_sal NUMBER(10,2),
 bonus       NUMBER(10,2)
);

ALTER TABLE EMPLOYEE ADD (total_sal AS (monthly_sal * 12 + bonus));
</pre><p>Note that the datatype of the new column is not declared. It will be assigned a datatype based on the result of the expression (in this case, it would be NUMBER). Now let&#8217;s insert some data in the table:</p><pre class="brush: sql; title: ; notranslate">
INSERT INTO employee (empl_id, empl_nm, monthly_sal, bonus)
   WITH DATA AS
        (SELECT 100 empl_id, 'AAA' empl_nm, 20000 monthly_sal, 3000 bonus
           FROM DUAL
         UNION
         SELECT 200, 'BBB', 12000, 2000
           FROM DUAL
         UNION
         SELECT 300, 'CCC', 32100, 1000
           FROM DUAL
         UNION
         SELECT 400, 'DDD', 24300, 5000
           FROM DUAL
         UNION
         SELECT 500, 'EEE', 12300, 8000
           FROM DUAL)
   SELECT *
     FROM DATA;

SELECT * FROM employee;

EMPL_ID | EMPL_NM | MONTHLY_SAL | BONUS | TOTAL_SAL
100     | AAA     | 20000       | 3000  | 243000
200     | BBB     | 12000       | 2000  | 146000
300     | CCC     | 32100       | 1000  | 386200
400     | DDD     | 24300       | 5000  | 296600
500     | EEE     | 12300       | 8000  | 155600
</pre><p>Here we have populated the table columns except the virtual column with some values. Upon selecting the data, we get the value for &#8220;total_sal&#8221;. Remember that this data is not actually stored in the database but evaluated dynamically. Lets try updating this value of this virtual column:</p><pre class="brush: sql; title: ; notranslate">
UPDATE employee
   SET total_sal = 2000;

ORA-54017: UPDATE operation disallowed on virtual columns
</pre><p>As mentioned before, the statistics can also be gathered for the virtual columns.</p><pre class="brush: sql; title: ; notranslate">
EXEC DBMS_STATS.GATHER_TABLE_STATS(user, 'EMPLOYEE');

SELECT column_name, num_distinct,
       display_raw (low_value, data_type)  low_value,
       display_raw (high_value, data_type) high_value
  FROM dba_tab_cols
 WHERE table_name = 'EMPLOYEE';

COLUMN_NAME | NUM_DISTINCT | LOW_VALUE | HIGH_VALUE
TOTAL_SAL   | 5            | 146000    | 386200
BONUS       | 5            | 1000      | 8000
MONTHLY_SAL | 5            | 12000     | 32100
EMPL_NM     | 5            | AAA       | EEE
EMPL_ID     | 5            | 100       | 500
</pre><h2>Limitations on Virtual Columns</h2><p><em>**The query above uses a wonderful function &#8220;display_raw&#8221; by &#8220;Greg Rahn&#8221; to display the high/low values. Please check the references at the last to see it&#8217;s definition.</em></p><ol><li>A virtual column can only be of scalar datatype or XMLDATATYE. It can&#8217;t be a user defined type, LOB or RAW.</li><li>All columns mentioned as part of the virtual column expression should belong to the same table.</li><li>No DMLs are allowed on the virtual columns.</li><li>The virtual column expression can&#8217;t reference any other virtual column.</li><li>Virtual columns can only be created on ordinary tables. They can&#8217;t be created on index-organized, external, object, cluster or temporary tables.</li><li>If a deterministic function is used as virtual column expression, that virtual column can&#8217;t be used as a partitioning key for virtual column-based partitioning.</li></ol><h2>Virtual Column-Based Partitioning</h2><p>Prior releases of Oracle only allowed a table to be partitioned based on a physical column. Oracle 11g, with the addition of virtual columns, now allows a partition key based on an expression, using one or more existing columns of the table. A virtual column can now be used as a partitioning key. Lets partition our table based on the virtual column &#8220;total_sal&#8221;:</p><pre class="brush: sql; title: ; notranslate">
DROP TABLE EMPLOYEE PURGE;

CREATE TABLE employee
(empl_id     NUMBER,
 empl_nm     VARCHAR2(50),
 monthly_sal NUMBER(10,2),
 bonus       NUMBER(10,2),
 total_sal   NUMBER(10,2) AS (monthly_sal*12 + bonus)
)
PARTITION BY RANGE (total_sal)
    (PARTITION sal_200000 VALUES LESS THAN (200000),
     PARTITION sal_400000 VALUES LESS THAN (400000),
     PARTITION sal_600000 VALUES LESS THAN (600000),
     PARTITION sal_800000 VALUES LESS THAN (800000),
     PARTITION sal_default VALUES LESS THAN (MAXVALUE));

INSERT INTO employee (empl_id, empl_nm, monthly_sal, bonus)
   WITH DATA AS
        (SELECT 100 empl_id, 'AAA' empl_nm, 20000 monthly_sal, 3000 bonus
           FROM DUAL
         UNION
         SELECT 200, 'BBB', 12000, 2000
           FROM DUAL
         UNION
         SELECT 300, 'CCC', 32100, 1000
           FROM DUAL
         UNION
         SELECT 400, 'DDD', 24300, 5000
           FROM DUAL
         UNION
         SELECT 500, 'EEE', 12300, 8000
           FROM DUAL)
   SELECT *
     FROM DATA;

EXEC DBMS_STATS.GATHER_TABLE_STATS(user,'EMPLOYEE',granularity =&amp;gt; 'PARTITION');

SELECT   table_name, partition_name, num_rows
    FROM user_tab_partitions
   WHERE table_name = 'EMPLOYEE'
ORDER BY partition_name;

TABLE_NAME | PARTITION_NAME | NUM_ROWS
EMPLOYEE   | SAL_200000     | 2
EMPLOYEE   | SAL_400000     | 3
EMPLOYEE   | SAL_600000     | 0
EMPLOYEE   | SAL_800000     | 0
EMPLOYEE   | SAL_DEFAULT    | 0
</pre><p>So far, everything looks fine, lets now try to update monthly salary of one employee and in turn the value of total_sal.</p><pre class="brush: sql; title: ; notranslate">
UPDATE employee
   SET monthly_sal = 30000
 WHERE empl_id = 500;

ORA-14402: updating partition key column would cause a partition change
</pre><p>What happened? The reason is simple, updating the &#8220;monthly_sal&#8221; would result into change in &#8220;total_sal&#8221; of the employee and thus a partition change is required. This can be handled by enabling the row movement in the current definition of the table.</p><pre class="brush: sql; title: ; notranslate">
ALTER TABLE employee ENABLE ROW MOVEMENT;

UPDATE employee
   SET monthly_sal = 80000
 WHERE empl_id = 500;

1 row updated.
</pre><p>The update works fine. As mentioned before, a deterministic function can&#8217;t be used as virtual column expression which is to be used as a partitioning key. It has to be an expression defined on the columns of the table as done in the previous example. The following syntax will result in oracle error:</p><pre class="brush: sql; title: ; notranslate">
CREATE TABLE employee_new
(empl_id     NUMBER,
 empl_nm     VARCHAR2(50),
 monthly_sal NUMBER(10,2),
 bonus       NUMBER(10,2),
 total_sal   NUMBER(10,2) AS (get_empl_total_sal(monthly_sal, bonus))
)
PARTITION BY RANGE (total_sal)
    (PARTITION sal_200000 VALUES LESS THAN (200000),
     PARTITION sal_400000 VALUES LESS THAN (400000),
     PARTITION sal_600000 VALUES LESS THAN (600000),
     PARTITION sal_800000 VALUES LESS THAN (800000),
     PARTITION sal_default VALUES LESS THAN (MAXVALUE));

ORA-54021: Cannot use PL/SQL expressions in partitioning or subpartitioning columns
</pre><h3>References:</h3><p><a rel="nofollow" target="_new" href="http://structureddata.org/2007/10/16/how-to-display-high_valuelow_value-columns-from-user_tab_col_statistics/">Greg Rahn&#8217;s display_raw function</a><br /> <a rel="nofollow" target="_new" href="http://download.oracle.com/docs/cd/B28359_01/server.111/b32024/part_avail.htm#BJEFFAGH">Oracle Documentation</a></p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2010/11/row-data-multiplication-in-oracle.html" title="Row Data Multiplication in Oracle">Row Data Multiplication in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/07/generating-random-data-in-oracle.html" title="Generating Random Data in Oracle">Generating Random Data in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/06/deleting-duplicate-rows-in-oracle.html" title="Deleting Duplicate Rows in Oracle">Deleting Duplicate Rows in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/06/invisible-indexes-in-oracle-11g.html" title="Invisible Indexes in Oracle 11g">Invisible Indexes in Oracle 11g</a></li><li><a href="http://viralpatel.net/blogs/2010/06/oracle-data-compression.html" title="Oracle Data Compression">Oracle Data Compression</a></li><li><a href="http://viralpatel.net/blogs/2010/02/understanding-primary-keypk-constraint-in-oracle.html" title="Understanding Primary Key(PK) Constraint in Oracle">Understanding Primary Key(PK) Constraint in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2009/05/fetch-random-rows-from-database-mysql-oracle-ms-sql-postgresql-example.html" title="Fetch Random rows from Database (MySQL, Oracle, MS SQL, PostgreSQL)">Fetch Random rows from Database (MySQL, Oracle, MS SQL, PostgreSQL)</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2011/02/oracle-11g-new-feature-virtual-column.html/feed</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Row Data Multiplication in Oracle</title><link>http://viralpatel.net/blogs/2010/11/row-data-multiplication-in-oracle.html</link> <comments>http://viralpatel.net/blogs/2010/11/row-data-multiplication-in-oracle.html#comments</comments> <pubDate>Thu, 18 Nov 2010 16:48:40 +0000</pubDate> <dc:creator>Anuj Parashar</dc:creator> <category><![CDATA[Database]]></category> <category><![CDATA[Oracle]]></category> <category><![CDATA[SQL]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2116</guid> <description><![CDATA[Aggregate functions return a single result row based on a group of rows. This differentiates them from Single-Row functions which act on each row. These functions are extensively used with the GROUP BY clause in SQL statements. AVG (), COUNT (), SUM () &#8230; are few aggregate functions which are quite commonly used. Today, one [...]]]></description> <content:encoded><![CDATA[<p><img src="http://img.viralpatel.net/2010/11/aggregate.jpg" alt="aggregate function multiply" width="250" height="167" class="alignright size-full wp-image-2117" /><strong>Aggregate functions</strong> return a single result row based on a group of rows. This differentiates them from Single-Row functions which act on each row. These functions are extensively used with the GROUP BY clause in SQL statements. AVG (), COUNT (), SUM () &#8230; are few aggregate functions which are quite commonly used. Today, one of my colleague asked me if there is some aggregation function for <strong>Multiplication</strong>. I thought about it for a while and found myself surprised that I have never thought about doing such a thing <img src='http://viralpatel.net/blogs/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>So, How do we do the multiplication then? I tried it but just couldn&#8217;t do it in SQL. So, I asked this question on our internal self help channel and I got a pretty impressive reply:</p><p><strong>&#8220;Using a mathematical approach&#8230;&#8221;</strong></p><p>After understanding the solution, I was surprisingly happy with the simplicity of the approach and found it worth sharing. Let&#8217;s assume that we have a table &#8220;tbl&#8221; with one column &#8220;num&#8221;. This table has three rows having values 2, 3 &amp; 4 for column &#8220;num&#8221;.</p><pre class="brush: sql; title: ; notranslate">
WITH tbl AS
     (SELECT 2 num
        FROM DUAL
      UNION
      SELECT 3 num
        FROM DUAL
      UNION
      SELECT 4 num
        FROM DUAL)
SELECT num
  FROM tbl;
</pre><p>We need the multiplication of row&#8217;s data for this column. So essentially, we are looking for an aggregate function MUL (num).</p><p>There is no such function as MUL () in Oracle (I actually tried using it). Here comes the computational part of the puzzle. A multiplication operation can be mathematically expressed as:</p><p><b>MUL (num) = EXP (SUM (LN (num)))</b></p><p>Not very clear at first, I agree. Lets review the maths behind it:<br /> <b><br /> x     =   (2 * 3 * 4)<br /> ln(x) = ln(2 * 3 * 4)<br /> ln(x) = ln(2) + ln(3) + ln(4) =&gt; SUM(LN(num))<br /> ln(x) = .693 + 1.098 + 1.386<br /> ln(x) = 3.178<br /> x     = e (3.178)             =&gt; EXP(SUM(LN(num)))<br /> x     = 24<br /> </b></p><p>And that&#8217;s it. We just created our own multiplication function and now the result can be calculated as:</p><pre class="brush: sql; title: ; notranslate">
  WITH tbl AS
     (SELECT 2 num
        FROM DUAL
      UNION
      SELECT 3 num
        FROM DUAL
      UNION
      SELECT 4 num
        FROM DUAL)
SELECT EXP (SUM (LN (num))) MUL
  FROM tbl;
</pre><p><strong>Result: 24</strong></p><p>Everything looks perfect. But hey, I have got negative values. The moment you put a negative value in the dataset, you are bound to get the following Oracle error:</p><p><strong>&#8220;ORA-01428: argument &#8216;x&#8217; is out of range&#8221;</strong></p><p>This is because the range for LN () argument is &gt; 0. But this is now easy to handle, here is how:</p><pre class="brush: sql; title: ; notranslate">
WITH tbl AS
     (SELECT -2 num
        FROM DUAL
      UNION
      SELECT -3 num
        FROM DUAL
      UNION
      SELECT -4 num
        FROM DUAL),
     sign_val AS
     (SELECT CASE MOD (COUNT (*), 2)
                WHEN 0 THEN 1
                ELSE -1
             END val
        FROM tbl
       WHERE num &lt; 0)
SELECT   EXP (SUM (LN (ABS (num)))) * val
    FROM tbl, sign_val
GROUP BY val
</pre><p><strong>Result: -24</strong></p><p>So, we first counted the negative records in the table. If the count is odd, the final result should be negative and vice versa. We then multiplied this signed value with the multiplication of the absolute values. A subquery can also be used instead of GROUP BY but that&#8217;s trivial. Now the solution is complete and we are able to handle the negative values too.</p><p>I was so impressed by this approach that I haven&#8217;t given a thought about any other solution. But I am sure there would be. If you find a different approach, please share.</p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2009/05/fetch-random-rows-from-database-mysql-oracle-ms-sql-postgresql-example.html" title="Fetch Random rows from Database (MySQL, Oracle, MS SQL, PostgreSQL)">Fetch Random rows from Database (MySQL, Oracle, MS SQL, PostgreSQL)</a></li><li><a href="http://viralpatel.net/blogs/2010/07/generating-random-data-in-oracle.html" title="Generating Random Data in Oracle">Generating Random Data in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/06/deleting-duplicate-rows-in-oracle.html" title="Deleting Duplicate Rows in Oracle">Deleting Duplicate Rows in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/06/invisible-indexes-in-oracle-11g.html" title="Invisible Indexes in Oracle 11g">Invisible Indexes in Oracle 11g</a></li><li><a href="http://viralpatel.net/blogs/2010/06/oracle-data-compression.html" title="Oracle Data Compression">Oracle Data Compression</a></li><li><a href="http://viralpatel.net/blogs/2010/02/understanding-primary-keypk-constraint-in-oracle.html" title="Understanding Primary Key(PK) Constraint in Oracle">Understanding Primary Key(PK) Constraint in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2009/08/fast-data-copy-with-create-table-select-from-in-plsql.html" title="Fast data copy with &#8220;Create Table Select From&#8221; in PL/SQL">Fast data copy with &#8220;Create Table Select From&#8221; in PL/SQL</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2010/11/row-data-multiplication-in-oracle.html/feed</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Generating Random Data in Oracle</title><link>http://viralpatel.net/blogs/2010/07/generating-random-data-in-oracle.html</link> <comments>http://viralpatel.net/blogs/2010/07/generating-random-data-in-oracle.html#comments</comments> <pubDate>Thu, 01 Jul 2010 16:36:06 +0000</pubDate> <dc:creator>Anuj Parashar</dc:creator> <category><![CDATA[Database]]></category> <category><![CDATA[Oracle]]></category> <category><![CDATA[database queries]]></category> <category><![CDATA[How-To]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2076</guid> <description><![CDATA[Most of the times, production data is not available in development environments. Here, I would like to share a single sql command which can generate random data. But before that, let&#8217;s address another issue faced by a lot of new oracle users. We need to generate a sequence of numbers using a sql statement. This will [...]]]></description> <content:encoded><![CDATA[<p><img class="alignright" src="http://img.viralpatel.net/2009/08/random-number.jpg" alt="random-numbers-oracle" width="225" height="150" />Most of the times, production data is not available in development environments. Here, I would like to share a single sql command which can generate random data. But before that, let&#8217;s address another issue faced by a lot of new oracle users. We need to generate a sequence of numbers using a sql statement. This will generate a number sequence. Nothing fancy, simplest of sql known <img src='http://viralpatel.net/blogs/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> Here it is:</p><pre class="brush: sql; title: ; notranslate">
SELECT ROWNUM
FROM DUAL
CONNECT BY LEVEL &lt; 10000;
</pre><p>Now, to generate the random data, the oracle build in package &#8220;dbms_random&#8221; comes handy. I am referring to the version 10GR2, there might be additional features available on 11G . Other build in functions can also be used. Here is a sample sql:</p><pre class="brush: sql; title: ; notranslate">
SELECT     LEVEL                                                       empl_id,
           MOD (ROWNUM, 50000)                                         dept_id,
           TRUNC (DBMS_RANDOM.VALUE (1000, 500000), 2)                 salary,
           DECODE (ROUND (DBMS_RANDOM.VALUE (1, 2)), 1, 'M', 2, 'F')   gender,
           TO_DATE (   ROUND (DBMS_RANDOM.VALUE (1, 28))
                    || '-'
                    || ROUND (DBMS_RANDOM.VALUE (1, 12))
                    || '-'
                    || ROUND (DBMS_RANDOM.VALUE (1900, 2010)),
                    'DD-MM-YYYY'
                   )                                                   dob,
           DBMS_RANDOM.STRING ('x', DBMS_RANDOM.VALUE (20, 50))        address
      FROM DUAL
CONNECT BY LEVEL &lt; 10000;
</pre><p>You can create a table using this sql and that will give you some random test data to work on. The output looks something like:</p><pre style="width:100%;overflow:auto;padding:3px;">EMPL_ID | DEPT_ID | SALARY    | GENDER | DOB       | ADDRESS
1       | 1       | 385433.6  | M      | 2/25/1903 | VVGJOPVIHD8HZELHK1SXWQ1RTNK84NT6
2       | 2       | 363024.64 | F      | 5/24/2010 | E4IOCU42LM7K2SS36OI0STDOO7A2UZ50L2Q5R1SME07
3       | 3       | 320010.48 | M      | 9/26/2009 | 8XM6CG3CSR6UA26PXPUTLPLPQNSQ3OJG7P0CL4XVHBMCVT
4       | 4       | 64230.96  | F      | 6/26/1991 | GLKYLEWG4NS0G67W64LF1G5GJPON5L8K93F
5       | 5       | 414134.44 | M      | 10/26/1981| QWXIT92XPEYYZZ0A8MR050ER8UJ30NYUHDJAEJHF2M3
...
...</pre><p>There are numerous functions which can be used to generate randomized data in different ways. Best is to create a wrapper package which can generate number, string, date etc based on the parameter passed and then call that package. I will share it as soon as I am done writing it.</p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2010/06/deleting-duplicate-rows-in-oracle.html" title="Deleting Duplicate Rows in Oracle">Deleting Duplicate Rows in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2009/05/fetch-random-rows-from-database-mysql-oracle-ms-sql-postgresql-example.html" title="Fetch Random rows from Database (MySQL, Oracle, MS SQL, PostgreSQL)">Fetch Random rows from Database (MySQL, Oracle, MS SQL, PostgreSQL)</a></li><li><a href="http://viralpatel.net/blogs/2010/11/row-data-multiplication-in-oracle.html" title="Row Data Multiplication in Oracle">Row Data Multiplication in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/06/invisible-indexes-in-oracle-11g.html" title="Invisible Indexes in Oracle 11g">Invisible Indexes in Oracle 11g</a></li><li><a href="http://viralpatel.net/blogs/2010/06/oracle-data-compression.html" title="Oracle Data Compression">Oracle Data Compression</a></li><li><a href="http://viralpatel.net/blogs/2010/02/understanding-primary-keypk-constraint-in-oracle.html" title="Understanding Primary Key(PK) Constraint in Oracle">Understanding Primary Key(PK) Constraint in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2011/12/reseting-mysql-autoincrement-column.html" title="How To Reset MySQL Autoincrement Column">How To Reset MySQL Autoincrement Column</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2010/07/generating-random-data-in-oracle.html/feed</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Deleting Duplicate Rows in Oracle</title><link>http://viralpatel.net/blogs/2010/06/deleting-duplicate-rows-in-oracle.html</link> <comments>http://viralpatel.net/blogs/2010/06/deleting-duplicate-rows-in-oracle.html#comments</comments> <pubDate>Thu, 24 Jun 2010 08:51:46 +0000</pubDate> <dc:creator>Anuj Parashar</dc:creator> <category><![CDATA[Database]]></category> <category><![CDATA[Oracle]]></category> <category><![CDATA[database queries]]></category> <category><![CDATA[How-To]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2069</guid> <description><![CDATA[Deleting duplicate rows from tables is one of the common task oracle developers come across. The data might get duplicated because of missing primary/unique key on the table or batch file getting loaded multiple times. Here I have tried to summarize different ways of deleting this duplicated data. Please note that this is not an [...]]]></description> <content:encoded><![CDATA[<p><img class="alignright size-full wp-image-2070" src="http://img.viralpatel.net/2010/06/oracle-logo.jpg" alt="" width="268" height="41" />Deleting duplicate rows from tables is one of the common task oracle developers come across. The data might get duplicated because of missing primary/unique key on the table or batch file getting loaded multiple times. Here I have tried to summarize different ways of deleting this duplicated data. Please note that this is not an extensive list of all available methods but the ones I was able to figure out. This should serve as a handy reference while at work.</p><pre class="brush: sql; title: ; notranslate">
CREATE TABLE tbl_test(
	 SER_NO NUMBER,
 	 FST_NM VARCHAR2(30),
 	 DEPTID	NUMBER,
 	 CMNT   VARCHAR2(30));

INSERT INTO tbl_test VALUES(1, 'aaaaa', 2004, 'xxx');
INSERT INTO tbl_test VALUES(2, 'bbbbb', 2005, 'yyy');
INSERT INTO tbl_test VALUES(1, 'aaaaa', 2004, 'xxx');
INSERT INTO tbl_test VALUES(1, 'aaaaa', 2004, 'xxx');
INSERT INTO tbl_test VALUES(3, 'ccccc', 2005, 'zzz');
INSERT INTO tbl_test VALUES(2, 'bbbbb', 2005, 'yyy');
</pre><p><strong>1.</strong> <strong>Using MIN(rowid) :</strong> The most common method of removing duplicate rows.</p><pre class="brush: sql; title: ; notranslate">
DELETE FROM tbl_test
      WHERE ROWID NOT IN (SELECT   MIN (ROWID)
                              FROM tbl_test
                          GROUP BY ser_no, fst_nm, deptid, cmnt);
</pre><p><strong>Comment:</strong> This will take hours &amp; hours if the table is large (records in million).</p><p><strong>2.</strong> <strong>Using MIN(rowid) &amp; Join:</strong> More or less the same as first one</p><pre class="brush: sql; title: ; notranslate">
DELETE FROM tbl_test t
      WHERE t.ROWID NOT IN (SELECT MIN (b.ROWID)
                              FROM tbl_test b
                             WHERE b.ser_no = t.ser_no
                               AND b.fst_nm = t.fst_nm
                               AND b.deptid = t.deptid
                               AND b.cmnt   = t.cmnt);
</pre><p><strong>3. Using Subquery: </strong>This is an interesting one</p><pre class="brush: sql; title: ; notranslate">
DELETE FROM tbl_test
      WHERE ser_no IN (SELECT ser_no FROM tbl_test GROUP BY ser_no, fst_nm, deptid, cmnt HAVING COUNT (*) &gt; 1)
        AND fst_nm IN (SELECT fst_nm FROM tbl_test GROUP BY ser_no, fst_nm, deptid, cmnt HAVING COUNT (*) &gt; 1)
        AND deptid IN (SELECT deptid FROM tbl_test GROUP BY ser_no, fst_nm, deptid, cmnt HAVING COUNT (*) &gt; 1)
        AND cmnt   IN (SELECT cmnt   FROM tbl_test GROUP BY ser_no, fst_nm, deptid, cmnt HAVING COUNT (*) &gt; 1)
        AND ROWID NOT IN (SELECT   MIN (ROWID)
                              FROM tbl_test
                          GROUP BY ser_no, fst_nm, deptid, cmnt
                            HAVING COUNT (*) &gt; 1)
</pre><p><strong>Comment:</strong> A complicated way of performing the same task. Not efficient.</p><p><strong>4. Using Nested Subqueries:<br /> </strong></p><pre class="brush: sql; title: ; notranslate">
DELETE FROM tbl_test a
      WHERE (a.ser_no, a.fst_nm, a.deptid, a.cmnt) IN (SELECT b.ser_no, b.fst_nm, b.deptid, b.cmnt
                                                     FROM tbl_test b
                                                    WHERE a.ser_no = b.ser_no
                                                      AND a.fst_nm = b.fst_nm
                                                      AND a.deptid = b.deptid
                                                      AND a.cmnt   = b.cmnt
                                                      AND a.ROWID  &gt; b.ROWID);
</pre><p><strong>Comment:</strong> Will work but for large tables, this is not efficient.</p><p><strong>5. Using Analytic Fucntions:</strong></p><pre class="brush: sql; title: ; notranslate">
DELETE FROM tbl_test
      WHERE ROWID IN (
               SELECT rid
                 FROM (SELECT ROWID rid,
                              ROW_NUMBER () OVER (PARTITION BY ser_no, fst_nm, deptid, cmnt ORDER BY ROWID) rn
                         FROM tbl_test)
                WHERE rn &lt;&gt; 1);
</pre><p><strong>Comments:</strong> This is by far one of the best solutions if the table is really really large. Using the invaluable power of Analytics.</p><p><strong>6. CREATE-DROP-RENAME:</strong>  This one is a more appropriate solution in terms of resource usage in the sense that if we have a really large table, then with delete option we are generating a huge amount of UNDO information.(if we want to rollback for any reason). Even worst, the rollback segment may not be large enough to hold your UNDO information and give error. CTAS comes handy in this case.<br /> Step 1.</p><pre class="brush: sql; title: ; notranslate">
CREATE  TABLE tbl_test1 NOLOGGING
   AS
   SELECT tbl_test .*
     FROM tbl_test tbl_test
    WHERE ROWID IN (SELECT rid
                      FROM (SELECT ROWID rid, ROW_NUMBER() OVER (PARTITION BY ser_no, fst_nm, deptid, cmnt ORDER BY ROWID) rn
                              FROM tbl_test)
                     WHERE rn=1);
</pre><p>Step 2.</p><pre class="brush: sql; title: ; notranslate">
DROP TABLE tbl_test; --drop the original table with lots of duplicate
</pre><p>Step 3.</p><pre class="brush: sql; title: ; notranslate">
RENAME tbl_test1 TO tbl_test; -- your original table without duplicates.
</pre><p>In case you have some other method of deleting duplicate data, please share it.</p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2010/07/generating-random-data-in-oracle.html" title="Generating Random Data in Oracle">Generating Random Data in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2009/05/fetch-random-rows-from-database-mysql-oracle-ms-sql-postgresql-example.html" title="Fetch Random rows from Database (MySQL, Oracle, MS SQL, PostgreSQL)">Fetch Random rows from Database (MySQL, Oracle, MS SQL, PostgreSQL)</a></li><li><a href="http://viralpatel.net/blogs/2010/11/row-data-multiplication-in-oracle.html" title="Row Data Multiplication in Oracle">Row Data Multiplication in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/06/invisible-indexes-in-oracle-11g.html" title="Invisible Indexes in Oracle 11g">Invisible Indexes in Oracle 11g</a></li><li><a href="http://viralpatel.net/blogs/2010/06/oracle-data-compression.html" title="Oracle Data Compression">Oracle Data Compression</a></li><li><a href="http://viralpatel.net/blogs/2010/02/understanding-primary-keypk-constraint-in-oracle.html" title="Understanding Primary Key(PK) Constraint in Oracle">Understanding Primary Key(PK) Constraint in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2011/12/reseting-mysql-autoincrement-column.html" title="How To Reset MySQL Autoincrement Column">How To Reset MySQL Autoincrement Column</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2010/06/deleting-duplicate-rows-in-oracle.html/feed</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Invisible Indexes in Oracle 11g</title><link>http://viralpatel.net/blogs/2010/06/invisible-indexes-in-oracle-11g.html</link> <comments>http://viralpatel.net/blogs/2010/06/invisible-indexes-in-oracle-11g.html#comments</comments> <pubDate>Mon, 21 Jun 2010 12:59:02 +0000</pubDate> <dc:creator>Keshaba Kuntulu</dc:creator> <category><![CDATA[Database]]></category> <category><![CDATA[Featured]]></category> <category><![CDATA[Oracle]]></category> <category><![CDATA[database indexes]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2061</guid> <description><![CDATA[The effective usage of an index is always a big question. There are instances in production environments, where an index may help the performance of just a single query, while it can degrade the performance of a number of queries. Always the Optimizer can’t guarantee the best suitable index required for the query in an [...]]]></description> <content:encoded><![CDATA[<p><img src="http://img.viralpatel.net/2010/06/oracle-invisible-index-11g.jpg" alt="oracle-invisible-index-11g" title="oracle-invisible-index-11g" width="210" height="196" class="alignright size-full wp-image-2062" />The effective usage of an index is always a big question. There are instances in production environments, where an index may help the performance of just a single query, while it can degrade the performance of a number of queries. Always the Optimizer can’t guarantee the best suitable index required for the query in an environment which is cluttered by too many indexes on a table.</p><p>One of the older solutions is to determine the effective usage of indexes in the database. Once the monitoring usage clause for the index is enabled, we can determine the usage of the index by querying <code>v$object_usage</code> data dictionary view. The index monitoring time again depends on the application, database usage and business hours. It varies from case to case. Some applications might require a few hours for monitoring the usage of indexes. Some might require even months to determine the perfect indexes that need to be retained and the ones that need to be detained.</p><p>If the usage of the index is at all, or it results a bad performance to other queries, one can easily drop the index. However in future, if some adhoc queries require the index badly (where the index dropped would have increased the performance dramatically), we need to think reinstating the index again. The recreation of an index is a very expensive one and requires a lot of database resources and consumes a lot of time as well.</p><p>One of the new features of oracle 11g, Invisible indexes is a perfect solution to the above problem. An index can be made invisible to the Optimizer, so that the optimizer can’t see it. If an adhoc query requires the usage of the index it can explicitly specify the index as a part of hint.</p><p>The following example demonstrates invisible index better.</p><pre class="brush: sql; title: ; notranslate">
SQL&gt; desc employee;
 Name                                      Null?    Type
 ----------------------------------------- -------- ---------

 EMPID                                              NUMBER
 DEPTNO                                             NUMBER
 EMPNAME                                            VARCHAR2(30)
 MGR_NAME                                           VARCHAR2(30)
 ADDRESS                                            VARCHAR2(100)
</pre><p>Let us create an index on EMPID column of the employee table.</p><pre class="brush: sql; title: ; notranslate">
SQL&gt; create index idx_empid on employee(empid);

Index created.
</pre><p>After creating the index let us fire this simple query:</p><pre class="brush: sql; title: ; notranslate">
SQL&gt; select * from employee where empid = 1001;

Execution Plan
-----------------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |           |     1 |   112 |     2   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| EMPLOYEE  |     1 |   112 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX_EMPID |     1 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
</pre><p>The above execution plan confirms the usage of the index which we created on the empid column. Now let us make this index invisible to the optimizer. An index can be made invisible using the simple ALTER statement.</p><pre class="brush: sql; title: ; notranslate">
SQL&gt; alter index idx_empid invisible;

Index altered.
</pre><p>The invisibility status of the index can be checked by using the following query:</p><pre class="brush: sql; title: ; notranslate">
SQL&gt; select visibility from user_indexes where index_name = 'IDX_EMPID';

VISIBILITY
---------
INVISIBLE
</pre><p>Now let us fire the same query on the employee table. The below explain plan shows the index became invisible to the optimizer and a full table scan is performed instead of index scan.</p><pre class="brush: sql; title: ; notranslate">
SQL&gt; select * from employee where empid = 1001;

Execution Plan

------------------------------------------------------------------------------
| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |          |     1 |   112 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| EMPLOYEE |     1 |   112 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------
</pre><p>Let us now try to give an index hint in our above query.</p><pre class="brush: sql; title: ; notranslate">
SQL&gt; select /*+ index(idx_empid) */ * from employee where empid = 1001;

Execution Plan

-----------------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |           |     1 |   112 |     2   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| EMPLOYEE  |     1 |   112 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX_EMPID |     1 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
</pre><p>After giving the hint, the optimizer used the index once again and performed an index scan. From the above example it is clear that, when an index can be made invisible only to the Optimizer and not to the user. User can still use it by giving a hint to the optimizer where ever it is required.<br /> Alternatively, there is a session level parameter, <strong>optimizer_use_invisible_indexes</strong>. This parameter can be set to <strong>TRUE</strong>, so that all the invisible indexes can be made visible to the optimizer.</p><pre class="brush: sql; title: ; notranslate">
SQL&gt; alter session set optimizer_use_invisible_indexes = true;
</pre><h2>Advantages of Invisble Indexes</h2><ol><li>Invisible indexes can help to a great extent, in testing scenarios where the optimizer behavior needs to be tested without the index. This does not need dropping and recreating the index.</li><li>Indexes can be created for certain adhoc queries (queries that are fired very infrequently) and can be made invisible after the usage.</li></ol><p>However, invisible indexes behave the same like a normal index towards the DML operations. They need to be updated with each DML operation.</p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2010/02/understanding-primary-keypk-constraint-in-oracle.html" title="Understanding Primary Key(PK) Constraint in Oracle">Understanding Primary Key(PK) Constraint in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/11/row-data-multiplication-in-oracle.html" title="Row Data Multiplication in Oracle">Row Data Multiplication in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/07/generating-random-data-in-oracle.html" title="Generating Random Data in Oracle">Generating Random Data in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/06/deleting-duplicate-rows-in-oracle.html" title="Deleting Duplicate Rows in Oracle">Deleting Duplicate Rows in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/06/oracle-data-compression.html" title="Oracle Data Compression">Oracle Data Compression</a></li><li><a href="http://viralpatel.net/blogs/2009/05/fetch-random-rows-from-database-mysql-oracle-ms-sql-postgresql-example.html" title="Fetch Random rows from Database (MySQL, Oracle, MS SQL, PostgreSQL)">Fetch Random rows from Database (MySQL, Oracle, MS SQL, PostgreSQL)</a></li><li><a href="http://viralpatel.net/blogs/2009/04/full-text-search-using-mysql-full-text-search-capabilities.html" title="Full-Text Search using MySQL: Full-Text Search Capabilities">Full-Text Search using MySQL: Full-Text Search Capabilities</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2010/06/invisible-indexes-in-oracle-11g.html/feed</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Oracle Data Compression</title><link>http://viralpatel.net/blogs/2010/06/oracle-data-compression.html</link> <comments>http://viralpatel.net/blogs/2010/06/oracle-data-compression.html#comments</comments> <pubDate>Wed, 16 Jun 2010 14:29:46 +0000</pubDate> <dc:creator>Anuj Parashar</dc:creator> <category><![CDATA[Database]]></category> <category><![CDATA[Oracle]]></category> <category><![CDATA[COMPRESS]]></category> <category><![CDATA[Data Compression]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2050</guid> <description><![CDATA[As the data grows in relational databases (new business requirements, managing audit data etc), the cost associated with the disk systems to store that data and the resources required to manage them becomes vital. Oracle understands this requirement and it is continuously implementing and improving on the compression techniques and algorithms while simultaneously meeting the [...]]]></description> <content:encoded><![CDATA[<p><img class="alignright size-full wp-image-2051" src="http://img.viralpatel.net/2010/06/oracle-data-compress.jpg" alt="oracle-data-compress" width="245" height="222" /><br /> As the data grows in relational databases (new business requirements, managing audit data etc), the cost associated with the disk systems to store that data and the resources required to manage them becomes vital. Oracle understands this requirement and it is continuously implementing and improving on the compression techniques and algorithms while simultaneously meeting the application scalability and performance requirements. In this article, I will be discussing the concept behind the Oracle Compression from database perspective and its advantages and disadvantages. The various compression features might differ with different releases but the underlying concept remains the same. I will also demonstrate the actual compression happening at the database level with suitable examples.</p><h2>Earlier Approach:</h2><p>Earlier RDBMS versions (6,7) were using a dictionary based approach based on static, table-wide dictionary. So, a table will have an associated look up global dictionary table which holds the lookup entries and the compressed data. The advantage of this approach was higher compression factor as compared to the latest block level compression. Also the global dictionary table will take less space as compared to the block level approach (explained next). But with the advent of new partition techniques and features, the block level approach holds greater merits.</p><h2>Latest Compressing Techniques (specifically in reference to Oracle 10GR2):</h2><p>The latest compression technique used by Oracle is a unique compression algorithm specially designed for RDMBS systems. The main features of this approach are:<br /> <b>Block Level compression:</b><br /> The compression window for data compression is a database block. This means the data is compressed block wide instead of table. Every compressed block is self contained and all the information needed to uncompress the data is available within the block.<br /> <b>Symbol table:</b><br /> The block contains a dictionary called as &#8220;symbol table&#8221; within each compressed block. This symbol table will have the common data and the links to associate this data with the actual rows.<br /> <b>Multi-Column Compression:</b><br /> If a sequence of columns are having common data, then instead of saving each individual column as separate entry, the combination of the columns will be saved in the symbol table as a whole. This approach is particularly useful in case of materialized views using grouping sets and cubes (where the data is ordered).<br /> <b>Cross Column Compression:</b><br /> As explain above, the symbol table holds the common data. This is true for the column values for different columns. So, if column values from the different columns are different, they all will share the same symbol table entry.</p><h2>Advantage of Block Level Compression:</h2><p><b>Disk Space saving:</b><br /> This is the obvious reason for implementing data compression. Although the space saving comes at a cost of decreased query performance (time required to decompress the data), when used along with other features, this can be minimized.<br /> <b>Coexisting compressed and non-compressed data:</b><br /> The same table can have both compressed and non-compressed data. This is possible because the compression is at block level, one block might hold compressed data and the other block might hold normal uncompressed data. This is particularly useful with partitioning where you can compress the old partitions while keep the current partition as non-compressed.<br /> <b>Less Buffer Size required:</b><br /> The data from a compressed block is read and cached in its compressed format and it is decompressed only at data access time. As the data is cached in compressed form, more data can be hold into the same<br /> amount of buffer cache.</p><h2>How to use compression:</h2><p>Compression can be used for tables, partitions and materialized view (Index compression is also possible, but that is out of scope of this article). The keyword &#8220;<strong>COMPRESS</strong>&#8221; is used with the table&#8217;s meta-data to compress the data. Please note that the compression works only in the following cases:</p><h4>CREATE TABLE AS SELECT</h4><p>Following example shows the compression using CTAS.</p><pre class="brush: sql; title: ; notranslate">
CREATE TABLE tbl_nocompress
AS
SELECT mod(rownum, 10) || 'ANY ADDITIONAL STRING TO MAKE THE COLUMN LENGTH LONGER, COMPRESSION WORKS BETTER' col1
  FROM all_objects;

CREATE TABLE tbl_compress
COMPRESS
AS
SELECT mod(rownum, 10) || 'ANY ADDITIONAL STRING TO MAKE THE COLUMN LENGTH LONGER, COMPRESSION WORKS BETTER' col1

SELECT segment_name, segment_type, blocks
  FROM dba_segments
 WHERE segment_name IN ('TBL_COMPRESS', 'TBL_NOCOMPRESS');

-- SEGMENT_NAME	  | SEGMENT_TYPE | BLOCKS
-- TBL_COMPRESS	  | TABLE        | 148
-- TBL_NOCOMPRESS | TABLE        | 1208
</pre><p>Two tables are created having 10 distinct values, one is compressed and other without compression. The blocks used for non-compressed table are almost 10 times that of compressed one. Please note that this is an indicative example and actual compression ratio will depend on database settings (for ex: db block size).</p><h4>INSERT /*+ APPEND */</h4><p>Now, lets insert the same data, with and without using &#8220;APPEND&#8221; hint:</p><pre class="brush: sql; title: ; notranslate">
INSERT INTO tbl_compress
SELECT mod(rownum, 10) || 'ANY ADDITIONAL STRING TO MAKE THE COLUMN LENGTH LONGER, COMPRESSION WORKS BETTER' col1
  FROM all_objects;

SELECT segment_name, segment_type, blocks
  FROM dba_segments
 WHERE segment_name IN ('TBL_COMPRESS', 'TBL_NOCOMPRESS');

-- SEGMENT_NAME   | SEGMENT_TYPE | BLOCKS
-- TBL_COMPRESS   | TABLE        | 1224
-- TBL_NOCOMPRESS | TABLE        | 1208
</pre><p>Although the tbl_compress is created with &#8220;<strong>COMPRESS</strong>&#8221; parameter (check the create script), normal DMLs are done without compression. If you use insert/update/delete, the modified data is <strong>NOT COMPRESSED</strong>. If you start with a large compressed table and update each row, each row will be decompressed and stored decompressed. This verifies that same table can hold both compressed and non-compressed data. Now, recreate the table and insert the entries in append mode:</p><pre class="brush: sql; title: ; notranslate">
DROP TABLE tbl_compress PURGE;

CREATE TABLE tbl_compress
COMPRESS
AS
SELECT mod(rownum, 10) || 'ANY ADDITIONAL STRING TO MAKE THE COLUMN LENGTH LONGER, COMPRESSION WORKS BETTER' col1
  FROM all_objects;

INSERT /*+ APPEND*/INTO tbl_compress
SELECT mod(rownum, 10) || 'ANY ADDITIONAL STRING TO MAKE THE COLUMN LENGTH LONGER, COMPRESSION WORKS BETTER' col1
  FROM all_objects;

-- SEGMENT_NAME   | SEGMENT_TYPE | BLOCKS
-- TBL_COMPRESS   | TABLE        |  292
-- TBL_NOCOMPRESS | TABLE        | 1208
</pre><p>This time we inserted the data in append mode, and the new data is compressed (block size approx. doubled instead of 10 times). Please note that although we are inserting the same data as it is already existing in the tables, new blocks are getting allocated to save it. The compression would have been much higher, if the table level compression were used instead of block level compression.</p><h4>DIRECT PATH LOADS (SQLLRD)</h4><p>while using DIRECT=TRUE with sqlldr</p><h4>ALTER TABLE &LT;TABLE_NAME&GT; MOVE</h4><p>Now lets try to compress the tbl_nocompress with ALTER command.</p><pre class="brush: sql; title: ; notranslate">
ALTER TABLE tbl_nocompress MOVE COMPRESS;

SELECT segment_name, segment_type, blocks
  FROM dba_segments
 WHERE segment_name IN ('TBL_COMPRESS', 'TBL_NOCOMPRESS');

-- SEGMENT_NAME   | SEGMENT_TYPE | BLOCKS
-- TBL_COMPRESS   | TABLE        | 292
-- TBL_NOCOMPRESS | TABLE        | 148
</pre><p>This is an easy way of compressing the table in case you were doing normal DMLs on a table with &#8220;compressed&#8221; attribute set (Remember that this will make the indexes on the table invalid because of rowid changes).</p><h2>Achieving higher Compression Ratio:</h2><p><strong>Read Only/mostly Data</strong> =&gt; Compression is generally used for &#8220;read only&#8221; or &#8220;read mostly&#8221; data like archived data or old partitioned data. The current running partition can be kept uncompressed while the old partitions can be compressed.</p><p><strong>Large DB Block Size</strong> =&gt; The larger the size of block size, the more rows it finds for compression in the same block and thus the chances of achieving higher compression are more.</p><p><strong>Ordered data</strong> =&gt; With the right sorting order, more rows can be find with common data and thus higher compression can be achieved. As mentioned before, this can be particularly useful with materialized views used for aggregating data.</p><p><strong>Long Fields with less Cardinality</strong> =&gt; Longer fields with less cardinality are ideal for compression as the space saving is larger.</p><h2>Adding / Removing Columns from compressed tables:</h2><p>Earlier it was not possible to add or remove columns from a compressed table. In Oracle 10G, you can add the column but can&#8217;t drop it (tested on 10.2.0.4). One way is to set the columns as unused:</p><pre class="brush: sql; title: ; notranslate">
ALTER TABLE tbl_compress ADD col2 NUMBER;

ALTER TABLE tbl_compress DROP COLUMN col2;
-- ORA-39726: unsupported add/drop column operation on compressed tables

ALTER TABLE tbl_compress SET UNUSED COLUMN col2;
</pre><p>Please note that once you set the column as unused, there is no easy way to get it back. There is no command like &#8220;ALTER TABLE  SET USED COLUMN<br /><col>&#8221; (at least in 10.2.0.4). In oracle 11G, you can drop the column from the compressed table after setting it unused. Here I would like to quote a statement from TOM&#8217;s blog:</p><blockquote><p>&#8220;It is sort of &#8220;not necessary&#8221; of course in this case &#8211; in fact, I&#8217;d say dropping a column from a compressed table probably should be done via &#8216;alter table t move&#8217; anyway (in order to, well, compress the data on the block again&#8230;)&#8221;</p></blockquote><p>This should have given a broad idea about the concept. In oracle 11G, oracle has added more sophisticated compression techniques like &#8220;OLTP Compression&#8221;, &#8220;RMAN Compression&#8221;, &#8220;Network Compression&#8221; but that is out of scope of this article. Also, we are not discussing the performance penalty we pay for compression and the trade-off between space/performance. There are in-depth white papers available on web for consultation.</p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2010/11/row-data-multiplication-in-oracle.html" title="Row Data Multiplication in Oracle">Row Data Multiplication in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/07/generating-random-data-in-oracle.html" title="Generating Random Data in Oracle">Generating Random Data in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/06/deleting-duplicate-rows-in-oracle.html" title="Deleting Duplicate Rows in Oracle">Deleting Duplicate Rows in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/06/invisible-indexes-in-oracle-11g.html" title="Invisible Indexes in Oracle 11g">Invisible Indexes in Oracle 11g</a></li><li><a href="http://viralpatel.net/blogs/2010/02/understanding-primary-keypk-constraint-in-oracle.html" title="Understanding Primary Key(PK) Constraint in Oracle">Understanding Primary Key(PK) Constraint in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2009/05/fetch-random-rows-from-database-mysql-oracle-ms-sql-postgresql-example.html" title="Fetch Random rows from Database (MySQL, Oracle, MS SQL, PostgreSQL)">Fetch Random rows from Database (MySQL, Oracle, MS SQL, PostgreSQL)</a></li><li><a href="http://viralpatel.net/blogs/2011/02/oracle-11g-new-feature-virtual-column.html" title="Oracle 11G new feature: Virtual Column">Oracle 11G new feature: Virtual Column</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2010/06/oracle-data-compression.html/feed</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Understanding Primary Key(PK) Constraint in Oracle</title><link>http://viralpatel.net/blogs/2010/02/understanding-primary-keypk-constraint-in-oracle.html</link> <comments>http://viralpatel.net/blogs/2010/02/understanding-primary-keypk-constraint-in-oracle.html#comments</comments> <pubDate>Tue, 16 Feb 2010 15:21:35 +0000</pubDate> <dc:creator>Anuj Parashar</dc:creator> <category><![CDATA[Database]]></category> <category><![CDATA[Oracle]]></category> <category><![CDATA[database indexes]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2032</guid> <description><![CDATA[The Primary Key(PK) constraint is the most basic concept of any RDBMS (I am particularly interested in Oracle). Yet, I have noticed people getting confused when it comes to the practical usage and asking questions like: - I have disabled PK and now oracle is doing full table scan. - How PK constraints and indexes [...]]]></description> <content:encoded><![CDATA[<p><img src="http://img.viralpatel.net/2010/02/primary-key.jpg" alt="primary-key" title="primary-key" width="343" height="183" class="aligncenter size-full wp-image-2034" /><br /> The Primary Key(PK) constraint is the most basic concept of any RDBMS (I am particularly interested in Oracle). Yet, I have noticed people getting confused when it comes to the practical usage and asking questions like:</p><p>- I have disabled PK and now oracle is doing full table scan.<br /> - How PK constraints and indexes are related/different?<br /> - How Oracle is using a non-unique index to enforce PK constraints?</p><p>Although these questions seem simple to the experienced users yet these can act as food for thought for the new developers. I have tried to consolidate few aspects about PK constraint which I found particularly confusing / worth knowing.</p><p><strong>1. Primary key(PK) constraint and unique index are different.</strong><br /> PK constraint is a rule that prohibits multiple rows from having the same value in the same column or combination of columns and prohibits values from being null.<br /> Index is a database object which is used for fast retrieval of data. It is created using DDL commands: &#8220;CREATE INDEX&#8221; or as part of a &#8220;CREATE TABLE&#8221; with PK/UK constraint or an &#8220;ALTER TABLE&#8221; command to add these constraints.</p><p><strong>2. An enabled PK constraint is always associated with an index.</strong><br /> The associated index can be unique or non-unique (discussed later). The corresponding index can be find by querying:</p><pre class="brush: sql; title: ; notranslate">
SELECT constraint_name, constraint_type, index_name
  FROM user_constraints
 WHERE table_name = '&lt;TABLE_NAME&gt;';
</pre><p>Also, if we have an enabled PK constraint, the corresponding column(s) will be &#8220;<strong>NOT NULL</strong>&#8220;. Now if you drop/disable the PK constriant, the column(s) will be changed to the state in which they were before adding the PK constraint.</p><pre class="brush: sql; title: ; notranslate">
-- Creating a table with two columns. One as NULL and other as NOT NULL
CREATE TABLE tbl_test ( col_1 NUMBER,
                                  col_2 NUMBER NOT NULL);

-- Querying to check the the column nullable status
SELECT table_name, column_name, nullable
  FROM user_tab_cols
 WHERE table_name = 'TBL_TEST';

-- TABLE_NAME | COLUMN_NAME | NULLABLE
-- TBL_TEST   | COL_1       | Y
-- TBL_TEST   | COL_2       | N

-- Adding the the PK constraint
ALTER TABLE tbl_test ADD CONSTRAINT tbl_test_pk PRIMARY KEY(col_1);

-- Querying to check the user constraints.
--Two entries, one for NOT NULL constraint and one for PK constraint
SELECT a.table_name, b.column_name, a.constraint_name,
           a.constraint_type, a.index_name
  FROM user_constraints a, user_cons_columns b
 WHERE a.table_name      = 'TBL_TEST'
   AND a.constraint_name = b.constraint_name;

-- TABLE_NAME | COLUMN_NAME | CONSTRAINT_NAME | CONSTRAINT_TYPE | INDEX_NAME
-- TBL_TEST   | COL_2       | SYS_C001231845  | C               |
-- TBL_TEST   | COL_1       | TBL_TEST_PK     | P               | TBL_TEST_PK

-- Rechecking the column nullable status. Both the columns are now NOT NULL
SELECT table_name, column_name, nullable
  FROM user_tab_cols
 WHERE table_name = 'TBL_TEST';

-- TABLE_NAME | COLUMN_NAME | NULLABLE
-- TBL_TEST   | COL_1       | N
-- TBL_TEST   | COL_2       | N

-- Disabling the PK constraint
ALTER TABLE tbl_test DISABLE PRIMARY KEY;
-- OR
-- ALTER TABLE tbl_test DISABLE CONSTRAINT tbl_test_pk;

-- The column status is changed back as it was before adding the PK.
SELECT table_name, column_name, nullable
  FROM user_tab_cols
 WHERE table_name = 'TBL_TEST';

-- TABLE_NAME | COLUMN_NAME | NULLABLE
-- TBL_TEST   | COL_1       | Y
-- TBL_TEST   | COL_2       | N</pre><p><strong>3. If the PK constraint is disabled, there will be no index associated with it.</strong><br /> The &#8220;index_name&#8221; in the above query would be blank. But the constraint name would still be there. So, PK constraint exists (with status as disabled) but there is no associated index.</p><pre class="brush: sql; title: ; notranslate">
DROP TABLE tbl_test;

CREATE TABLE tbl_test (col_1 NUMBER);

CREATE INDEX idx_col_1 ON tbl_test (col_1);

ALTER TABLE tbl_test ADD CONSTRAINT tbl_test_pk PRIMARY KEY(col_1);

SELECT constraint_name, constraint_type, index_name
  FROM user_constraints
 WHERE table_name = 'TBL_TEST';

-- CONSTRAINT_NAME | CONSTRAINT_TYPE | INDEX_NAME
-- TBL_TEST_PK     | P               | IDX_COL_1

ALTER TABLE tbl_test DISABLE PRIMARY KEY;
-- OR
-- ALTER TABLE tbl_test DISABLE CONSTRAINT tbl_test_pk;

-- Once the PK is disabled, the association with the index is gone
SELECT constraint_name, constraint_type, index_name, status
  FROM user_constraints
 WHERE table_name = 'TBL_TEST';

CONSTRAINT_NAME | CONSTRAINT_TYPE | INDEX_NAME | STATUS
TBL_TEST_PK     | P               |            | DISABLED
</pre><p><strong>4. Once PK constraint is disabled, the index left on that column can be dropped.</strong><br /> If the index was created by oracle with the creation of PK constraint, it will be dropped automatically. If some existing index was associated with the PK constraint, it will not be dropped by oracle(refer point 6 for details). But its now possible to drop that index manually.</p><pre class="brush: sql; title: ; notranslate">
-- With the primary key disabled, the index can now be dropped
DROP INDEX idx_col_1;

SELECT table_name, index_name
  FROM user_indexes
 WHERE table_name = 'TBL_TEST';

-- no rows returned.
</pre><p><strong>5. Enabling of the PK constraint requires association with index.</strong><br /> If we now try to enable the PK constraint again, it will pick up the first index it found on that column and will get associated with it. In case there is no index to get associated, oracle will create a new index with the name same as that of PK constraint.</p><pre class="brush: sql; title: ; notranslate">
ALTER TABLE tbl_test ENABLE PRIMARY KEY;
-- OR
-- ALTER TABLE  tbl_test ENABLE CONSTRAINT tbl_test_pk;

-- Oracle has created a new index with name &quot;TBL_TEST_PK&quot;
SELECT constraint_name, constraint_type, index_name
  FROM user_constraints
 WHERE table_name = 'TBL_TEST';

-- A new index &quot;TBL_TEST_PK&quot; is created and associated with the PK constraint
-- CONSTRAINT_NAME | CONSTRAINT_TYPE | INDEX_NAME
-- TBL_TEST_PK     | P               | TBL_TEST_PK

SELECT table_name, index_name
  FROM user_indexes
 WHERE table_name = 'TBL_TEST';

-- TABLE_NAME | INDEX_NAME
-- TBL_TEST   | TBL_TEST_PK
</pre><p><strong>6. Use &#8220;USING INDEX&#8221; clause to associated a particular index with the PK.</strong><br /> If there are more than one indexes on the column on which you want to add PK constraint, we can selectively choose the index to be assoicated with the PK using &#8220;<strong>USING INDEX</strong>&#8220;. This clause can be used while:<br /> a) Adding the PK constraint for the first time (using &#8220;ALTER TABLE&#8221; command).</p><pre class="brush: sql; title: ; notranslate">
DROP TABLE tbl_test;

CREATE TABLE tbl_test ( col_1 NUMBER,
                        col_2 NUMBER,
                        col_3 NUMBER);

CREATE INDEX idx_col_1_2 ON tbl_test(col_1, col_2);

CREATE INDEX idx_col_1_3 ON tbl_test(col_1, col_3);

CREATE UNIQUE INDEX idx_col_1 ON tbl_test(col_1);

-- Forcing oracle to use the unique index &quot;IDX_COL_1&quot;
ALTER TABLE tbl_test ADD CONSTRAINT tbl_test_pk PRIMARY KEY(col_1)
USING INDEX idx_col_1;

SELECT constraint_name, constraint_type, index_name
  FROM user_constraints
 WHERE table_name = 'TBL_TEST';

-- CONSTRAINT_NAME | CONSTRAINT_TYPE | INDEX_NAME
-- TBL_TEST_PK     | P               | IDX_COL_1
</pre><p>b) Enabling the PK constraint.</p><pre class="brush: sql; title: ; notranslate">
DROP TABLE tbl_test;

CREATE TABLE tbl_test ( col_1 NUMBER, col_2 NUMBER,
                        col_3 NUMBER);

CREATE INDEX idx_col_1_2 ON tbl_test(col_1, col_2);

CREATE INDEX idx_col_1_3 ON tbl_test(col_1, col_3);

CREATE UNIQUE INDEX idx_col_1 ON tbl_test(col_1);

ALTER TABLE tbl_test ADD CONSTRAINT tbl_test_pk PRIMARY KEY(col_1);

SELECT table_name, index_name, uniqueness
  FROM user_indexes
 WHERE table_name = 'TBL_TEST';

-- TABLE_NAME | INDEX_NAME  | UNIQUENESS
-- TBL_TEST   | IDX_COL_1_2 | NONUNIQUE
-- TBL_TEST   | IDX_COL_1_3 | NONUNIQUE
-- TBL_TEST   | IDX_COL_1   | UNIQUE

-- Although an unique index exists, oracle has picked up the first index
SELECT constraint_name, constraint_type, index_name
  FROM user_constraints
 WHERE table_name = 'TBL_TEST';

-- CONSTRAINT_NAME | CONSTRAINT_TYPE | INDEX_NAME
-- TBL_TEST_PK     | P               | IDX_COL_1_2

ALTER TABLE tbl_test DISABLE PRIMARY KEY;

-- Forcing oracle to use the unique index
ALTER TABLE  tbl_test ENABLE CONSTRAINT TBL_TEST_PK USING INDEX IDX_COL_1;

SELECT constraint_name, constraint_type, index_name
  FROM user_constraints
 WHERE table_name = 'TBL_TEST';

-- CONSTRAINT_NAME | CONSTRAINT_TYPE | INDEX_NAME
-- TBL_TEST_PK     | P               | IDX_COL_1
</pre><p>Manully associating PK constraint with already existing unique/non-unique index has the following advantages:<br /> a) The index remains available and valid when the constraint is disabled.<br /> b) Enabling the PK constraint doesn&#8217;t require rebuilding the unique/non-unique index associated with the constraint.<br /> c) The redundant indexes can be eliminated. PK constraint can be associated with a composite index too if the column is included as the prefix of the composite index. So, in the example above, it iss possible to remove the unique index (if not required) and the composite index can be used for PK enforcement.</p><p><strong>7. The index associated with the PK constraint needn&#8217;t be unique.</strong><br /> A non-unique index can also be be associated with the PK constraints. Now the question is <strong>how oracle allows PK constraint to be enforced using a non-unique index</strong>. Here is the explanation (as per best of my knowledge, might not be correct):</p><p>As described above, PK constraint is a rule to prohibit duplicate/null records for the PK column. Suppose, we already have 1 Million records in the table and inserting a new entry. So, to enforce the PK constraint, Oracle has to search through the already present records and this is where the index comes handy. If you have an index on that column, the search will be quite fast. The unique index will be the best but a non-unique index will also be a better option as compared to a full table scan. So, the basic purpose of associating index with PK constraints is to efficiently enforce the underlying rule. So, using index for PK constraint enforcement is a part of Oracle architecture (I assume its the same for all other RDBMS).</p><pre class="brush: sql; title: ; notranslate">
DROP TABLE tbl_test;

CREATE TABLE tbl_test ( col_1 NUMBER, col_2 NUMBER,
                        col_3 NUMBER);

CREATE INDEX idx_col_1_2 ON tbl_test(col_1, col_2);

-- Associating composite index with the PK constraint
ALTER TABLE tbl_test ADD CONSTRAINT tbl_test_pk PRIMARY KEY(col_1)
USING INDEX idx_col_1_2;

SELECT constraint_name, constraint_type, index_name
  FROM user_constraints
 WHERE table_name = 'TBL_TEST';

-- CONSTRAINT_NAME | CONSTRAINT_TYPE | INDEX_NAME
-- TBL_TEST_PK     | P               | IDX_COL_1_2

 SELECT table_name, index_name, uniqueness
  FROM user_indexes
 WHERE table_name = 'TBL_TEST';

-- TABLE_NAME | INDEX_NAME  | UNIQUENESS
-- TBL_TEST   | IDX_COL_1_2 | NONUNIQUE
</pre><p><strong>8. Merits of allowing non-unique index for enforcing PK constraints</strong>:<br /> a) The non-unique indexes facilitates the use of &#8220;<strong>INITIALLY DEFERRED</strong>&#8221; clause with the constraint until the transaction has been committed if the PK constraint has been defined as &#8220;<strong>DEFERRABLE</strong>&#8221; at the time of creating. The &#8220;<strong>DEFERRABLE</strong>&#8221; PK constraint can&#8217;t be associated with a unique index.</p><pre class="brush: sql; title: ; notranslate">
DROP TABLE tbl_test;

CREATE TABLE tbl_test ( col_1 NUMBER,
                        col_2 NUMBER);

ALTER TABLE tbl_test ADD CONSTRAINT tbl_test_pk PRIMARY KEY(col_1)
INITIALLY DEFERRED DEFERRABLE;

-- The resulting index created by oracle is non-unique
SELECT table_name, index_name, uniqueness
  FROM user_indexes
 WHERE table_name = 'TBL_TEST';

-- TABLE_NAME | INDEX_NAME  | UNIQUENESS
-- TBL_TEST   | TBL_TEST_PK | NONUNIQUE

-- Allowing duplicate records inspite of the presence of PK consraint
INSERT INTO tbl_test VALUES (1,2);
INSERT INTO tbl_test VALUES (1,2);
INSERT INTO tbl_test VALUES (1,2); 

-- Constraint checked at the time of transaction commit
COMMIT;
-- ORA-02091: transaction rolled back
-- ORA-00001: unique constraint (GC_ADMIN.TBL_TEST_PK) violated
</pre><p>b) The &#8220;<strong>NOVALIDATE</strong>&#8221; option can be used to exclude the enforcement of constraint on the already existing data.</p><pre class="brush: sql; title: ; notranslate">
DROP TABLE tbl_test purge;

CREATE TABLE tbl_test ( col_1 NUMBER);

INSERT INTO tbl_test VALUES (1);
INSERT INTO tbl_test VALUES (1);
INSERT INTO tbl_test VALUES (1);

ALTER TABLE tbl_test add constraint idx_col_1 PRIMARY KEY (col_1) NOVALIDATE;
-- ORA-02437: cannot validate (GC_ADMIN.IDX_COL_1) - primary key violated

ALTER TABLE tbl_test add constraint idx_col_1 PRIMARY KEY (col_1) DISABLE;

ALTER TABLE tbl_test ENABLE NOVALIDATE PRIMARY KEY;
-- ORA-02437: cannot validate (GC_ADMIN.IDX_COL_1) - primary key violated

-- This is because oracle tries to create unique index for the PK constraints.
-- The statement fails while checking the uniqueness for creating the unique index.
-- To fix this, create a non-unique index first. Then oracle will associate
-- the primary key constraint with this non-unique index.
CREATE INDEX idx_col_1 ON tbl_test(col_1);

ALTER TABLE tbl_test ENABLE NOVALIDATE PRIMARY KEY;
</pre><p><strong>9. Bitmap index can&#8217;t be associated with a PK constraint.</strong></p><pre class="brush: sql; title: ; notranslate">
DROP TABLE tbl_test;

CREATE TABLE tbl_test ( col_1 NUMBER,
                        col_2 NUMBER,
                        col_3 NUMBER);

CREATE BITMAP INDEX idx_col_1 ON tbl_test (col_1);

ALTER TABLE tbl_test ADD CONSTRAINT tbl_test_pk PRIMARY KEY(col_1) USING INDEX idx_col_1;
-- ORA-14196: Specified index cannot be used to enforce the constraint.
</pre><p><strong>10. Dropping the PK may or may not drop the associated index.</strong><br /> If you drop a PK constraint, the associated index may or may not be dropped depending on the association of PK constraint and index. Two scenario arises:<br /> a) The PK constraint is associated with an already present index (either by using &#8220;USING INDEX&#8221; clause or by default association if not specifically specified). In that case, the index will not be dropped with the dropping of PK constraint.</p><pre class="brush: sql; title: ; notranslate">
DROP TABLE tbl_test;

CREATE TABLE tbl_test ( col_1 NUMBER);

CREATE INDEX idx_col_1 ON tbl_test (col_1);

ALTER TABLE tbl_test ADD CONSTRAINT tbl_test_pk PRIMARY KEY(col_1)
USING INDEX idx_col_1;

ALTER TABLE tbl_test DROP PRIMARY KEY;

-- Primary Key dropped
SELECT constraint_name, constraint_type, index_name
  FROM user_constraints
 WHERE table_name = 'TBL_TEST';

-- no rows selected.
-- The index is still present
 SELECT table_name, index_name, uniqueness
  FROM user_indexes
 WHERE table_name = 'TBL_TEST';

-- TABLE_NAME | INDEX_NAME | UNIQUENESS
-- TBL_TEST   | IDX_COL_1  | NONUNIQUE
</pre><p>b) If the PK constraint is created while there is no index on PK column, oracle will create a new unique index with the same name as PK constraint. By default, this index will be dropped with the dropping of PK constraint. You can keep this index intact by using the &#8220;<strong>KEEP INDEX</strong>&#8221; clause.</p><pre class="brush: sql; title: ; notranslate">
DROP TABLE tbl_test;

CREATE TABLE tbl_test ( col_1 NUMBER);

ALTER TABLE tbl_test ADD CONSTRAINT tbl_test_pk PRIMARY KEY(col_1);

SELECT constraint_name, constraint_type, index_name
  FROM user_constraints
 WHERE table_name = 'TBL_TEST';

-- CONSTRAINT_NAME | CONSTRAINT_TYPE | INDEX_NAME
-- TBL_TEST_PK     | P               | TBL_TEST_PK

SELECT table_name, index_name, uniqueness
  FROM user_indexes
 WHERE table_name = 'TBL_TEST';

-- TABLE_NAME | INDEX_NAME  | UNIQUENESS
-- TBL_TEST   | TBL_TEST_PK | UNIQUE

ALTER TABLE tbl_test DROP PRIMARY KEY;

SELECT constraint_name, constraint_type, index_name
  FROM user_constraints
 WHERE table_name = 'TBL_TEST';

-- no rows selected.

 SELECT table_name, index_name, uniqueness
  FROM user_indexes
 WHERE table_name = 'TBL_TEST';

-- no rows selected.

ALTER TABLE tbl_test ADD CONSTRAINT tbl_test_pk PRIMARY KEY(col_1);

ALTER TABLE tbl_test DROP PRIMARY KEY KEEP INDEX;

-- The PK constraint is gone
SELECT constraint_name, constraint_type, index_name
  FROM user_constraints
 WHERE table_name = 'TBL_TEST';

-- no rows selected.
-- Yet the index created by oracle is still there
 SELECT table_name, index_name, uniqueness
  FROM user_indexes
 WHERE table_name = 'TBL_TEST';

-- TABLE_NAME | INDEX_NAME  | UNIQUENESS
-- TBL_TEST   | TBL_TEST_PK | UNIQUE
</pre><p>Please note that the above mentioned points are also more or less applicable for Unique key(UK) constraints. I haven&#8217;t tried to touch that subject to keep the content precise.<br /> All queries are tested and verified on Oracle 10.2.0.4 version.</p><p><em><strong>Disclaimer:</strong> All data and information provided on this article is for informational purposes only. Author makes no representations as to accuracy, completeness, suitability, or validity of any information on this article. All information is provided on an as-is basis.</em></p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2010/06/invisible-indexes-in-oracle-11g.html" title="Invisible Indexes in Oracle 11g">Invisible Indexes in Oracle 11g</a></li><li><a href="http://viralpatel.net/blogs/2010/11/row-data-multiplication-in-oracle.html" title="Row Data Multiplication in Oracle">Row Data Multiplication in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/07/generating-random-data-in-oracle.html" title="Generating Random Data in Oracle">Generating Random Data in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/06/deleting-duplicate-rows-in-oracle.html" title="Deleting Duplicate Rows in Oracle">Deleting Duplicate Rows in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/06/oracle-data-compression.html" title="Oracle Data Compression">Oracle Data Compression</a></li><li><a href="http://viralpatel.net/blogs/2009/05/fetch-random-rows-from-database-mysql-oracle-ms-sql-postgresql-example.html" title="Fetch Random rows from Database (MySQL, Oracle, MS SQL, PostgreSQL)">Fetch Random rows from Database (MySQL, Oracle, MS SQL, PostgreSQL)</a></li><li><a href="http://viralpatel.net/blogs/2009/04/full-text-search-using-mysql-full-text-search-capabilities.html" title="Full-Text Search using MySQL: Full-Text Search Capabilities">Full-Text Search using MySQL: Full-Text Search Capabilities</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2010/02/understanding-primary-keypk-constraint-in-oracle.html/feed</wfw:commentRss> <slash:comments>5</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced

Served from: viralpatel.net @ 2012-02-09 03:12:31 -->
