<?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>dbsnaps</title>
	<atom:link href="http://www.dbsnaps.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dbsnaps.com</link>
	<description>database video tutorials</description>
	<lastBuildDate>Mon, 06 Sep 2010 10:41:25 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Replicating virtual machines with Oracle databases</title>
		<link>http://www.dbsnaps.com/oracle/replicating-virtual-machines-with-oracle-databases/</link>
		<comments>http://www.dbsnaps.com/oracle/replicating-virtual-machines-with-oracle-databases/#comments</comments>
		<pubDate>Mon, 23 Aug 2010 11:12:44 +0000</pubDate>
		<dc:creator>Roni Vered</dc:creator>
				<category><![CDATA[Administration]]></category>
		<category><![CDATA[Main-Administration]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Oracle - Latest Articles]]></category>
		<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[Database Control]]></category>
		<category><![CDATA[emca]]></category>
		<category><![CDATA[virtual machines]]></category>

		<guid isPermaLink="false">http://www.dbsnaps.com/?p=418</guid>
		<description><![CDATA[Virtual machines are used in many organizations due to the simplicity of administration, especially in development environments.

This post will describe how to configure the new replicated machine to work with the Oracle database.]]></description>
			<content:encoded><![CDATA[<p>Virtual machines are used in many organizations due to the simplicity of administration, especially in development environments.</p>
<p>One popular use of virtualization, is creating a MASTER image of one virtual machine and then copy it when necessary.</p>
<p><span style="font-size: 13.3333px">But, what do we do when we need an Oracle Database on this machine. How can we replicate the machine and work with the database.</span></p>
<p><span style="font-size: 13.3333px">Moreover, will the Database itself and the Database Control (Oracle Enterprise Manager) work on the new machine?</span></p>
<p>Below are the steps to configure the database and the Database control in the new machine.<br />
The following steps were performed on Oracle Database 10g Release 2 (10.2.0.4) 64-bit, on CentOS 5 (64-bit) virtual machine :</p>
<p><strong>Database:</strong></p>
<ul>
<li>Change the hostname in the file <strong>$ORACLE_HOME/network/admin/listener.ora</strong><br />
for example:</li>
</ul>
<pre class="brush: plain;">
LISTENER =
   (DESCRIPTION_LIST =
    (DESCRIPTION =
     (ADDRESS = (PROTOCOL = TCP)(HOST = NEW_HOSTNAME)(PORT = 1521))
    )
   )
</pre>
<ul>
<li>Change the hostname in the file <strong>$ORACLE_HOME/network/admin/tnsnames.ora</strong><br />
Please change the hostname in all the relevant entries.<br />
for example:</li>
</ul>
<pre class="brush: plain;">
 ORCL1 =
   (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = NEW_HOSTNAME)(PORT = 1521))
     (CONNECT_DATA =
     (SERVER = DEDICATED)
     (SERVICE_NAME = orcl1)
    )
   )
</pre>
<p><strong>Database Control:</strong></p>
<p>Recreating the Database control repository is needed. without it, the Database Control won&#8217;t start.<br />
In order to recreate the DB control run following commands:</p>
<ul>
<li>Dropping the current DB control&#8217;s settings.<br />
In the &lt;NEW HOSTNAME&gt; please make sure to write the new hostname.</li>
</ul>
<pre class="brush: plain;">
$ emca -deconfig dbcontrol db -repos drop -ORACLE_HOSTNAME &lt;NEW HOSTNAME&gt; -SID &lt;ORACLE_SID&gt; -PORT &lt;Listener's Port&gt; -SYSMAN_PWD &lt;SYSMAN password&gt; -SYS_PWD &lt;SYS password&gt;&lt;/pre&gt;
</pre>
<p><span style="font-size: 11.6667px"> Information in regards the different &#8216;emca&#8217; attributes can be acquire by running &#8216;emca&#8217; without any attribute from the CMD. </span></p>
<pre class="brush: plain;"> $ emca -deconfig dbcontrol db -repos drop -ORACLE_HOSTNAME ORCLSERVER -SID orcl1 -PORT 1521 -SYSMAN_PWD **** -SYS_PWD ****

STARTED EMCA at Jun 17, 2010 7:54:31 PM EM Configuration Assistant, Version 11.2.0.0.2   Production Copyright (c) 2003, 2005, Oracle.  All rights reserved.
Do you wish to continue? [yes(Y)/no(N)]: y

Jun 17, 2010 7:54:49 PM oracle.sysman.emcp.EMConfig   perform
INFO: This operation is being logged at   /u01/app/oracle/cfgtoollogs/emca/orcl/emca_2010_06_17_19_54_31.log.

Jun 17, 2010 7:54:50 PM   oracle.sysman.emcp.EMDBPreConfig performDeconfiguration
WARNING: EM is not configured for this database. No   EM-specific actions can be performed.
Jun 17, 2010 7:54:50 PM   oracle.sysman.emcp.ParamsManager checkListenerStatusForDBControl WARNING: Error initializing SQL connection. SQL   operations cannot be performed

Jun 17, 2010 7:54:50 PM oracle.sysman.emcp.EMReposConfig   invoke INFO: Dropping the EM repository (this may take a   while) ...

Jun 17, 2010 7:54:50 PM   oracle.sysman.emcp.EMReposConfig invoke INFO: Repository successfully dropped Enterprise Manager configuration completed
successfully FINISHED EMCA at Jun 17, 2010 7:54:50 PM </pre>
<ul>
<li><span style="font-size: 11.6667px">Recreating the DB control&#8217;s repository.<br />
</span><span style="font-size: 13.3333px">In the &lt;NEW HOSTNAME&gt; please make sure to write the new hostname.</span></li>
</ul>
<pre class="brush: plain;">
$emca -config dbcontrol db -ORACLE_HOSTNAME &lt;NEW HOSTNAME&gt; -SID &lt;ORACLE_SID&gt; -PORT &lt;Listener's  Port&gt; -SYS_PWD &lt;SYSMAN password&gt; -SYSMAN_PWD &lt;SYSMAN  password&gt; -DBSNMP_PWD &lt;DBSNMP password&gt;
</pre>
<p><span style="font-size: 11.6667px">After this step the Database Control&#8217;s repository will be recreated and you will able to connect the Database control&#8217;s URL.</span></p>
<pre class="brush: plain;">$ emca -config dbcontrol db -ORACLE_HOSTNAME ORCLSERVER -SID orcl1 -PORT 1521 -SYS_PWD **** -SYSMAN_PWD **** -DBSNMP_PWD ****
STARTED EMCA at Jun 17, 2010 8:04:27 PM

