<?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>Vincent Prouillet</title>
	<atom:link href="http://www.mademyday.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mademyday.net</link>
	<description>Hey, it made my day !</description>
	<lastBuildDate>Sat, 08 Oct 2011 22:14:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Windows 8 Preview</title>
		<link>http://www.mademyday.net/2011/09/14/windows-8-preview/</link>
		<comments>http://www.mademyday.net/2011/09/14/windows-8-preview/#comments</comments>
		<pubDate>Wed, 14 Sep 2011 04:22:20 +0000</pubDate>
		<dc:creator>Vincent Prouillet</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[preview]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[windows 8]]></category>

		<guid isPermaLink="false">http://www.mademyday.net/?p=223</guid>
		<description><![CDATA[Windows 8 was presented at the BUILD conference and a preview was available for download. You can find the iso (with or without tools) here : . I couldn&#8217;t get it to work in VMWare but it works well in VirtualBox. There are several new things : - Integration with Windows Live (you can put [...]]]></description>
			<content:encoded><![CDATA[<p>Windows 8 was presented at the BUILD conference and a preview was available for download.<br />
You can find the iso (with or without tools) here : <a href="http://msdn.microsoft.com/en-us/windows/home/" title="http://msdn.microsoft.com/en-us/windows/home/"></a>.<br />
I couldn&#8217;t get it to work in VMWare but it works well in VirtualBox.</p>
<p>There are several new things :<br />
- Integration with Windows Live (you can put your Live mail and it will connect)<br />
<a href="http://www.mademyday.net/wp-content/uploads/2011/09/live_integrations1.png"><img src="http://www.mademyday.net/wp-content/uploads/2011/09/live_integrations1-150x150.png" alt="" title="live_integrations" width="150" height="150" class="aligncenter size-thumbnail wp-image-230" /></a></p>
<p>- Metro interface (my WLM picture appeared a bit later)<br />
<a href="http://www.mademyday.net/wp-content/uploads/2011/09/metro1.png"><img src="http://www.mademyday.net/wp-content/uploads/2011/09/metro1-150x150.png" alt="" title="metro" width="150" height="150" class="aligncenter size-thumbnail wp-image-231" /></a></p>
<p>- Ribbons in explorer (you can go to the usual interface using the Desktop button or Windows Explorer button on the previous screen)<br />
<a href="http://www.mademyday.net/wp-content/uploads/2011/09/explorer1.png"><img src="http://www.mademyday.net/wp-content/uploads/2011/09/explorer1-150x150.png" alt="" title="explorer" width="150" height="150" class="aligncenter size-thumbnail wp-image-233" /></a></p>
<p>- A neat task manager (you can go back to the metro interface with the windows button in the bottom left)<br />
<a href="http://www.mademyday.net/wp-content/uploads/2011/09/task11.png"><img src="http://www.mademyday.net/wp-content/uploads/2011/09/task11-150x150.png" alt="" title="task1" width="150" height="150" class="aligncenter size-thumbnail wp-image-232" /></a><br />
<a href="http://www.mademyday.net/wp-content/uploads/2011/09/task21.png"><img src="http://www.mademyday.net/wp-content/uploads/2011/09/task21-150x150.png" alt="" title="task2" width="150" height="150" class="aligncenter size-thumbnail wp-image-234" /></a></p>
<p>- IE 10<br />
<a href="http://www.mademyday.net/wp-content/uploads/2011/09/ie1.png"><img src="http://www.mademyday.net/wp-content/uploads/2011/09/ie1-150x150.png" alt="" title="ie" width="150" height="150" class="aligncenter size-thumbnail wp-image-237" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mademyday.net/2011/09/14/windows-8-preview/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Get capacity metrics for SQL Server and Oracle</title>
		<link>http://www.mademyday.net/2011/09/06/216/</link>
		<comments>http://www.mademyday.net/2011/09/06/216/#comments</comments>
		<pubDate>Tue, 06 Sep 2011 18:04:02 +0000</pubDate>
		<dc:creator>Vincent Prouillet</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[capacity]]></category>
		<category><![CDATA[sql server]]></category>

		<guid isPermaLink="false">http://www.mademyday.net/?p=216</guid>
		<description><![CDATA[Second round of the capacity metrics SQL Server Size of database : Size of all the tables > 10mo : Current users Current queries Oracle Size of the instance Size of the tablespaces Size of the schemas (only the one above 10MB) Size of the tables (only the one above 10MB) Current users and queries]]></description>
			<content:encoded><![CDATA[<p>Second round of the capacity metrics</p>
<h2>SQL Server</h2>
<p>Size of database :</p>
<pre class="brush: sql; title: ; notranslate">
EXEC sp_spaceused
</pre>
<p>Size of all the tables > 10mo :</p>
<pre class="brush: sql; title: ; notranslate">
--Removes the procedure if it already exists
IF OBJECT_ID('dbo.GetSizeOfAllTables') IS NOT NULL
DROP PROCEDURE dbo.GetSizeOfAllTables
GO
--Gets the number of rows and size in MB of every table in the current database
CREATE PROCEDURE GetSizeOfAllTables
AS
DECLARE @TableName VARCHAR(100)

--Cursor storing all the user tables names
DECLARE tableCursor CURSOR
FOR
SELECT [name]
FROM dbo.sysobjects
WHERE  OBJECTPROPERTY(id, N'IsUserTable') = 1
FOR READ ONLY

--We create a temp table to hold the result of sp_spaceused
CREATE TABLE #TempTable
(
    tableName varchar(100),
    numberOfRows varchar(100),
    reservedSize varchar(50),
    dataSize varchar(50),
    indexSize varchar(50),
    unusedSize varchar(50)
)

OPEN tableCursor
--Get the first table name from the cursor
FETCH NEXT FROM tableCursor INTO @TableName
WHILE (@@Fetch_Status &gt;= 0)
BEGIN
    --Dump the results of the sp_spaceused query to the temp table
    INSERT  #TempTable
        EXEC sp_spaceused @TableName

    FETCH NEXT FROM tableCursor INTO @TableName
END
CLOSE tableCursor
DEALLOCATE tableCursor

--Select all records and compute the data we want
SELECT * FROM
    (SELECT tableName, RTRIM(numberOfRows) as 'rows', ROUND((CONVERT(FLOAT, SUBSTRING(dataSize, 1, LEN(dataSize)-3)) + CONVERT(FLOAT, SUBSTRING(indexSize, 1, LEN(indexSize)-3)))/1024, 3) as 'Size'
    FROM #TempTable) T
WHERE Size &gt; 10

--Clean up behind us
DROP TABLE #TempTable
GO
EXEC GetSizeOfAllTables
</pre>
<p>Current users</p>
<pre class="brush: sql; title: ; notranslate">
--Create a table to hold the data from sp_who
CREATE TABLE #temp
(
    spid varchar(100),
    ecid varchar(100),
    statuts varchar(100),
    loginame varchar(100),
    hostname varchar(50),
    blk varchar(50),
    dbname varchar(50),
    cmd varchar(50),
    requestID varchar(50),
);

INSERT INTO #temp EXEC sp_who

--Get the data we want
SELECT COUNT(*) AS cnt, loginame FROM #temp WHERE dbname = 'OnlyForTest' GROUP BY loginame ORDER BY cnt DESC;

--Clean up
DROP TABLE #temp
</pre>
<p>Current queries</p>
<pre class="brush: sql; title: ; notranslate">
SELECT COUNT(*) AS cnt, text FROM sys.dm_exec_requests
CROSS APPLY sys.dm_exec_sql_text(sql_handle) WHERE status='running' GROUP BY text ORDER BY cnt DESC;
</pre>
<h2>Oracle</h2>
<p>Size of the instance</p>
<pre class="brush: sql; title: ; notranslate">
SELECT sys_context('USERENV','DB_NAME'), SUM(bytes)/1024/1024 &quot;Mb&quot; FROM dba_data_files
</pre>
<p>Size of the tablespaces</p>
<pre class="brush: sql; title: ; notranslate">
SELECT b.tablespace_name, tbs_size SizeMB, a.free_space FreeMB
FROM  (SELECT tablespace_name, round(SUM(bytes)/1024/1024 ,2) AS free_space
FROM dba_free_space
GROUP BY tablespace_name) a,
(SELECT tablespace_name, SUM(bytes)/1024/1024 AS tbs_size
FROM dba_data_files
GROUP BY tablespace_name) b
WHERE a.tablespace_name(+)=b.tablespace_name
</pre>
<p>Size of the schemas (only the one above 10MB)</p>
<pre class="brush: sql; title: ; notranslate">
SELECT owner, (SUM(bytes)/1024/1024)
FROM dba_segments WHERE owner NOT IN ('SYS')
GROUP BY owner HAVING (SUM(bytes)/1024/1024) &gt; 10
</pre>
<p>Size of the tables (only the one above 10MB)</p>
<pre class="brush: sql; title: ; notranslate">
SELECT owner, table_name, TRUNC(sum(bytes)/1024/1024) Meg
FROM
    (SELECT segment_name table_name, owner, bytes
    FROM dba_segments
    WHERE segment_type = 'TABLE'
    UNION ALL
    SELECT i.table_name, i.owner, s.bytes
    FROM dba_indexes i, dba_segments s
    WHERE s.segment_name = i.index_name
    AND   s.owner = i.owner
    AND   s.owner = i.owner
    AND   s.segment_type = 'INDEX'
    UNION ALL
    SELECT l.table_name, l.owner, s.bytes
    FROM dba_lobs l, dba_segments s
    WHERE s.segment_name = l.segment_name
    AND   s.owner = l.owner
    AND   s.segment_type = 'LOBSEGMENT'
    UNION ALL
    SELECT l.table_name, l.owner, s.bytes
    FROM dba_lobs l, dba_segments s
    WHERE s.segment_name = l.index_name
    AND   s.owner = l.owner
    AND   s.segment_type = 'LOBINDEX')
WHERE owner NOT IN ('SYS')
GROUP BY table_name, owner
HAVING SUM(bytes)/1024/1024 &gt; 10
ORDER BY SUM(bytes) desc
</pre>
<p>Current users and queries</p>
<pre class="brush: sql; title: ; notranslate">
SELECT COUNT(*) AS cnt, a.username, b.sql_text
FROM v$session a, v$sqlarea b
WHERE sql_address=b.address
GROUP BY a.username, b.sql_text
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mademyday.net/2011/09/06/216/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Install ibm_db on Ubuntu</title>
		<link>http://www.mademyday.net/2011/08/24/install-ibm_db-on-ubuntu/</link>
		<comments>http://www.mademyday.net/2011/08/24/install-ibm_db-on-ubuntu/#comments</comments>
		<pubDate>Wed, 24 Aug 2011 13:31:14 +0000</pubDate>
		<dc:creator>Vincent Prouillet</dc:creator>
				<category><![CDATA[DB2]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[db2]]></category>
		<category><![CDATA[driver]]></category>
		<category><![CDATA[ibm_db]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[remote]]></category>

		<guid isPermaLink="false">http://www.mademyday.net/?p=200</guid>
		<description><![CDATA[Ok so this one was a bit tricky. I needed to access remote DB2 databases using Python. I found ibm_db (page here) and followed the instructions. First you need to set up DB2 drivers : you can get it here (Data Server Driver Package, NOT the ODBC) or here here (I used this one). You [...]]]></description>
			<content:encoded><![CDATA[<p>Ok so this one was a bit tricky.<br />
I needed to access remote DB2 databases using Python.<br />
I found ibm_db (<a title="http://code.google.com/p/ibm-db/" href="http://code.google.com/p/ibm-db/">page here</a>) and followed the instructions.</p>
<p>First you need to set up DB2 drivers : you can get it <a title="https://www-304.ibm.com/support/docview.wss?uid=swg27016878" href="https://www-304.ibm.com/support/docview.wss?uid=swg27016878">here (Data Server Driver Package, NOT the ODBC)</a> or here <a title="https://www14.software.ibm.com/webapp/iwm/web/reg/download.do?source=swg-informixfpd&amp;lang=en_US&amp;S_PKG=dl&amp;cp=UTF-8" href="https://www14.software.ibm.com/webapp/iwm/web/reg/download.do?source=swg-informixfpd&amp;lang=en_US&amp;S_PKG=dl&amp;cp=UTF-8">here (I used this one)</a>. You will need to create an account for both.<br />
You can then untar the archive, select the good folder (odbc_cli_driver/linuxia32) and untar the archive present there, for example in /home/vincent/db2driver .</p>
<p>If you try to build and install ibm_db right now it will tell you to set up the DB2 environment so let&#8217;s do it.</p>
<pre class="brush: bash; title: ; notranslate">
vincent@ubuntu:~$ export IBM_DB_LIB=/home/vincent/db2driver/lib
vincent@ubuntu:~$ export IBM_DB_DIR=/home/vincent/db2driver
</pre>
<p>You should now be install to build install ibm_db :</p>
<pre class="brush: bash; title: ; notranslate">
vincent@ubuntu:~$ cd /home/Downloads/ibm_db/
vincent@ubuntu:~/home/Downloads/ibm_db/$ python setup.py build
vincent@ubuntu:~/home/Downloads/ibm_db/$ python setup.py install
</pre>
<p>Try to import it in python and you should get the following error :</p>
<pre class="brush: bash; title: ; notranslate">
vincent@ubuntu:/home/vincent/Downloads/ibm_db-1.0.4# python
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24)
[GCC 4.5.2] on linux2
Type &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.
&gt;&gt;&gt; import ibm_db
Traceback (most recent call last):
  File &quot;&quot;, line 1, in
ImportError: libdb2.so.1: cannot open shared object file: No such file or directory
</pre>
<p>Huuum still not working&#8230;after a little googling I found how to resolve it in this <a title="http://code.google.com/p/ibm-db/issues/detail?id=53" href="http://code.google.com/p/ibm-db/issues/detail?id=53">issue </a>.</p>
<p>You have to do the following :</p>
<pre class="brush: bash; title: ; notranslate">
vincent@ubuntu:~/Downloads/ibm_db-1.0.4$ sudo nano /etc/ld.so.conf.d/db2.conf
[sudo] password for vincent:
vincent@ubuntu:~/Downloads/ibm_db-1.0.4$ sudo ldconfig
vincent@ubuntu:~/Downloads/ibm_db-1.0.4$ python
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24)
[GCC 4.5.2] on linux2
Type &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.
&gt;&gt;&gt; import ibm_db
Traceback (most recent call last):
  File &quot;&quot;, line 1, in
ImportError: libstdc++.so.5: cannot open shared object file: No such file or directory
</pre>
<p>Install the libstdc++5 package and voila!</p>
<pre class="brush: bash; title: ; notranslate">
vincent@ubuntu:~/Downloads/ibm_db-1.0.4$ sudo apt-get install libstdc++5
....
incent@ubuntu:~/Downloads/ibm_db-1.0.4$ python
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24)
[GCC 4.5.2] on linux2
Type &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.
&gt;&gt;&gt; import ibm_db
&gt;&gt;&gt;
</pre>
<p>It should work now !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mademyday.net/2011/08/24/install-ibm_db-on-ubuntu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get capacity metrics for MySQL and PostgreSQL</title>
		<link>http://www.mademyday.net/2011/08/18/get-capacity-metrics-for-mysql-and-postgresql/</link>
		<comments>http://www.mademyday.net/2011/08/18/get-capacity-metrics-for-mysql-and-postgresql/#comments</comments>
		<pubDate>Fri, 19 Aug 2011 03:23:44 +0000</pubDate>
		<dc:creator>Vincent Prouillet</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PosgreSQL]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[capacity]]></category>
		<category><![CDATA[metrics]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[postgres]]></category>

		<guid isPermaLink="false">http://www.mademyday.net/?p=192</guid>
		<description><![CDATA[Getting capacity metrics for these two dabatases is suprisingly easily. We will get the size of database(s), current users connected and current queries made (and also the size for each tablespace for PostgreSQL). MySQL Size of database : Size of all the tables : Current users and queries If you have the slow query (doc [...]]]></description>
			<content:encoded><![CDATA[<p>Getting capacity metrics for these two dabatases is suprisingly easily. We will get the size of database(s), current users connected and current queries made (and also the size for each tablespace for PostgreSQL).</p>
<h2>MySQL</h2>
<p>Size of database :</p>
<pre class="brush: sql; title: ; notranslate">
SELECT LOCALTIMESTAMP, table_schema AS 'Name', ROUND( SUM( data_length + index_length ) /1024 /1024, 3 ) AS 'Size (MB)'
FROM information_schema.tables
WHERE table_schema = 'name_of_our_database'
GROUP BY table_schema
</pre>
<p>Size of all the tables :</p>
<pre class="brush: sql; title: ; notranslate">
SELECT LOCALTIMESTAMP, table_name, table_rows,
ROUND(data_length/1024/1024,2) + ROUND(index_length/1024/1024,2) FROM information_schema.tables
WHERE table_schema NOT IN ('information_schema','mysql')
</pre>
<p>Current users and queries</p>
<pre class="brush: sql; title: ; notranslate">
SELECT LOCALTIMESTAMP, COUNT(*) AS cnt, user, host, info
FROM INFORMATION_SCHEMA.PROCESSLIST GROUP BY user, info ORDER BY cnt DESC;
</pre>
<p>If you have the slow query (<a href="http://dev.mysql.com/doc/refman/5.0/en/slow-query-log.html" title="http://dev.mysql.com/doc/refman/5.0/en/slow-query-log.html">doc here</a>) activated, it&#8217;s really worth getting the data from it.</p>
<h2>PostgreSQL</h2>
<p>Size of all the databases from the instance (we don&#8217;t use pg_size_pretty because we want all our reports to use the same unit and we exclude the basic databases)</p>
<pre class="brush: sql; title: ; notranslate">
SELECT localtimestamp, pg_database.datname, (pg_database_size(pg_database.datname)::float/1024/1024)::numeric(8,3)
FROM pg_database WHERE datname NOT IN ('template0','template1','postgres')
</pre>
<p>Size of the tablespaces (same thing as before)</p>
<pre class="brush: sql; title: ; notranslate">
SELECT localtimestamp, spcname, (pg_tablespace_size(oid)::float/1024/1024)::numeric(8,3)
FROM pg_tablespace WHERE spcname != 'pg_global';
</pre>
<p>Size of the tables (only the one above 10MB)</p>
<pre class="brush: sql; title: ; notranslate">
SELECT * FROM (
    SELECT localtimestamp, nspname || '.' || relname AS &quot;table&quot;, reltuples,
    (pg_total_relation_size(C.oid)::float/1024/1024)::numeric(8,3) AS &quot;size&quot;
    FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
    WHERE nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast') AND C.relkind &lt;&gt; 'i') T
WHERE size &gt; 10
</pre>
<p>Current users and queries</p>
<pre class="brush: sql; title: ; notranslate">
SELECT localtimestamp, COUNT(*) AS cnt, usename, current_query
FROM pg_stat_activity GROUP BY usename,current_query ORDER BY cnt DESC;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mademyday.net/2011/08/18/get-capacity-metrics-for-mysql-and-postgresql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Install Oracle on CentOS 6</title>
		<link>http://www.mademyday.net/2011/08/10/install-oracle-on-centos-6/</link>
		<comments>http://www.mademyday.net/2011/08/10/install-oracle-on-centos-6/#comments</comments>
		<pubDate>Wed, 10 Aug 2011 21:52:43 +0000</pubDate>
		<dc:creator>Vincent Prouillet</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[centos]]></category>
		<category><![CDATA[installation]]></category>

		<guid isPermaLink="false">http://www.mademyday.net/?p=166</guid>
		<description><![CDATA[I followed the quick installation guide Oracle provides so that&#8217;s more like an even quicker installation guide. To start, we need to install the necessary packages : [root@oracletest database]# yum install binutils compat-libstdc++* elfutils* gcc gcc-c++ glibc* compat-glibc* ksh libaio* libstdc++* make sysstat unixODBC unixODBC-devel We now need to create the users and groups : [...]]]></description>
			<content:encoded><![CDATA[<p>I followed the quick installation guide Oracle provides so that&#8217;s more like an even quicker installation guide.</p>
<p>To start, we need to install the necessary packages :<br />
<code><br />
[root@oracletest database]# yum install binutils compat-libstdc++* elfutils* gcc gcc-c++ glibc* compat-glibc* ksh libaio* libstdc++* make sysstat unixODBC unixODBC-devel<br />
</code></p>
<p>We now need to create the users and groups :<br />
<code><br />
[root@oracletest database]# groupadd oinstall<br />
[root@oracletest database]# groupadd dba<br />
[root@oracletest database]# useradd -g oinstall -G dba oracle<br />
[root@oracletest database]# passwd oracle<br />
</code></p>
<p>Tune the kernel a bit :<br />
<code><br />
[root@oracletest database]# nano /etc/sysctl.conf<br />
//Then add these lines at the end of the file<br />
kernel.shmall = 2097152<br />
kernel.shmmax = 2147483648<br />
kernel.shmmni = 4096<br />
kernel.sem = 250 32000 100 128<br />
fs.file-max = 6815744<br />
fs.aio-max-nr = 1048576<br />
net.ipv4.ip_local_port_range = 9000 65500<br />
net.core.rmem_default = 4194304<br />
net.core.rmem_max = 4194304<br />
net.core.wmem_default = 262144<br />
net.core.wmem_max = 1048576<br />
//And validates it<br />
[root@oracletest database]# /sbin/sysctl -p<br />
</code></p>
<p>Change the shell limits :<br />
<code><br />
[root@oracletest database]# nano /etc/security/limits.conf<br />
//Then add these lines at the end of the file<br />
oracle           soft    nproc   2047<br />
oracle           hard    nproc   16384<br />
oracle           soft    nofile  1024<br />
oracle           hard    nofile  65536</p>
<p>[root@oracletest database]# nano /etc/pam.d/login<br />
//Then add this line at the end of the file<br />
session required pam_limits.so<br />
</code></p>
<p>Modify the bash profile :<br />
<code><br />
[root@oracletest ~]# nano /home/oracle/.bash_profile<br />
//Then add these lines at the end of the file<br />
ulimit -u 16384 -n 65536<br />
umask 022<br />
ORACLE_BASE=/u01/app; export ORACLE_BASE<br />
ORACLE_SID=orcl; export ORACLE_SID<br />
ORACLE_HOME=$ORACLE_BASE/product/11.2.0/db1 #depends on your directory<br />
PATH=$ORACLE_HOME/bin:$PATH; export PATH<br />
</code></p>
<p>Create the directories :<br />
<code><br />
[root@oracletest database]# mkdir -p /u01/app/<br />
[root@oracletest database]# chown -R oracle.oinstall /u01<br />
</code></p>
<p>And for the X (you might have to open a new console for that to work):<br />
<code><br />
[root@oracletest vincent]# xhost +<br />
</code></p>
<p>You can now su &#8211; oracle, run the ./runInstaller script and follows what the installer says (a couple of scripts to run at the end).<br />
It might tell that you don&#8217;t have the necessary packages, but it somehow doesn&#8217;t recognize higher versions or 64bits versions of these one so you can safely continue.<br />
You can now access EM on https://hostname:1518/em .</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mademyday.net/2011/08/10/install-oracle-on-centos-6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Install CentOS 6 using the remote Net Install</title>
		<link>http://www.mademyday.net/2011/08/06/install-centos-6-using-the-remote-net-install/</link>
		<comments>http://www.mademyday.net/2011/08/06/install-centos-6-using-the-remote-net-install/#comments</comments>
		<pubDate>Sat, 06 Aug 2011 16:53:45 +0000</pubDate>
		<dc:creator>Vincent Prouillet</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[centos]]></category>
		<category><![CDATA[installation]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://www.mademyday.net/?p=158</guid>
		<description><![CDATA[Instead of downloading the 4.x go for the DVD iso, you could download the Net Install (about 216mo) and let it retrieves what it needs to install. You can download the iso there http://www.centos.org/modules/tinycontent/index.php?id=30 in the 6 or 6.0 directory. Once you load it on your server or VM, you will have to choose the [...]]]></description>
			<content:encoded><![CDATA[<p>Instead of downloading the 4.x go for the DVD iso, you could download the Net Install (about 216mo) and let it retrieves what it needs to install.</p>
<p>You can download the iso there <a href="http://www.centos.org/modules/tinycontent/index.php?id=30" title="http://www.centos.org/modules/tinycontent/index.php?id=30">http://www.centos.org/modules/tinycontent/index.php?id=30</a> in the 6 or 6.0 directory.</p>
<p>Once you load it on your server or VM, you will have to choose the media from which to install CentOS.<br />
Choose URL and you now have 2 options : use one of your image in your network or use a CentOS mirror.</p>
<p>The CentOS mirrors URL are the following (choose the one according to your architecture) :<br />
<code></p>
<p>http://mirror.centos.org/centos/6/os/i386/</p>
<p>http://mirror.centos.org/centos/6/os/x86_64/</p>
<p></code></p>
<p>It will now retrieve the image and start the installation with the GUI.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mademyday.net/2011/08/06/install-centos-6-using-the-remote-net-install/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cleaning Postgres WAL archive directory</title>
		<link>http://www.mademyday.net/2011/08/04/cleaning-postgres-wal-archive-directory/</link>
		<comments>http://www.mademyday.net/2011/08/04/cleaning-postgres-wal-archive-directory/#comments</comments>
		<pubDate>Thu, 04 Aug 2011 21:58:09 +0000</pubDate>
		<dc:creator>Vincent Prouillet</dc:creator>
				<category><![CDATA[PosgreSQL]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[clean]]></category>
		<category><![CDATA[ksh]]></category>
		<category><![CDATA[logs]]></category>
		<category><![CDATA[postgres]]></category>
		<category><![CDATA[sh]]></category>
		<category><![CDATA[WAL]]></category>

		<guid isPermaLink="false">http://www.mademyday.net/?p=142</guid>
		<description><![CDATA[A little script allowing to clean old WAL files for PostgreSQL]]></description>
			<content:encoded><![CDATA[<p>The disk containing the WAL (Write-Ahead Logging explained here : <a href="http://www.postgresql.org/docs/8.0/static/wal.html" title="http://www.postgresql.org/docs/8.0/static/wal.html">http://www.postgresql.org/docs/8.0/static/wal.html</a>) at work was getting close to 90% since we didn&#8217;t have any kind of deleting obsolete WAL files.<br />
A WAL directory is filled with files with names like <em>000000010000000000000034</em> but a few looks like <em>000000010000000000000065.007C9330.backup</em>.<br />
The ones with the backup extension indicate a new backup and the starting WAL file would be <em>000000010000000000000065</em> in this example (the second part of the filename can be ignored).<br />
We can then safely delete the files older than this one.</p>
<p>I found after having spent some time on the script that pg_archivecleanup (<a href="http://developer.postgresql.org/pgdocs/postgres/pgarchivecleanup.html" title="http://developer.postgresql.org/pgdocs/postgres/pgarchivecleanup.html">http://developer.postgresql.org/pgdocs/postgres/pgarchivecleanup.html</a>) existed, but our server is running PostgreSQL 8.3 and I had some library problems when compiling it as a standalone so I just finished my ksh script.<br />
I delete all the files older than the most recent starting WAL file and log every deletion with the timestamp of file creation.</p>
<pre class="brush: bash; title: ; notranslate">
#!/bin/ksh

archive_directory=/home/vincent/postgres/archive #put your own directory obviously
backup_labels=$archive_directory/*.backup
files=$archive_directory/*
log_path=/home/vincent/logs/clean.log #a made-up directory, you get the idea

if [ ! -f $log_path ];then
	touch $log_path
	echo -e &quot;Cleaning of WAL archives log\n\n&quot; &gt;&gt; $log_path
fi

#Gets the last backup label created
latest_file_path=`ls -tr $backup_labels | tail -1`
#Gets the name of the start file
start_wal=$(echo `basename $latest_file_path` | cut -d'.' -f1)

current_time=`date +&quot;%Y-%m-%d %H:%M&quot;` 

echo -e &quot;\nCleaning started at : ${current_time}&quot; &gt;&gt; $log_path
echo -e &quot;\tKeep WAL file ${start_wal} and later\n&quot; &gt;&gt; $log_path

for file in $files
do
	if [ $file -ot $latest_file_path ]; then
		time=`ls -l $file | awk '{ print $6, $7 }'`
		rm $file
		echo &quot;Removing file ${file} (created at ${time})&quot; &gt;&gt; $log_path
	fi
done

echo -e &quot;\n--------------------------------------------------&quot; &gt;&gt; $log_path
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mademyday.net/2011/08/04/cleaning-postgres-wal-archive-directory/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Load various excel files into MySQL</title>
		<link>http://www.mademyday.net/2011/08/01/load-various-excel-files-into-mysql-2/</link>
		<comments>http://www.mademyday.net/2011/08/01/load-various-excel-files-into-mysql-2/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 20:36:28 +0000</pubDate>
		<dc:creator>Vincent Prouillet</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[load]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.mademyday.net/?p=124</guid>
		<description><![CDATA[I recently had to write a python script that was unzipping a an archive containing several excel files and then load the data of a specific sheet into a MySQL 5 database. Doing it with only SQL was not an option since it required some manual actions (saving the sheet as csv, which resulted in [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had to write a python script that was unzipping a an archive containing several excel files and then load the data of a specific sheet into a MySQL 5 database. Doing it with only SQL was not an option since it required some manual actions (saving the sheet as csv, which resulted in the loss the data from formulas including other sheets, corrected by copying/pasting the data beforehand and columns containing commas or other type of char).</p>
<p>I used <a title="xlrd" href="http://pypi.python.org/pypi/xlrd">xlrd</a> as the API to read the excel files and the <a href="http://docs.python.org/library/zipfile.html" title="zipfile">zipfile</a> module to unzip.</p>
<p>My first thought was to parse each line and insert the whole file in a single really big INSERT. Needless to say it was really slow.<br />
I then thought of converting the xls files to csv files and then use the <a title="load_into" href="http://dev.mysql.com/doc/refman/5.1/en/load-data.html">LOAD INTO</a> syntax from MySQL, which is quite fast (~3s for 30k lines).</p>
<p>I found a script doing close to what I wanted <a title="excel_to_csv" href="http://code.activestate.com/recipes/546518-simple-conversion-of-excel-files-into-csv-and-yaml/">here</a> so I took the core and tweaked it a bit : choose a sheet, a delimiter and remove unwanted characters.</p>
<p>For the example, let&#8217;s say we have 2 tables (table1 and table2) to load into (indentation are whitespace, not tab) :</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import xlrd
import csv
import MySQLdb
import os
import re
import zipfile

#Gets and formats the data from the sheet
def sheet_to_dictionary(excel_file, sheet_number):
   book = xlrd.open_workbook(excel_file)
   formatter = lambda(t,v): format_excel_value(book,t,v)
   raw_sheet = book.sheet_by_index(sheet_number)
   data = []

   for row in range(raw_sheet.nrows):
      (types, values) = (raw_sheet.row_types(row), raw_sheet.row_values(row))
      data.append(map(formatter, zip(types, values)))

   return ({ 'sheet_data': data })

#Format Excel date to isodate
def exceldate_to_isodate(datetuple):
   (y,m,d, hh,mm,ss) = datetuple
   nonzero = lambda n: n!=0
   date = &quot;%04d-%02d-%02d&quot; % (y,m,d) if filter(nonzero,(y,m,d)) else ''
   return date

#Clean the excel formatting
def format_excel_value(book, type, value):
   if type == 2: # NUMBER
      if value == int(value): value = int(value)
   elif type == 3: # DATE
      datetuple = xlrd.xldate_as_tuple(value, book.datemode)
      value = exceldate_to_isodate(datetuple)
   elif type == 5: # ERROR
      value = xlrd.error_text_from_code[value]
   elif type == 1 and '\n' in value: #There was some \n characters in my files that i needed to remove
      value = value.replace('\n',' ')
   return value

#UTF-8 the strings
def utf8ize(l):
   return [unicode(s).encode(&quot;utf-8&quot;) if hasattr(s,'encode') else s for s in l]

#Creates the CSV
def create_csv(table, file_path, delimit):
   file = open(file_path, 'wb')
   csvout = csv.writer(file, delimiter=delimit, doublequote=False, escapechar='\\')
   csvout.writerows(map(utf8ize, table))

#Load the table1 CSV into the table1 table
def load_table1(file_path):
   sql = &quot;&quot;&quot;LOAD DATA LOCAL INFILE '%s'
   INTO TABLE table1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' IGNORE 1 LINES
   (col1, col2, col3)
   &quot;&quot;&quot; % (file_path)
   execute_sql(sql)

#Load the table2 CSV into the table2 table
def load_table2(file_path):
#Using ';' as a delimiter since there are ',' in the rows
   sql = &quot;&quot;&quot;LOAD DATA LOCAL INFILE '%s'
   INTO TABLE table2 FIELDS TERMINATED BY ';' LINES TERMINATED BY '\n' IGNORE 1 LINES
   (col1, col2, col3)
   &quot;&quot;&quot; % (file_path)
   execute_sql(sql)

def execute_sql(sql):
   connection = MySQLdb.connect(host = &quot;127.0.0.1&quot;, user = &quot;root&quot;, passwd = &quot;password&quot;, db = &quot;test&quot;)
   cursor = connection.cursor()
   cursor.execute(sql)
   cursor.close
   connection.commit()
   connection.close

#Unzip the archive containing the excel files
re_zip = re.compile(r'(\.zip)$')
zip_filename = filter(re_zip.search, os.listdir(&quot;.&quot;)) #Using the script directory, but you could easily change that

#Should have only one zip file in the directory
z = zipfile.ZipFile(zip_filename[0])
names = z.namelist()
z.extractall()
z.close()

#Loads the xls data into the database and removes the files when we're done with them
for filename in names:
   if &quot;table1&quot; in filename:
      csv_name = 'table1.csv'
      table = sheet_to_dictionary(filename, 3)
      create_csv(table['sheet_data'], csv_name, ',')
      load_non_mandate(csv_name)
      os.remove(filename)
      os.remove(csv_name)
   if &quot;table2&quot; in filename:
      csv_name = 'table2.csv'
      table = sheet_to_dictionary(filename, 9)
      create_csv(table['sheet_data'], csv_name, ';') #There was some commas in the columns, preventing me to use a basic CSV
      load_time_reporting(csv_name)
      os.remove(filename)
      os.remove(csv_name)

os.remove(zip_filename[0])
#When the script is finished, data is loaded in the tables and all the files, including the zip are deleted, you could also
#archive them if you want
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mademyday.net/2011/08/01/load-various-excel-files-into-mysql-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Expert 101 3/X : DDL and DML</title>
		<link>http://www.mademyday.net/2010/04/15/sql-expert-101-3x-ddl-and-dml/</link>
		<comments>http://www.mademyday.net/2010/04/15/sql-expert-101-3x-ddl-and-dml/#comments</comments>
		<pubDate>Fri, 16 Apr 2010 00:43:24 +0000</pubDate>
		<dc:creator>Vincent Prouillet</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[certification]]></category>
		<category><![CDATA[learning]]></category>

		<guid isPermaLink="false">http://www.mademyday.net/?p=113</guid>
		<description><![CDATA[This article is the third of a series of articles aiming to prepare me (and you) to pass the 1Z0-047 Oracle Database SQL Expert. This part covers DDL (like creating table, adding constraints) and DML (insert/update/delete data). Maybe I should have done it in first but anyway let&#8217;s begin. Summary : Using DDL Statements to [...]]]></description>
			<content:encoded><![CDATA[<div>
    This article is the third of a series of articles aiming to prepare me (and you) to pass the <a href="http://education.oracle.com/pls/web_prod-plq-dad/db_pages.getpage?page_id=41&amp;p_exam_id=1Z0_047" target="_blank">1Z0-047 Oracle Database SQL Expert</a>.</p>
<p>    This part covers DDL (like creating table, adding constraints) and DML (insert/update/delete data).<br />
    Maybe I should have done it in first but anyway let&#8217;s begin.</p>
<p>    Summary :</p>
<ol>
<li><a href="#ddl">Using DDL Statements to Create and Manage Tables</a></li>
<li><a href="#dml">Manipulating Data</a></li>
</ol>
<p>    <span id="more-113"></span></p>
<p>    <a name="ddl"></a><span style="text-decoration: underline;"><strong>Using DDL Statements to Create and Manage Tables</strong></span></p>
<p>    <span style="text-decoration: underline;">The main database objects :</span><br />
    The 047 certification will only represent the following objects :</p>
<ul>
<li>Table : the basic structure to stock data, organized in columns and rows</li>
<li>Constraint : an element used on a table that will decide how the table will accept or reject data</li>
<li>Index : an object that accelerates searches in a table : it copies and sorts only a small chunk of data that will be used when we lookup for data in this table</li>
<li>Sequence : an object that generates unique numbers, typically used for primary key</li>
<li>View : a virtual table created by filtering the data of a real table, used when we don&#8217;t need the whole table</li>
<li>Synonym : an alias for a database object</li>
<li>User : the database objects owner</li>
<li>Role : one (or several) privilege(s) that can be granted to users</li>
</ul>
<p>    All these objects except users, roles and public synonyms are called schema objects. That means it belongs to a schema (collection of objects) and thus can be owned by a user.<br />
    The three left are non-schema objects : no user can own it. </p>
<p>    <span style="text-decoration: underline;"> 	List the data types that are available for columns :</span><br />
    Before creating a table, we can ask ourselves what kind of data types we can use in a column&#8217;s table.<br />
    Here is the list :</p>
<ul>
<li>CHAR(n) : stock a fixed-length alphanumerical value, n represents the length of the value. If the value is shorter than n, it will pad the value with blanks. n is optional : if not present, the database uses a value of 1</li>
<li>VARCHAR2(n) : stock a variable-length alphanumerical value, n represents the maximal length of the value. If the value is shorter than n, it will not pad the value. n is mandatory and it needs a minimal value of 1.</li>
<li>NUMBER(n,m) : stock numeric value (negative, 0, positive), n is the maximum number of digits in the value and m is the maximum number of digits of decimals. They are both optional (m default value is 0 though so the value will be rounded)</li>
<li>DATE : stock dates in litterals (depending on the parameter NLS_DATE_FORMAT, generally DD-MON-RR like 10-APR-10) or using conversions functions previously seen.</li>
<li>TIMESTAMP(n) : type of dates that stores up to the fractional seconds, n is optional and is the precision for fractional seconds (default 6)</li>
<li>TIMESTAMP(n) WITH TIME ZONE : same as above but adds a time zone region name or an offset for time zone</li>
<li>TIMESTAMP(n) WITH LOCAL TIME ZONE : same as above but the offset for time zone is retrieved from the user&#8217;s session and not stored in the column</li>
<li>INTERVAL YEAR(n) TO MONTH : used to store a period of time in month or year value (like the difference between 2 dates) with n being optional and in 0-9</li>
<li>INTERVAL DAY(n) TO SECOND (n) : same as above but the value is in seconds, minutes, hours and days with n being optional and in 0-9.</li>
<li>BLOB : means Binary Large OBjects, used to store binary objects like video or pictures, it can&#8217;t be used as primary key or with DISTINCT, GROUP BY, ORDER BY and joins</li>
<li>CLOB : means Character Large OBjects, same as above but used to store large texts</li>
<li>NCLOB : same as above but used to store large texts in Unicode</li>
</ul>
<p></p>
<p>    <span style="text-decoration: underline;">Create a simple table :</span><br />
    Now we have seen the different data types, we can safely create tables.<br />
    For example how could we create the table used in the previous articles ?</p>
<pre class="brush: sql; title: ; notranslate">
    CREATE TABLE employees
    (
    id              NUMBER,
    first_name      VARCHAR2(30),
    last_name       VARCHAR2(40),
    monthly_salary  NUMBER
    );
    </pre>
<p>    As you can see, tables are created using the words CREATE TABLE followed by the desired name of the database and column&#8217;s names and their type (see previous paragraph) in parentheses.</p>
<p>    A quick word on the names of database objects : it should have between 1 and 30 characters, the first one must be a letter, you can use letters, numbers, $ (dollar), _ (underscore) and # (pound) in it.<br />
    It also should not be one of the database reserved words. <br />
    The name isn&#8217;t case sensitive except if you use double quotes. If it&#8217;s the case, the name is case sensitive and you can also use some more special characters. The counterpart is you always have to use double quotes to reference this table so it&#8217;s not recommended to use it.<br />
    The name must also be unique in his namespace (same concept as programmation) : in a schema, constraints and indexes are in their own namespaces but tables, views, sequences and private synonyms are are in one namespace.<br />
    What does it mean? You can&#8217;t have 2 tables called employees in the same schema but one table called employees and an index also called employees in the same schema is ok.<br />
    To conclude this reflection, don&#8217;t forget to give meaningful and easy to read names.</p>
<p>    <span style="text-decoration: underline;">Review the table structure</span><br />
    We&#8217;ve already seen that in a previous article so that&#8217;s going to be quick.<br />
    We can see the structure of a table using the DESCRIBE command :</p>
<pre class="brush: sql; title: ; notranslate">
    DESCRIBE employees;
    DESC employees;
    </pre>
<p>    DESC is a synonym for DESCRIBE.</p>
<p>    <span style="text-decoration: underline;">Explain how constraints are created at the time of table creation</span><br />
    There are several constraints :</p>
<ul>
<li>NOT NULL : a column that has this constraint must have a value. If it doesn&#8217;t, the statement will fail</li>
<li>UNIQUE : a column that has this constraint ensure that its value won&#8217;t be present in any other rows. You can use UNIQUE on a combination of columns</li>
<li>PRIMARY KEY : identifier of rows in a table, it&#8217;s a combination of NOT NULL and UNIQUE. You can use a multi-column primary key : it&#8217;s called a composite primary key but you can have only one primary key per table</li>
<li>FOREIGN KEY : a foreign key works with a primary key from another table, it&#8217;s a reference to it, to preserve data integrity</li>
<li>CHECK : this constraint add a rule to a column following an expression (there is an example after)</li>
</ul>
<p>    There is no CREATE CONSTRAINT command, you have to add constraints for tables in a CREATE TABLE or ALTER TABLE command.</p>
<pre class="brush: sql; title: ; notranslate">
    -- out of line primary key constraint
    CREATE TABLE employees
    (
    id              NUMBER,
    first_name      VARCHAR2(30),
    last_name       VARCHAR2(40),
    monthly_salary  NUMBER,
    CONSTRAINT employees_pk PRIMARY KEY (id)
    );

     -- in line primary key constraint
    CREATE TABLE employees
    (
    id              NUMBER CONSTRAINT employees_pk PRIMARY KEY,
    first_name      VARCHAR2(30),
    last_name       VARCHAR2(40),
    monthly_salary  NUMBER
    );

     -- not null constraint : a value has to be provided in the monthly salary column
    CREATE TABLE employees
    (
    id              NUMBER,
    first_name      VARCHAR2(30),
    last_name       VARCHAR2(40),
    monthly_salary  NUMBER CHECK NOT NULL
    );

    -- check constraint : monthly salary must be between 0 et 5000
    CREATE TABLE employees
    (
    id              NUMBER,
    first_name      VARCHAR2(30),
    last_name       VARCHAR2(40),
    monthly_salary  NUMBER CHECK (monthly_salary IN (0, 5000))
    );

    --Add a primary key constraint on id (supposing we didn't add one before), in line
    ALTER TABLE employees
    MODIFY id CONSTRAINT employees_pk PRIMARY KEY;

    --same as above, out of line
    ALTER TABLE employees
    ADD CONSTRAINT employees_pk PRIMARY KEY (id);

    --Add a not null constraint
    ALTER TABLE employees
    MODIFY monthly_salary NOT NULL;
    </pre>
<p>    Note that the NOT NULL constraint can only be added with an in line method.</p>
<p>    If you don&#8217;t provide a name to the constraint, the database will automatically assign one.</p>
<p>    <a name="dml"></a><span style="text-decoration: underline;"><strong>Manipulating Data</strong></span></p>
<p>    <span style="text-decoration: underline;">Describe each data manipulation language (DML) statement</span><br />
    There are five DML statements :</p>
<ul>
<li>SELECT : displays data from a table or a view</li>
<li>INSERT : inserts data in a table</li>
<li>UPDATE : modifies data in a table</li>
<li>DELETE : removes data from a table</li>
<li>MERGE : inserts or modifies data in a table depending on whether or not a condition matches</li>
</ul>
<p>    <span style="text-decoration: underline;">Insert rows into a table</span><br />
    INSERT is used to add rows in a table, for the example let&#8217;s add some rows in the table employees.</p>
<pre class="brush: sql; title: ; notranslate">
    INSERT INTO employees
    (id, first_name, last_name, monthly_salary)
    VALUES
    (1, 'Eric', 'Leyton', 2000);

    -- Or since the value matches the list of columns
    INSERT INTO employees
    VALUES
    (1, 'Eric', 'Leyton', 2000);
    </pre>
<p>    So which one should we use?<br />
    It&#8217;s the same answer than for SELECT *, if you modify the columns, for example switch the place of first_name and last_name, the statement will run successfully but the data won&#8217;t be correct.<br />
    <br />
    Of course, INSERT statements have to respect the constraint on the table (PRIMARY KEY, NOT NULL, etc..).<br />
    <br />
    How could we be sure that the id will be unique?</p>
<pre class="brush: sql; title: ; notranslate">
    --Create a sequence object
    CREATE SEQUENCE seq_employees_id;
    --Insert data using the sequence
    INSERT INTO employees
    (id, first_name, last_name, monthly_salary)
    VALUES
    (seq_employees_id.NEXTVAL, 'Eric', 'Leyton', 2000);
    </pre>
<p>    <span style="text-decoration: underline;">Update rows in a table</span><br />
    UPDATE is used to modify existing data in a table, identified with a WHERE clause if necessary.</p>
<pre class="brush: sql; title: ; notranslate">
    UPDATE employees
    SET first_name = 'Leyla',
        monthly_salary = 2200
    WHERE id = 1
    </pre>
<p>    The WHERE clause is very important : without it, all the rows of the table would be updated.<br />
    <br />
    The UPDATE statement also have to respect the constraints.</p>
<p>    <span style="text-decoration: underline;">Delete rows from a table</span><br />
    DELETE is used to delete existing data in a table, identified with a WHERE clause generally (except if you want to delete all the rows in a table).</p>
<pre class="brush: sql; title: ; notranslate">
    DELETE FROM employees
    WHERE id = 1
    </pre>
<p>    <span style="text-decoration: underline;">Control transactions</span><br />
    When we use DML, we generally also use TCL (Transaction Control Language).<br />
    TCL provides the functionality to save or rollback changes made to the database.<br />
    There are 3 TCL :</p>
<ul>
<li>COMMIT : saves changes to the database</li>
<li>ROLLBACK : undoes changes to the last COMMIT or SAVEPOINT</li>
<li>SAVEPOINT : allows to commit ot rollback at certain point</li>
</ul>
<p>    There are 2 types of COMMIT : explicit and implicit.</p>
<pre class="brush: sql; title: ; notranslate">
    -- Explicit commit
    COMMIT;
    -- Or COMMIT WORK; ANSI standard
    </pre>
<p>    Implicit commit occurs before and after any DDL (such as CREATE, ALTER, etc &#8230;) and when the user exits the application. <br />
    Before changes are committed, they&#8217;re only visible to the one that made the change and so other users could use obsolete data without knowing.</p>
<p>    ROLLBACK removes changes made to the database up to the last COMMIT or SAVEPOINT.</p>
<pre class="brush: sql; title: ; notranslate">
    COMMIT;
    DELETE FROM employees;
    --Oops forgot the WHERE clause and deleted the whole table
    ROLLBACK;
    -- No problem the datas are back
    </pre>
<p>    SAVEPOINT allows to perform ROLLBACK at a point by naming a SCN (System Change Number).</p>
<pre class="brush: sql; title: ; notranslate">
    UPDATE employees SET monthly_salary = 2000
    SAVEPOINT sp_1;
    UPDATE employees SET monthly_salary = 3000
    SAVEPOINT sp_2;
    UPDATE employees SET monthly_salary = 30000
    --Oops
    ROLLBACK WORK TO sp_2;
    COMMIT;
    </pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.mademyday.net/2010/04/15/sql-expert-101-3x-ddl-and-dml/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RMAN</title>
		<link>http://www.mademyday.net/2010/04/08/rman/</link>
		<comments>http://www.mademyday.net/2010/04/08/rman/#comments</comments>
		<pubDate>Thu, 08 Apr 2010 20:55:54 +0000</pubDate>
		<dc:creator>Vincent Prouillet</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Oracle]]></category>

		<guid isPermaLink="false">http://www.mademyday.net/?p=109</guid>
		<description><![CDATA[RMAN (Recovery Manager) is the the backup and recovery tool recommended by Oracle. There are several ways to create RMAN jobs : EM interface, command-line and scripts.Before the technical stuff, we should learn the backup vocabulary. First of all, there is 2 types of backup : user-managed (using OS commands) and server-managed (using database tools [...]]]></description>
			<content:encoded><![CDATA[<div>
<p>RMAN (Recovery Manager) is the the backup and recovery tool recommended by Oracle.</p>
<p>There are several ways to create RMAN jobs : EM interface, command-line and scripts.Before the technical stuff, we should learn the backup vocabulary.<br />
<span id="more-109"></span><br />
First of all, there is 2 types of backup : user-managed (using OS commands) and server-managed (using database tools like RMAN).</p>
<p>This article will only deal with backup of the second type.</p>
<p>There are 3 choices to make :</p>
<ul>
<li>closed (database is shutdown) or open (database is running, but needs to be in archivelog mode)</li>
<li>whole (backup of all the datafiles and control files) or partial (only a part of it)</li>
<li>full (backup of all the files) or incremental (backup of only the blocks that changed since the last backup)</li>
</ul>
<p>RMAN can backup datafile, archive redo log, SPFILE and control file and offers 3 types of backup type : backup set (oracle format which needs to be restored before use), compressed backup set (same as backup set but compressed) and image copy (immediatly interchangeable with the source).</p>
<p>The backup and recovery operations are done using processes known as channels (disk or tape).</p>
<p>The RMAN repository contains metadata about the target database and its backup (name, location) and is stored in the controlfile of the target database.</p>
<p>Optionnaly, you can store it in a catalog database.</p>
<p>You can also use an auxiliary database, created from a backup from the target database.</p>
<h2>Consistent backups</h2>
<p>We can do that in command line or with EM.</p>
<p>EM 10g version : Maintenance &gt; Schedule Backup &gt; choose customized as backup strategy<br />
EM 11g version : Availabilty &gt; Schedule Backup &gt; choose customized as backup strategy<br />
Select Offline Backup and follow instructions</p>
<p>Command line version : create a script backup_full_offline.rman</p>
<pre class="brush: bash; title: ; notranslate">
run {
shutdown immediate;
startup mount;
allocate channel c1 type disk;
backup as backupset database
format 'd:\backup\offline_full_whole.bus';
alter database open;
}
</pre>
<p>and run it with :</p>
<pre class="brush: bash; title: ; notranslate">
 rman target sys/oracle@orcl11g @offline_full_whole.rman
</pre>
<p>Or run each command separately in the rman appli.</p>
<h2>Open backups</h2>
<p>This backup is of course also reliable (database must be in archivelog mode).<br />
Same as before.<br />
Example of a script :</p>
<pre class="brush: bash; title: ; notranslate">
run {
allocate channel c1 type disk; #2 channels for parallelisation
allocate channel c2 type disk;
backup
format '/home/oracle/%d_t%t_s%s_p%p' #d = database_id, s = backup set number, p = piece number
(database); #save everything including archivelog files
release channel c1;
release channel c2;
}
</pre>
<p>You can also assign a tag to a backupset (a logical name).</p>
<p>To check if the database can be restored, use:</p>
<pre class="brush: bash; title: ; notranslate">
 restore database validate
</pre>
<h2>Incremental backups</h2>
<p>Incremental backups relies on a first full backup of the database, known as level 0.</p>
<pre class="brush: bash; title: ; notranslate">
backup as backupset incremental level 0 database plus archivelog;
</pre>
<p>When the level 0 backup is done, we will perform level 1 backup that will backup only the block that have changed since the last level 0 backup.</p>
<pre class="brush: bash; title: ; notranslate">
backup as backupset incremental level 1 database plus archivelog;
</pre>
<p>You can specify if you want the incremental backup to be cumulative (quicker) or differential (default value).<br />
Not necessarily faster than full backup because you have to scan the whole backup to look for changes.<br />
There&#8217;s a process to speed this up  : Change Tracking Writer which will write the address of each block that has changed in a file.</p>
<h2>Copy images</h2>
<p>Make an identical copy of datafiles/controlfile/archivelog</p>
<pre class="brush: bash; title: ; notranslate">
backup as copy database; #backup datafile and controlfile to the flash area
backup as copy archivelog all delete all input; #backup archivelog files to the flash area
</pre>
<h2>Backup of backups</h2>
<p>If you use tapes you can use these commands :</p>
<pre class="brush: bash; title: ; notranslate">
backup recovery area;
backup recovery files;
</pre>
<p>which will backup the flash area and files related to recovery to tape.</p>
<h2>Managing backups</h2>
<p>You can check the backup sets, copies or other files using list :</p>
<pre class="brush: bash; title: ; notranslate">
LIST backup;
LIST copy;
LIST backup of archivelog all;
</pre>
<p>You can also ask what needs to be backed up or obsolete files :</p>
<pre class="brush: bash; title: ; notranslate">
REPORT need backup;
REPORT obsolete;
</pre>
<p>LIST and REPORT commands use the rman repository for information and thus we can&#8217;t be sure if the files really exist. To check, use this command :</p>
<pre class="brush: bash; title: ; notranslate">
CROSSCHECK backup of database;
</pre>
<p>If there is data in rman repository but there isn&#8217;t corresponding files, use this :</p>
<pre class="brush: bash; title: ; notranslate">
DELETE EXPIRED backup;
DELETE obsolete will delete the files and the info in the repository.
</pre>
<h1>Recover and restore</h1>
<p>The DRA (Data Recovery Advisor) is a new tool in 11g used for diagnosing and repairing databases.<br />
Commands :</p>
<pre class="brush: bash; title: ; notranslate">
list failure;
advise failure; #generate script to repaire the failure
repair failure; #start the script
</pre>
<p>To restore a database, use :</p>
<pre class="brush: bash; title: ; notranslate">
#optional : set until time | to recover the database until that ime
restore database;
recover database; #use the archive logs to repeat the queries
alter database open resetlogs; #reset the online redo logs
</pre>
<p>If you want to restore only a tablespace or a datafile :</p>
<pre class="brush: bash; title: ; notranslate">
restore datafile '/disk/something.dbf';
restore tablespace example;
</pre>
<p>You also have to ensure the controlfile (vital for the database) will be have an autobackup :</p>
<pre class="brush: bash; title: ; notranslate">
configure controlfile autobackup on;
</pre>
<p>This command will enable an automatic backup of controlfile during every RMAN operation that can be easily restored :</p>
<pre class="brush: bash; title: ; notranslate">
restore controlfile from autobackup;
</pre>
<p>If you want to restore a database that has a copy image :</p>
<pre class="brush: bash; title: ; notranslate">
switch database to copy;
</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.mademyday.net/2010/04/08/rman/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