EM Configuration Assistant, Version 11.2.0.0.2   Production
Copyright (c) 2003, 2005, Oracle.  All rights reserved.
Enter the following information:
Email address for notifications (optional):
Outgoing Mail (SMTP) server for notifications (optional):
-----------------------------------------------------------------
You have specified the following settings

Database ORACLE_HOME ................   /u01/app/oracle/product/11.2.0/db_1

Local hostname ................ &lt;HOSTNAME&gt;

Listener ORACLE_HOME ................   /u01/app/oracle/product/11.2.0/db_1

Listener port number ................ 1521

Database SID ................ orcl1

Email address for notifications ...............

Outgoing Mail (SMTP) server for notifications   ...............

-----------------------------------------------------------------

Do you wish to continue? [yes(Y)/no(N)]: y

Jun 17, 2010 8:04:44 PM oracle.sysman.emcp.EMConfig   perform
INFO: This operation is being logged at   /u01/app/oracle/cfgtoollogs/emca/orcl2/emca_2010_06_17_20_04_27.log          .

Jun 17, 2010 8:04:45 PM   oracle.sysman.emcp.EMReposConfig uploadConfigDataToRepository
INFO: Uploading configuration data to EM repository   (this may take a while) ...

Jun 17, 2010 8:05:43 PM   oracle.sysman.emcp.EMReposConfig invoke
INFO: Uploaded configuration data successfully

Jun 17, 2010 8:05:44 PM   oracle.sysman.emcp.util.DBControlUtil configureSoftwareLib
INFO: Software library is already configured.

Jun 17, 2010 8:05:44 PM   oracle.sysman.emcp.util.DBControlUtil configureSoftwareLib
INFO:    EM_SWLIB_STAGE_LOC (value) will be ignored.

Jun 17, 2010 8:05:44 PM   oracle.sysman.emcp.EMDBPostConfig configureSoftwareLibrary
INFO: Deploying   Provisioning archives ...

Jun 17, 2010 8:06:09 PM   oracle.sysman.emcp.EMDBPostConfig configureSoftwareLibrary
INFO: Provisioning archives deployed successfully.

Jun 17, 2010 8:06:09 PM   oracle.sysman.emcp.util.DBControlUtil secureDBConsole
INFO: Securing Database Control (this may take a   while) ...

Jun 17, 2010 8:06:34 PM   oracle.sysman.emcp.util.DBControlUtil secureDBConsole
INFO: Database Control secured successfully.

Jun 17, 2010 8:06:34 PM   oracle.sysman.emcp.util.DBControlUtil startOMS
INFO: Starting Database Control (this may take a   while) ...

Jun 17, 2010 8:07:28 PM oracle.sysman.emcp.EMDBPostConfig   performConfiguration
INFO: Database Control started successfully

Jun 17, 2010 8:07:28 PM   oracle.sysman.emcp.EMDBPostConfig performConfiguration
INFO: &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;   The Database Control URL is https://HOSTNAME:1158/em   &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;

Jun 17, 2010 8:07:36 PM   oracle.sysman.emcp.EMDBPostConfig invoke
WARNING:
************************  WARNING    ************************
Management Repository has been placed in secure mode   wherein Enterprise Manager data will be encrypted.  The encryption key has been placed in the   file: /u01/app/oracle/product/11.2.0/db_1/HOSTNAME_orcl2/sysman/config/emkey.ora.   Please ensure this file is backed up as   the encrypted data will become unusable if this file is lost.
***********************************************************

Enterprise Manager configuration completed   successfully

FINISHED EMCA at Jun 17, 2010 8:07:36 PM
</pre>
<p><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;line-height: 22px;font-size: 13.3333px"><strong>Known Issues:</strong> </span></p>
<p><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;line-height: 22px;font-size: 13.3333px">In case no new hostname is provided in the attribute </span><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;line-height: 26px;font-size: 13.3333px">&#8216;–ORACLE_HOSTNAME&#8217; of the emca command, the utility will use the <strong>old</strong> hostname and the drop/create operation will fail. </span></p>
<p><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;line-height: 26px;font-size: 13.3333px"> </span><br />
<span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;line-height: 26px;font-size: 13.3333px"><strong>For more information in regards to Drop, Create And Recreate DB Control, please refer to Metalink note</strong><strong>:</strong><strong> <span style="text-decoration: underline">278100.1</span></strong></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbsnaps.com/oracle/replicating-virtual-machines-with-oracle-databases/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Oracle Wait Event &#8211; db file sequential read</title>
		<link>http://www.dbsnaps.com/oracle/oracle-wait-event-db-file-sequential-read/</link>
		<comments>http://www.dbsnaps.com/oracle/oracle-wait-event-db-file-sequential-read/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 14:35:51 +0000</pubDate>
		<dc:creator>Liron Amitzi</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Oracle - Latest Articles]]></category>
		<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[AWR]]></category>
		<category><![CDATA[db file sequential read]]></category>
		<category><![CDATA[db sequential read]]></category>
		<category><![CDATA[sequential]]></category>
		<category><![CDATA[wait event]]></category>

		<guid isPermaLink="false">http://www.dbsnaps.com/?p=415</guid>
		<description><![CDATA[db file sequential read is an important and common wait event in Oracle databases. We'll try to understand what it means.]]></description>
			<content:encoded><![CDATA[<p>There are 2 main I/O related wait events in Oracle: &#8220;db file scattered read&#8221; and &#8220;db file sequential read&#8221;. In this post we will understand the &#8220;db file sequential read&#8221; wait event (to read about &#8220;db file scattered read&#8221; go to the <a href="http://www.dbsnaps.com/uncategorized/oracle-wait-event-db-file-scattered-read" target="_self">db file scattered read</a> post)</p>
<p>A server process is waiting on &#8220;db file sequential read&#8221; wait event after it performs a single block I/O operation and it is waiting for the operating system to complete it.</p>
<p>A single block I/O operation occurs when a server process request a single block for the operating system. This happens during operations such as index unique or range scans, table access by rowid, etc.</p>
<p>Seeing this wait event in the top wait events is expected and doesn&#8217;t mean that something is wrong. Remember, users are working and reading indexes or table blocks from the disk is common. However, if we see that this event is very high and consuming unreasonable time, we need to check our SQL statement, they might need tuning, or might have unnecessary hints such as the &#8220;index&#8221; hint.</p>
<p>To read about analyzing wait events in an AWR report, see my post <a href="http://www.dbsnaps.com/uncategorized/analyzing-oracle-awr-reports-top-5-events" target="_self">analyzing oracle awr reports &#8211; top 5 events</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbsnaps.com/oracle/oracle-wait-event-db-file-sequential-read/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Oracle Wait Event &#8211; db file scattered read</title>
		<link>http://www.dbsnaps.com/oracle/oracle-wait-event-db-file-scattered-read/</link>
		<comments>http://www.dbsnaps.com/oracle/oracle-wait-event-db-file-scattered-read/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 14:35:18 +0000</pubDate>
		<dc:creator>Liron Amitzi</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Oracle - Latest Articles]]></category>
		<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[AWR]]></category>
		<category><![CDATA[db file scattered read]]></category>
		<category><![CDATA[db scattered read]]></category>
		<category><![CDATA[scattered]]></category>
		<category><![CDATA[scattered read]]></category>
		<category><![CDATA[wait event]]></category>

		<guid isPermaLink="false">http://www.dbsnaps.com/?p=405</guid>
		<description><![CDATA[db file scattered read is an important and common wait event in Oracle databases. We'll try to understand what it means.]]></description>
			<content:encoded><![CDATA[<p>There are 2 main I/O related wait events in Oracle: &#8220;db file scattered read&#8221; and &#8220;db file sequential read&#8221;. In this post we will understand the &#8220;db file scattered read&#8221; wait event (to read about &#8220;db file sequential read&#8221; go to the <a href="http://www.dbsnaps.com/uncategorized/oracle-wait-event-db-file-sequential-read" target="_self">db file sequential read</a> post).</p>
<p>A server process is waiting on &#8220;db file scattered read&#8221; wait event after it performs a multiblock I/O operation and it is waiting for the operating system to complete it.</p>
<p>A multiblock I/O operation occurs when the server process asks for a &#8220;chunk&#8221; of blocks and not for a single block. The amount of blocks in the &#8220;chunk&#8221; is determined by the DB_FILE_MULTIBLOCK_READ_COUNT initialization parameter. For example, if the database block size is 8k and DB_FILE_MULTIBLOCK_READ_COUNT is 8, a single multiblock I/O operation will read 8 blocks, which is 64KB of data. The maximum size of a multiblock I/O operation is determined by the   operating system and storage.</p>
<p>When talking about performance, there are several things we need to remember:</p>
<ul>
<li>A server process can perform multiblock I/O operations only in certain cases like full table scans and fast full index scans. It is important to remember that multiblock I/O and DB_FILE_MULTIBLOCK_READ_COUNT are irrelevant to other operations such as index  range/unique scans.</li>
<li>Setting the DB_FILE_MULTIBLOCK_READ_COUNT to a high value will result in less I/O operations (as long as it is not exceeding the operating system and storage limitation).</li>
<li>Setting the DB_FILE_MULTIBLOCK_READ_COUNT to a high value can also result in unwanted full table scans, since a higher value lowers the optimizer cost of full table scans.</li>
<li>Starting in 10gR2, Oracle will determine the best value for the DB_FILE_MULTIBLOCK_READ_COUNT parameter if it is not set. If the parameter is set, Oracle will not automatically set its value.</li>
</ul>
<p>To read about analyzing wait events in an AWR report, see my post <a href="http://www.dbsnaps.com/uncategorized/analyzing-oracle-awr-reports-top-5-events" target="_self">analyzing oracle awr reports &#8211; top 5 events</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbsnaps.com/oracle/oracle-wait-event-db-file-scattered-read/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Analyzing Oracle AWR reports &#8211; top 5 events</title>
		<link>http://www.dbsnaps.com/oracle/analyzing-oracle-awr-reports-top-5-events/</link>
		<comments>http://www.dbsnaps.com/oracle/analyzing-oracle-awr-reports-top-5-events/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 14:34:23 +0000</pubDate>
		<dc:creator>Liron Amitzi</dc:creator>
				<category><![CDATA[Main-Performance]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Oracle - Latest Articles]]></category>
		<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[Automatic Workload Repository]]></category>
		<category><![CDATA[AWR]]></category>
		<category><![CDATA[wait event]]></category>

		<guid isPermaLink="false">http://www.dbsnaps.com/?p=393</guid>
		<description><![CDATA[This is the first post related to analyzing AWR reports. We will focus on the "top 5 events" of the page, what is the importance of this part and understanding some of the main wait events.]]></description>
			<content:encoded><![CDATA[<p>This is the first post related to analyzing AWR reports. We will focus on the &#8220;top 5 events&#8221; section,understand its importance and see some of the main wait events.</p>
<p>From Oracle documentation:<br />
<em><strong>&#8220;Wait events are statistics that are incremented by a server process or thread to indicate that it had to wait for an event to complete before being able to continue processing.&#8221;</strong></em></p>
<p>For example, wait events can be related to I/O, locks, memory allocation, etc.</p>
<p>The top events tell us what the server processes wait for the most. Eliminating these wait events will definately reduce execution time, since server processes will not have to wait this time for other operations to complete.</p>
<p>There are many wait event in Oracle databases, this is a list of some important and common wait events:</p>
<ul>
<li>buffer busy waits</li>
<li>free buffer waits</li>
<li><a href="http://www.dbsnaps.com/uncategorized/oracle-wait-event-db-file-scattered-read" target="_self">db file scattered read</a></li>
<li><a href="http://www.dbsnaps.com/uncategorized/oracle-wait-event-db-file-sequential-read" target="_self">db file sequential read</a></li>
<li>enqueue waits</li>
<li>log buffer space</li>
<li>log file sync</li>
</ul>
<p>To identify a performance problem we will check the time spent on each wait event and the average wait time. These numbers can be very different for different wait events, I/O wait events will probably have a low average, while waiting on locking related wait events can take a long time. Don&#8217;t forget to compare the wait time to the AWR report time period, waiting on I/O for an hour may be reasonable if the AWR report was generated on 6 hours period, but may indicate a problem on a 10 minutes report (the waiting time can exceed the total report time, since it is cumulative for all server processes).</p>
<p>The best way to find performance problems is to compare the wait events and the time spent on them to an AWR report from a time period in which the database worked fine. So try to save reports as a baseline for future reference.</p>
<p>In the next posts we&#8217;ll go deeper into analyzing the rest of the AWR report.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbsnaps.com/oracle/analyzing-oracle-awr-reports-top-5-events/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rolling back TRUNCATE statements in SQL Server</title>
		<link>http://www.dbsnaps.com/sql-server/tips-tricks-sql-server/rolling-back-truncate-statements-in-sql-server/</link>
		<comments>http://www.dbsnaps.com/sql-server/tips-tricks-sql-server/rolling-back-truncate-statements-in-sql-server/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 09:49:58 +0000</pubDate>
		<dc:creator>Roni Vered</dc:creator>
				<category><![CDATA[Administration]]></category>
		<category><![CDATA[Main-Administration]]></category>
		<category><![CDATA[SQL Server - Latest Articles]]></category>
		<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[BEGIN TRAN]]></category>
		<category><![CDATA[DELETE]]></category>
		<category><![CDATA[Rollback]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[TRUNCATE]]></category>

		<guid isPermaLink="false">http://www.dbsnaps.com/?p=374</guid>
		<description><![CDATA[There are two main ways to delete all records from a table - DELETE and TRUNCATE commands, but if we do, can we rollback the operation?]]></description>
			<content:encoded><![CDATA[<p>There are two main statements used for deleting data from a table in SQL SERVER:</p>
<ul>
<li>TRUNCATE</li>
<li>DELETE</li>
</ul>
<p>The two commands achieve the same result; however, each of the commands acts a little bit different. Each of the two commands have advantages, limitations, and consequences, which have to be considered when deciding which method to use.</p>
<p>In this post we will concentrate in <em>one</em> aspect of these commands usage – <em>the ability to rollback each operation</em>.</p>
<p>DELETE statements delete rows one at a time, logging each row in the transaction log and maintaining the log sequence number (LSN) information.<br />
Even though it will consumes more database resources, it comes in handy as these transactions can be <strong>rolled back</strong> if necessary by using the log files, when the recovery model of the database is set to full.</p>
<p>But what happens when you issue the <em>TRUNCATE </em>command?</p>
<p>The TRUNCATE statement is much faster statement than the DELETE command.<br />
It deletes all records in a table by deallocating the data pages used to store the table&#8217;s data. This operation has a limited logging in the transaction log (only the page deallocations are recorded in the transaction log). In addition fewer locks are acquired with this statement in compare to the DELETE statement.<br />
As a result of the above it is commonly believed that records removed by the TRUNCATE statement cannot be restored – rolled back.</p>
<p>It is true in most cases, however <strong>DELETE and TRUNCATE can both be rolled back</strong> when they are executed inside a ‘BEGIN <em>TRANSACTION’</em> block and the current session has not yet ended.<br />
In other words, when the TRUNCATE statement has not been committed yet, it can be rolled back</p>
<p>The following code demonstrates a scenario when a TRUNCATE can be rolled back for that particular session.</p>
<pre class="brush: sql;">
--Creating a testTable for the demonstration
CREATE TABLE TESTTABLE (ID INT)

--Inserting rows into the testTable.
INSERT INTO TESTTABLE
SELECT TOP 1000 OBJECT_ID FROM SYS.OBJECTS
BEGIN TRAN
   --Truncating the table
   TRUNCATE TABLE TESTTABLE
   --No rows will return
   SELECT * FROM TESTTABLE
ROLLBACK

--The original rows from testTable will return
SELECT * FROM TESTTABLE

--Dropping the testTable.
DROP TABLE TESTTABLE
</pre>
<p><strong>To summarize,<br />
</strong>DELETE can always be rolled back-</p>
<ul>
<li><span style="font-size: 13.3333px">When the recovery model of the database is set to SIMPLE, the statement can be rolled back &#8211; when the statement is executed inside a ‘BEGIN TRANSACTION’ block.</span></li>
<li><span style="font-size: 13.3333px">When the recovery model of the database is set to FULL, the statement can also be recovered from the log files.</span></li>
</ul>
<p><span style="font-size: 13.3333px">TRUNCATE can or cannot be rolled back, depends if it is executed from within a ‘BEGIN TRANSACTION’ block.</span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbsnaps.com/sql-server/tips-tricks-sql-server/rolling-back-truncate-statements-in-sql-server/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Determine query for Linux process</title>
		<link>http://www.dbsnaps.com/oracle/determine-query-for-linux-process/</link>
		<comments>http://www.dbsnaps.com/oracle/determine-query-for-linux-process/#comments</comments>
		<pubDate>Sat, 17 Jul 2010 14:29:17 +0000</pubDate>
		<dc:creator>Alon Spiegel</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Oracle - Latest Articles]]></category>
		<category><![CDATA[Tips & Tricks]]></category>

		<guid isPermaLink="false">http://www.dbsnaps.com/?p=348</guid>
		<description><![CDATA[In this article we will demonstrate how to retrieve the SQL statement of the most CPU consuming process in Linux/Unix]]></description>
			<content:encoded><![CDATA[<p>How many times a co-worker comes to you and tells you that the database is running slowly?<br />
Of course there are many reasons that can cause the database to slug, for example:</p>
<ol>
<li>High concurrency of active sessions</li>
<li>Queries using a lot of disk time such as full table scans</li>
<li>Long duration locks on rows</li>
<li>Hardware failure such as disks defect</li>
</ol>
<p>Another reason could be because there is a very CPU intensive query that is effecting the performance of the entire database.</p>
<p>This post will demonstrate how to determine which process is taking the most CPU in the system and how to retrieve the SQL statement it is currently running in the database.</p>
<p>** This post applies to Unix/Linux and Oracle 10g, 11g</p>
<p>In order to reach are goal we have to do the following things:</p>
<ol>
<li>Determine which process is consuming the most CPU in the system – we can use the TOP Linux/Unix command.</li>
<li>Finding out the query this process is running – we can prepare a script in advance to help us.</li>
</ol>
<p>Let’s begin with the preparations – preparing the script that will display the actual activity of the session within the database. The script will be a shell script that incorporates an SQL script within (you can find out more on this topic here <a href="http://www.dbsnaps.com/oracle/oracle-running-sqlplus-from-unix-bash-scripts/">oracle-running-sqlplus-from-unix-bash-scripts/</a>). The script receives an argument which is the Linux/Unix process ID of the process we want to examine. I usually put such scripts in a folder that is part of my $PATH such as ~/bin (or /home/oracle/bin).</p>
<p>Create a run-able script in Linux:</p>
<pre class="brush: bash;">
touch /home/oracle/bin/oraproc
chmod +x /home/oracle/bin/oraproc
vi /home/oracle/bin/oraproc
</pre>
<p>In this file write the a copy of the following snippet</p>
<pre class="brush: bash;">

#!/bin/bash
if [ $# -ne 1 ];then
	echo &quot;Usage: oraproc &lt;Unix Process ID&gt;&quot;
	exit
fi

unix_pid=$1

sqlplus -s -l / as sysdba &lt;&lt;EOF
set head off feed off time off timing off
set serveroutput on lines 10000
DECLARE
	stmt VARCHAR2(32000) := '';
	report BOOLEAN := TRUE;
	SPACECHAR CONSTANT CHAR(1) := ' ';
	TABLEN CONSTANT NUMBER(2) := 10;
BEGIN
	dbms_output.enable(99999);
	FOR rec IN (
		SELECT  s.sid, s.username, s.osuser, s.machine,
				nvl(s.module, s.program) prog, s.event, t.sql_text
		FROM    v\$process p
		JOIN    v\$session s ON s.paddr = p.addr
		LEFT JOIN v\$sqltext_with_newlines t
				ON	t.address = s.sql_address
				AND	t.hash_value = s.sql_hash_value
		WHERE   p.spid = ${unix_pid}
		ORDER BY t.piece ) LOOP

		stmt := stmt || rec.SQL_TEXT;
		IF report THEN
			DBMS_OUTPUT.PUT_LINE(RPAD('SID:', TABLEN, spacechar) || rec.sid);
			DBMS_OUTPUT.PUT_LINE(RPAD('USERNAME:', TABLEN, spacechar) || rec.username);
			DBMS_OUTPUT.PUT_LINE(RPAD('OSUSER:', TABLEN, spacechar) || rec.osuser);
			DBMS_OUTPUT.PUT_LINE(RPAD('MACHINE:', TABLEN, spacechar) || rec.machine);
			DBMS_OUTPUT.PUT_LINE(RPAD('PROGRAM:', TABLEN, spacechar) || rec.prog);
			DBMS_OUTPUT.PUT_LINE(RPAD('EVENT:', TABLEN, spacechar) || rec.event);
			DBMS_OUTPUT.PUT_LINE('---------------------------------------');
			report := FALSE;
		END IF;
	END LOOP;
	IF NOT report THEN
		IF LENGTH(stmt) &gt; 0 THEN
			DBMS_OUTPUT.PUT_LINE(stmt);
		ELSE
			DBMS_OUTPUT.PUT_LINE('No current running statement');
		END IF;
	ELSE
		DBMS_OUTPUT.PUT_LINE('Unix PID ${unix_pid} not found');
	END IF;
END;
/
EXIT
EOF
</pre>
<p>Now let’s see this script at work. I have written a PL/SQL anonymous block that uses a lot of CPU. It looks like this:</p>
<pre class="brush: sql;">
declare
	start_date date;
	end_time date;
	dum number;
begin
	start_date := sysdate;
	end_time := sysdate + 1/24/60; -- minute
	while end_time &gt; sysdate loop
		dum := 0;
		for i in 1..10000 loop
			dum := dum + 1;
		end loop;
	end loop;
	dbms_output.put_line (start_date || ' ' || end_time);
end;
/
</pre>
<p>This script runs for a minute in a loop so it uses CPU very intensively. I run it from one session and run the TOP command from another session like this:</p>
<p><a class="highslide" onclick="return vz.expand(this)" href="http://www.dbsnaps.com/wp-content/uploads/2010/07/top.jpg"><img class="alignnone size-medium wp-image-365" title="top" src="http://www.dbsnaps.com/wp-content/uploads/2010/07/top-300x186.jpg" alt="" width="300" height="186" /></a></p>
<p>Notice that we see the process ID 9530 takes 98% CPU time.</p>
<p>We use this PID as an argument to our script by calling it from shell like this:</p>
<p><strong>$ oraproc 9530</strong></p>
<p>This will display the actual statement this process is currently running in the database (with some additional info I like to add). It looks like this:</p>
<pre>$ oraproc 9503
SID:      1
USERNAME: DEMO
OSUSER:   oracle
MACHINE:  ora2
PROGRAM:  SQL Developer
EVENT:    SQL*Net message from client
---------------------------------------
declare
	start_date date;
	end_time date;
	dum number;
begin
	start_date := sysdate;
	end_time := sysdate + 1/24/60; -- minute
	while end_time &gt; sysdate loop
		dum := 0;
		for i in 1..10000 loop
			dum := dum + 1;
		end loop;
	end loop;
	dbms_output.put_line (start_date || ' ' || end_time);
end;</pre>
<p>Good luck.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbsnaps.com/oracle/determine-query-for-linux-process/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SQL Server &#8211; How to determine instance uptime</title>
		<link>http://www.dbsnaps.com/sql-server/334/</link>
		<comments>http://www.dbsnaps.com/sql-server/334/#comments</comments>
		<pubDate>Fri, 09 Jul 2010 09:29:40 +0000</pubDate>
		<dc:creator>Alon Spiegel</dc:creator>
				<category><![CDATA[Administration]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server - Latest Articles]]></category>
		<category><![CDATA[Tips & Tricks]]></category>

		<guid isPermaLink="false">http://www.dbsnaps.com/?p=334</guid>
		<description><![CDATA[In this article we will demonstrate how to retrieve the startup time of SQL Server]]></description>
			<content:encoded><![CDATA[<p>Unfortunately, SQL Server does not provide an easy and simple query that answers this question. What we could do is use the fact that tempdb database is being created every time we start SQL Server and query the create time of this reincarnating temporary database. The table/columns we are interested is sysdatabase.crdate  The following statement demonstrates it. Just copy it and run it in SSMS.</p>
<p>(I have written it for SQL 2005 but I guess it runs both on 2000 and 2008 versions)</p>
<pre class="brush: sql;">

declare @startupDate datetime
,		@days bigint
,		@hours bigint
,		@minutes bigint
,		@seconds bigint

select	@startupDate = CrDate
,		@seconds = DateDiff(second, CrDate, getdate())
,		@days = @seconds/60/60/24
,		@seconds = @seconds - (@days*60*60*24)
,		@hours = @seconds/60/60
,		@seconds = @seconds - (@hours*60*60)
,		@minutes = @seconds/60
,		@seconds = @seconds - (@minutes*60)

from	sysdatabases (nolock)
where	[name] = 'TempDb'

select	@startupDate startup_time
,		cast(@days as varchar) + ' days ' +
		case when @hours &lt; 10 then '0' else '' end + cast(@hours as varchar) + ':' +
		case when @minutes &lt; 10 then '0' else '' end + cast(@minutes as varchar) + ':' +
		case when @seconds &lt; 10 then '0' else '' end + cast(@seconds as varchar)
		as online_duration		 
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.dbsnaps.com/sql-server/334/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Oracle &#8211; How to kill orphan sessions easily</title>
		<link>http://www.dbsnaps.com/oracle/oracle-how-to-kill-session-from-specific-application/</link>
		<comments>http://www.dbsnaps.com/oracle/oracle-how-to-kill-session-from-specific-application/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 20:14:12 +0000</pubDate>
		<dc:creator>Alon Spiegel</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Oracle - Latest Articles]]></category>
		<category><![CDATA[Tips & Tricks]]></category>

		<guid isPermaLink="false">http://www.dbsnaps.com/?p=291</guid>
		<description><![CDATA[In this article we'll see a script that will help developers to kill applicaitions orphan sessions, even on RAC environment.]]></description>
			<content:encoded><![CDATA[<p>Working with application developers, I am often asked to kill orphan sessions stuck in Oracle. These sessions sometime use a lot of resources or lock objects and rows. Developers usually work with unstable applications that crash a lot, or debuggers allowing the developer to stop the application process abruptly so they skip the commit/rollback part and even the disconnect part of the code. The client program is killed and does not report to Oracle server to cancel the statement and disconnect in a proper manner. This might produce an orphan process in the database. True, Oracle (PMON background process) will kill these orphan processes by itself, but it can take a while before they are identified and killed, and the developers could be facing locks or the database could be heavily loaded. When the development environment is relatively small, it is easy to identify the sessions that need to be killed. But in a large environment with numerous developers connected to the same database server with sometimes the same username, it is a little bit tricky. Moreover, a RAC environment makes this job of “killing sessions” more tedious. Addressing this time consuming repetitive task, I have created a very easy to use mechanism that will allow a developer to kill his/her own sessions without my help. My assumptions are:</p>
<ol>
<li>Developers are not granted the alter system / alter user privileges.</li>
<li>When creating users for developers the DBA can add a prefix to the name (DEV_USER1, DEV_JOHN, DEV_RACHEL …).</li>
<li>Developers do not share the same username.</li>
<li>Multiple developers can run from the same client using different usernames to login to Oracle.</li>
<li>A developer can run from multiple client machines – in this case he/she will want to kill sessions opened only from one specific client machine</li>
</ol>
<p>Tested on:</p>
<ol>
<li>Oracle 10g</li>
<li>Oracle 10g RAC</li>
<li>Oracle 11g</li>
<li>Oracle 11g RAC</li>
</ol>
<p>Now, I will display the setup code, followed by an explanation: Create owner for the procedure (schema)</p>
<pre class="brush: sql;">
create user killer identified by killer;
grant alter system to killer;
grant select on v_$session, gv_$session to killer;
alter user killer account lock;
</pre>
<p>Create the procedure</p>
<pre>
<div>
<pre class="brush: sql;">
create or replace PROCEDURE killer.KILL_MY_CLIENTS AUTHID DEFINER AS
   job_no number;
   user_prefix varchar(20);
   domain_name varchar(20);
   num_of_kills number := 0;
   BACKSLASH constant char(1) := chr(92);
begin
   user_prefix := 'DEV';       -- All my developer username prefixed with DEV
                               -- (DEV_USER1, DEV_USER2, DEV_MIKE, DEV_JOHN ...)
   domain_name := 'WORKGROUP'; -- We work in a workgroup.
                               -- Once we work in a windows domain this variable should
                               -- hold the domain name

   for REC in
       (SELECT SID, SERIAL#, INST_ID, MODULE,
               SYS_CONTEXT('USERENV', 'INSTANCE') MY_INST_ID
        from gv$session s
        where s.username like user_prefix || '%'                  -- precaution
          and s.username = sys_context('USERENV', 'SESSION_USER') -- only my username
          and not (S.SID = SYS_CONTEXT('USERENV', 'SID')          -- excluding my session
          and INST_ID = SYS_CONTEXT('USERENV', 'INSTANCE'))
          and replace(upper(machine), domain_name || BACKSLASH, '')     -- my machine
                 = replace(upper(sys_context('USERENV', 'HOST')), domain_name || BACKSLASH, '')
          and s.module not in ('SQL*Plus', 'SQL Developer')       -- not sqlplus
                                                                  -- nor sql developer
          and s.module not like 'sqlplus@%'
          and S.LOGON_TIME &lt; sysdate-(1/24/60/60)                 -- logged-on more
                                                                  -- than a second
        ORDER BY inst_id asc
       ) LOOP
      if rec.inst_id = rec.my_inst_id then
         ---------------------------------------------------------------------------
         -- kill local sessions immediately
         ---------------------------------------------------------------------------
         dbms_output.put('LOCAL SID ' || rec.sid || '(' || rec.module || ')');
         execute immediate 'alter system kill session ''' || rec.sid || ', ' ||
                            rec.serial# || '''' ;
         dbms_output.put_line('. killed locally ' || job_no);
      ELSE
         ---------------------------------------------------------------------------
         -- kill remote sessions (for RAC) as a job
         ---------------------------------------------------------------------------
         DBMS_OUTPUT.PUT('REMOTE SID ' || REC.SID || ' on instance ' || REC.INST_ID  ||
                         '(' || rec.module || ')');
         DBMS_JOB.SUBMIT (
                 job =&gt; job_no,
                 what =&gt; 'execute immediate ''alter system kill session ''''' || rec.sid ||', ' ||
                          rec.serial# || ''''''';',
                 INSTANCE =&gt; rec.inst_id);
         dbms_output.put_line('. killed with job ' || job_no);
         COMMIT;
      end if;
      num_of_kills := num_of_kills + 1;
   end loop;
   dbms_output.put_line ('number of killed sessions: ' || num_of_kills);
end kill_my_clients;
</pre>
</div>
</pre>
<p>Make procedure available to all</p>
<pre class="brush: sql;">
create public synonym kill_my_clients for killer.kill_my_clients;
grant execute on killer.kill_my_clients to public;
alter user killer account lock;
</pre>
<p>Use it: login as the developer from client machine to any application that can run statements like SQL*Plus</p>
<pre class="brush: sql;">
exec kill_my_clients
</pre>
<p>Explanation: The commands in the first section create a user called “killer”. This user is the owner of the procedure described in the next section. Notice that this user is very powerful because it can kill any user with the permission “alter system”. That is why we must limit access to it so it is locked. The grants on v_$session and gv_$session must be done by sys or other user with admin options on these views. The second section is the procedure itself. It should be compiled under “killer” (as the code demonstrates). Here is an explanation of this procedure:</p>
<ol>
<li>Identify all sessions running from the developer’s machine from his/hers username except for the session running this query in the current node and remote RAC nodes.
<ol>
<li>If the session is on the same instance of the current connection – kill it immediately.</li>
<li>If the session is on a different RAC node – kill it by submitting a job on that node.</li>
</ol>
<p>There are 2 variables that I usually change when I deploy this procedure in an environment:</p>
<ul>
<li><strong><em>USER_PREFIX</em></strong> – I try naming all the developer users with a prefix such as DEV_USER1, DEV_USER2, DEV_MIKE, DEV_JOHN &#8230; I use this prefix as a measure of precaution – I don’t want my procedure to kill any users not beginning with this prefix. This way if my developer is running this procedure from user sys or system by mistake it will do no harm.</li>
<li><em><strong>DOMAIN_NAME</strong></em> – when working with windows clients sometimes the application is prefixed with the domain name (such as SQL Developer) and sometimes not (such as SQL*Plus). This variable will become crucial to identifying sessions opened from the developer’s machine.</li>
</ul>
</li>
<li>Execute kill command on the local instance.</li>
<li>Execute kill command on all remote instances of RAC by submitting jobs with instance affinity.</li>
</ol>
<ol></ol>
<p>Another factor I take into account is that I don’t want to kill connections from SQL*Plus or from SQL Developer. If you are working with other programs such as PL/SQL Developer or Toad you might want to include them in the where clause as well.</p>
<p>The third section demonstrates how to use this mechanism: You just have to login as the developer from the client machine to any application that can run statements like SQL*Plus and execute the procedure (you do not have to use the owner’s name in the call because you have declared a public synonym for it).</p>
<p>Enjoy ﻿</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbsnaps.com/oracle/oracle-how-to-kill-session-from-specific-application/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Creating Multiple AWR reports</title>
		<link>http://www.dbsnaps.com/oracle/automatic-awr-reports/</link>
		<comments>http://www.dbsnaps.com/oracle/automatic-awr-reports/#comments</comments>
		<pubDate>Tue, 22 Jun 2010 08:29:27 +0000</pubDate>
		<dc:creator>Roni Vered</dc:creator>
				<category><![CDATA[Administration]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Oracle - Latest Articles]]></category>
		<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[Automatic Workload Repository]]></category>
		<category><![CDATA[AWR]]></category>

		<guid isPermaLink="false">http://www.dbsnaps.com/?p=265</guid>
		<description><![CDATA[Analyzing AWR (Automated Workload Repository) is a common operation while doing a performance and tuning sessions on a database instance.]]></description>
			<content:encoded><![CDATA[<p>Analyzing AWR (Automated Workload Repository) is a common operation while doing a performance and tuning sessions on a database instance.</p>
<p>If your database contains the Oracle Database Diagnostic Pack, then by default, the database generates an AWR snapshot in an hourly interval (it of course can be changed by using the DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS procedure).</p>
<p>Once taken, each two snapshots can be compared in an AWR report and greatly assist in the performance and tuning job.</p>
<p>There’re several methods of generating these AWR report, however, most of the methods are manual methods &#8211; creating one report at the time.</p>
<p>The following procedure will create <strong>several</strong> AWR reports in HTML format in a given directory, based on a begin/end snapshot id parameters.</p>
<p><strong>Procedure’s Parameters:</strong></p>
<ul>
<li><strong>Begin_snap</strong> – the first AWR snapshot to be compared.</li>
<li><strong>End_snap</strong> – the last AWR snapshot to be compared.</li>
<li><strong>Directory</strong> – the directory in which it will generate the reports</li>
</ul>
<p>The required begin/end snapshot values can be retrieved from the following query on DBA_HIST_SNAPSHOT:</p>
<div>
<pre>
<div>
<pre class="brush: sql;">

SELECT     	SNAP_ID,
                TO_CHAR(BEGIN_INTERVAL_TIME,'DD/MM/YYYY HH24:MI') ,
                TO_CHAR(END_INTERVAL_TIME,'DD/MM/YYYY HH24:MI')&lt;/pre&gt;
FROM DBA_HIST_SNAPSHOT 
--The following WHERE clause can be used in order to limit the snapshot details.
--WHERE TO_CHAR(BEGIN_INTERVAL_TIME,'DD/MM/YYYY') &gt; TO_CHAR(SYSDATE -2,'DD/MM/YYYY'); 
</pre>
</div>
</pre>
</div>
<p>Once Created, the procedure can be executed as the following example:</p>
<p><em>EXEC CreateAwrReports (465, 475, &#8216;C:\TEMP&#8217;);</em></p>
<p>Below is the procedure&#8217;s script:</p>
<pre class="brush: sql;">
CREATE OR REPLACE PROCEDURE CreateAwrReports (begin_snap number,end_snap number, directory varchar2 )
as
/*---------------------------------------------------------------------------
 Name: CreateAwrReports Procedure
 Purpose : 	Create several AWR reported based on begin_snap and end_snap input parameters.
			The AWR reports will be created in the directory input parameter.
 Date    : 06.21.2010.
 Author  : Roni Vered
 Website : WWW.DBSNAPS.COM
 Execution :	exec CreateAwrReports (462, 472, 'c:\temp');

 Remarks : Run as privileged user
 --------------------------------------------------------------------------- */
	v_Instance_number v$instance.instance_number%TYPE;
	v_Instance_name v$instance.instance_name%TYPE;
	v_dbid V$database.dbid%TYPE;
	v_file UTL_FILE.file_type;

BEGIN

/* Collecting instance information: Instance_number, Instance_name and Dbid */
	SELECT instance_number, instance_name
	into v_Instance_number,v_Instance_name
	FROM   gv$instance
	ORDER BY 1;

	SELECT dbid
	INTO v_dbid
	FROM v$database;

/* Creating a database directory which will point to the acual wanted report directory in the OS */
	EXECUTE IMMEDIATE('CREATE OR REPLACE DIRECTORY TEMP_DIR AS '''||directory||'''');

/*
	Looping on all the snapshots from the begin_snap input parameter to the end_snap input parameter
	On each snapshot pair we will create a file in the given directory which will contain the AWR report.
	We use DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_HTML build in procedure to create the HTML report.
*/
  FOR i IN begin_snap..end_snap-1 LOOP
		BEGIN
			--Creating and Naming the file:
			v_file := UTL_FILE.fopen('TEMP_DIR', 'awr_' || v_Instance_name ||'_'|| v_Instance_number || '_' || i || '_' || (i+1) || '.html', 'w', 32767);
			FOR c_AWRReport IN (
				SELECT output FROM TABLE (DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_HTML( v_dbid, v_Instance_number,  i, i+1))
					   ) LOOP
						--Writing the AWR HTML report content to the file:
						UTL_FILE.PUT_LINE(v_file, c_AWRReport.output);
					   END LOOP;
			--Closing the file:
			UTL_FILE.fclose(v_file);
		END;
	END LOOP;

/* Dropping the database directory which we've created earlier. */
	EXECUTE IMMEDIATE('DROP DIRECTORY TEMP_DIR');

END;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.dbsnaps.com/oracle/automatic-awr-reports/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Oracle Associative Arrays</title>
		<link>http://www.dbsnaps.com/oracle/oracle-associative-arrays/</link>
		<comments>http://www.dbsnaps.com/oracle/oracle-associative-arrays/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 11:44:43 +0000</pubDate>
		<dc:creator>Liron Amitzi</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Oracle - Latest Articles]]></category>
		<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[Associative]]></category>
		<category><![CDATA[index by]]></category>

		<guid isPermaLink="false">http://www.dbsnaps.com/?p=241</guid>
		<description><![CDATA[Working with arrays in PL/SQL is not very complicated, this is a sequence of cells we can access by their index.

Sometimes, all we need is to get a value from an index we have, and this index is not a sequence number, but a number that has meaning or even text.]]></description>
			<content:encoded><![CDATA[<p>Working with arrays in PL/SQL is not very complicated, this is a sequence of cells we can access by their index.</p>
<p>Sometimes, all we need is to get a value from an index we have, and this index is not a sequence number, but a number that has meaning or even text. To solve this problem we can use a regular table or temporary table, but these have some overhead and can be affected by other users or operations.</p>
<p>A simple example for this scenario can be coloring the world map in 4 colors (red, green, blue and yellow). In this example each country has a color and we need to know the color for a given country and go over the countries to check if they have a color.</p>
<p>The most effective way to do that is to use associative arrays with varchar2(30) as the index (for the country names) and varchar2(6) and the value (for the colors).</p>
<p>The following code shows how to work with associative arrays, add new cells, check the array length and go over the entire array.</p>
<pre>
<div>
<pre class="brush: sql;">
&lt;pre&gt;declare
   type map_array is table of varchar2(4) index by varchar2(30);
   map map_array;
   idx varchar2(30);
begin
   -- add countries to the array
   map('France'):='blue';
   map('Italy'):='red';

   -- print the number of countries in the arrary
   dbms_output.put_line('There are '||map.count||' countries');

   -- go over the entire array
   idx:=map.first;
   while (idx is not null)
   loop
      dbms_output.put_line('Country '||idx||' is '||map(idx));
      idx:=map.next(idx);
   end loop;

   -- check if a country exists
   idx:='England';
   if (map.exists(idx))
   then
      dbms_output.put_line(idx||' has the color '||map(idx));
   else
      dbms_output.put_line(idx||' does not have a color');
   end if;
end;
</pre>
</div>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.dbsnaps.com/oracle/oracle-associative-arrays/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
