6. Next step is to start ASM instance. Do not forget to set SID to be +ASM when you try to login with sqlplus in to the instance
$ export ORACLE_SID=+ASM
$ sqlplus / as sysasm
SQL*Plus: Release 11.2.0.1.0 Production on Mon Apr 5 09:28:21 2010
Copyright (c) 1982, 2009, Oracle. All rights reserved.
Connected to an idle instance.
SQL> startup
ASM instance started
Total System Global Area 284565504 bytes
Fixed Size 1336036 bytes
Variable Size 258063644 bytes
ASM Cache 25165824 bytes
ASM diskgroups mounted
SQL>
7. Lets check the status of our diskgroups
SQL> SELECT name, type, total_mb, free_mb FROM V$ASM_DISKGROUP;
DATA NORMAL 32756 32575
8. Check the list of available disks
SQL> select name, path from V$ASM_DISK;
NAME
------------------------------
PATH
--------------------------------------------------------------------
ORCL:DFDISK4
ORCL:DFDISK5
DFDISK0
ORCL:DFDISK0
DFDISK1
ORCL:DFDISK1
DFDISK2
ORCL:DFDISK2
DFDISK3
ORCL:DFDISK3
FBDISK0
ORCL:FBDISK0
FBDISK1
ORCL:FBDISK1
8 rows selected.
9. And create new diskgroup for flashback
SQL> CREATE DISKGROUP FBA NORMAL REDUNDANCY FAILGROUP fba_fb1 disk 'ORCL:FBDISK0' FAILGROUP fba_fb2 disk 'ORCL:FBDISK1';
Diskgroup created.
10. and see the new list of diskgroups
SQL> select name,total_mb from V$ASM_DISKGROUP;
NAME TOTAL_MB
------------------------------ ----------
DATA 32756
FBA 16378
11. Add two new disks to diskgroup DATA
SQL> ALTER DISKGROUP data ADD DISK 'ORCL:DFDISK4', 'ORCL:DFDISK5';
Diskgroup altered.
SQL> select name,total_mb from V$ASM_DISKGROUP where name='DATA';
NAME TOTAL_MB
------------------------------ ----------
DATA 49134
12. Remove one of the disks from diskgroup
SQL> ALTER DISKGROUP data DROP DISK DFDISK5;
Diskgroup altered.
SQL> select name,total_mb from V$ASM_DISKGROUP where name='DATA';
NAME TOTAL_MB
------------------------------ ----------
DATA 40945
and size is already 40GB
For further information about migration of database to ASM, filepaths, etc, please consult official Oracle documentation about ASM: Oracle® Database Storage Administrator's Guide
Oracle ASM - yet another LVM (system configuration)
4. Its time for some system administrator tasks. Oracle ASM need special mark of disks will work with
4.1. Because of some reason (i don't know why) ASM can work only with partitions, but not with entire disks. So it is need to create one big partition on each disk
[root@rh-asm-ora ~]# fdisk /dev/sda
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that, of course, the previous
content won't be recoverable.
The number of cylinders for this disk is set to 1044.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)
Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-1044, default 1):
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-1044, default 1044):
Using default value 1044
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
And the similar for the rest of the disks /dev/sdb, /dev/sdc, /dev/sdd, /dev/sde and /dev/sdf
4.2. Next step is to configure the ASMlib. This is done via init script
[root@rh-asm-ora ~]# /etc/init.d/oracleasm configure
Configuring the Oracle ASM library driver.
This will configure the on-boot properties of the Oracle ASM library
driver. The following questions will determine whether the driver is
loaded on boot and what permissions it will have. The current values
will be shown in brackets ('[]'). Hitting without typing an
answer will keep that current value. Ctrl-C will abort.
Default user to own the driver interface []: oracle
Default group to own the driver interface []: dba
Start Oracle ASM library driver on boot (y/n) [n]: y
Scan for Oracle ASM disks on boot (y/n) [y]: y
Writing Oracle ASM library driver configuration: done
Initializing the Oracle ASMLib driver: [ OK ]
Scanning the system for Oracle ASMLib disks: [ OK ]
If you do not get OK on the last line check /var/log/messages. Usual reason is you do not install the correct version of ASMlib. Check on this site Oracle ASMLib. If you cant find modules for your version of kernel you should compile them from source you can get from here: http://oss.oracle.com/projects/oracleasm/
4.3. And check if the kernel module is loaded
[root@rh-asm-ora ~]# lsmod |grep ora
oracleasm 46356 1
4.4. The module is loaded so lets label the disks to be recognized by Oracle ASM. I will dedicate 4 disks for tablespace and 2 disks for flashback
[root@rh-asm-ora ~]# /etc/init.d/oracleasm createdisk dfdisk0 /dev/sda1
Marking disk "dfdisk0" as an ASM disk: [ OK ]
[root@rh-asm-ora ~]# /etc/init.d/oracleasm createdisk dfdisk1 /dev/sdb1
Marking disk "dfdisk1" as an ASM disk: [ OK ]
[root@rh-asm-ora ~]# /etc/init.d/oracleasm createdisk dfdisk2 /dev/sdc1
Marking disk "dfdisk2" as an ASM disk: [ OK ]
[root@rh-asm-ora ~]# /etc/init.d/oracleasm createdisk dfdisk3 /dev/sdd1
Marking disk "dfdisk3" as an ASM disk: [ OK ]
[root@rh-asm-ora ~]# /etc/init.d/oracleasm createdisk fbdisk0 /dev/sde1
Marking disk "fbdisk0" as an ASM disk: [ OK ]
[root@rh-asm-ora ~]# /etc/init.d/oracleasm createdisk fbdisk1 /dev/sdf1
Marking disk "fbdisk1" as an ASM disk: [ OK ]
4.5. Check the ASM volumes
[root@rh-asm-ora ~]# /etc/init.d/oracleasm listdisks
DFDISK0
DFDISK1
DFDISK2
DFDISK3
FBDISK0
FBDISK1
5. The next step is install Oracle ASM software. This is mostly straight-forward process, so just read the installation guide and do it. Please do not forget in version 11gR2 Oracle ASM is part of Grid installation package and not standard Oracle Database installation package
4.1. Because of some reason (i don't know why) ASM can work only with partitions, but not with entire disks. So it is need to create one big partition on each disk
[root@rh-asm-ora ~]# fdisk /dev/sda
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that, of course, the previous
content won't be recoverable.
The number of cylinders for this disk is set to 1044.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)
Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-1044, default 1):
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-1044, default 1044):
Using default value 1044
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
And the similar for the rest of the disks /dev/sdb, /dev/sdc, /dev/sdd, /dev/sde and /dev/sdf
4.2. Next step is to configure the ASMlib. This is done via init script
[root@rh-asm-ora ~]# /etc/init.d/oracleasm configure
Configuring the Oracle ASM library driver.
This will configure the on-boot properties of the Oracle ASM library
driver. The following questions will determine whether the driver is
loaded on boot and what permissions it will have. The current values
will be shown in brackets ('[]'). Hitting without typing an
answer will keep that current value. Ctrl-C will abort.
Default user to own the driver interface []: oracle
Default group to own the driver interface []: dba
Start Oracle ASM library driver on boot (y/n) [n]: y
Scan for Oracle ASM disks on boot (y/n) [y]: y
Writing Oracle ASM library driver configuration: done
Initializing the Oracle ASMLib driver: [ OK ]
Scanning the system for Oracle ASMLib disks: [ OK ]
If you do not get OK on the last line check /var/log/messages. Usual reason is you do not install the correct version of ASMlib. Check on this site Oracle ASMLib. If you cant find modules for your version of kernel you should compile them from source you can get from here: http://oss.oracle.com/projects/oracleasm/
4.3. And check if the kernel module is loaded
[root@rh-asm-ora ~]# lsmod |grep ora
oracleasm 46356 1
4.4. The module is loaded so lets label the disks to be recognized by Oracle ASM. I will dedicate 4 disks for tablespace and 2 disks for flashback
[root@rh-asm-ora ~]# /etc/init.d/oracleasm createdisk dfdisk0 /dev/sda1
Marking disk "dfdisk0" as an ASM disk: [ OK ]
[root@rh-asm-ora ~]# /etc/init.d/oracleasm createdisk dfdisk1 /dev/sdb1
Marking disk "dfdisk1" as an ASM disk: [ OK ]
[root@rh-asm-ora ~]# /etc/init.d/oracleasm createdisk dfdisk2 /dev/sdc1
Marking disk "dfdisk2" as an ASM disk: [ OK ]
[root@rh-asm-ora ~]# /etc/init.d/oracleasm createdisk dfdisk3 /dev/sdd1
Marking disk "dfdisk3" as an ASM disk: [ OK ]
[root@rh-asm-ora ~]# /etc/init.d/oracleasm createdisk fbdisk0 /dev/sde1
Marking disk "fbdisk0" as an ASM disk: [ OK ]
[root@rh-asm-ora ~]# /etc/init.d/oracleasm createdisk fbdisk1 /dev/sdf1
Marking disk "fbdisk1" as an ASM disk: [ OK ]
4.5. Check the ASM volumes
[root@rh-asm-ora ~]# /etc/init.d/oracleasm listdisks
DFDISK0
DFDISK1
DFDISK2
DFDISK3
FBDISK0
FBDISK1
5. The next step is install Oracle ASM software. This is mostly straight-forward process, so just read the installation guide and do it. Please do not forget in version 11gR2 Oracle ASM is part of Grid installation package and not standard Oracle Database installation package
Oracle ASM - yet another LVM (Instalation)
1. OS installation
For OS I will use CentOS with config:
- 1.5 GB RAM
- 20 GB harddisk for OS and software
- 6*8GB harddisks for ASM
I install only server cluster and exclude some packages like PCMCIA support, smartcard, power management, etc. They are not need for server.
1.1. After installation the first task is to update your system. For this I will use command
yum update yum* rpm* kernel*
At the moment I do not need more updates. After update the kernel its need to reboot server.
1.2. Install prerequisites packages. Here is the list of the packages:
xdpyinfo
libXmp
binutils
compat-libstdc++-33
elfutils-libelf
elfutils-libelf-devel
elfutils-libelf-devel-static
gcc
gcc-c++
glibc
glibc-common
glibc-devel
glibc-headers
kernel-headers
ksh
libaio
libaio-devel
libgcc libgomp
libstdc++
libstdc++-devel
make
sysstat
unixODBC
unixODBC-devel
Here and below the information is get directly from Oracle Technical Network, Documentation section.
First and second packages are not need according to the documentation, but my personal experience show me they are need.
2. Configure OS
2.1. Set kernel parameters
this is the list of parameters you should set in /etc/sysctl.conf to make software run. If some ot the parameters exist in original file just set recommended values
fs.aio-max-nr = 1048576
fs.file-max = 6815744
kernel.shmall = 2097152
kernel.shmmax = 536870912
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048586
Do not forget to execute sysctl -p or reboot the server to get parameters set.
2.2. Add groups
oinstall, oper, dba, asmadmin, asmdba, asmoper
2.3. Create oracle user to have primary group oinstall and member of dba and oper and shell KornShell
2.4. Set in /etc/security/limits.conf number of files and number of processes for oracle user as follow
oracle soft nproc 2047
oracle hard nproc 16384
oracle soft nofile 1024
oracle hard nofile 65536
2.5. Add in /etc/profile the settings for ulimits for oracle user
if [ $USER = "oracle" ]; then
if [ $SHELL = "/bin/ksh" ]; then
ulimit -u 16384
ulimit -n 65536
else
ulimit -u 16384 -n 65536
fi
umask 022
fi
On my CentOS option, provided by Oracle documentation (ulimit -p 16384) because of version of ksh, so if you are with RHEL 5.x and if the version of ksh is like ksh-20080202-14.
_4.2 use ulimit -u 16384
3. Install Oracle ASM libraries and kernel modules. The packages should be downloaded from https://www.oracle.com/technetwork/database/enterprise-edition/downloads/oracle18c-linux-180000-5022980.html
Search for "Oracle Database XXX Grid Infrastructure"
Do not forget you should download and install libraries for your distribution and version of kernel. You can use this command to check the version of kernel
[root@rh-asm-ora rpm]# uname -r
2.6.18-164.15.1.
For OS I will use CentOS with config:
- 1.5 GB RAM
- 20 GB harddisk for OS and software
- 6*8GB harddisks for ASM
I install only server cluster and exclude some packages like PCMCIA support, smartcard, power management, etc. They are not need for server.
1.1. After installation the first task is to update your system. For this I will use command
yum update yum* rpm* kernel*
At the moment I do not need more updates. After update the kernel its need to reboot server.
1.2. Install prerequisites packages. Here is the list of the packages:
xdpyinfo
libXmp
binutils
compat-libstdc++-33
elfutils-libelf
elfutils-libelf-devel
elfutils-libelf-devel-static
gcc
gcc-c++
glibc
glibc-common
glibc-devel
glibc-headers
kernel-headers
ksh
libaio
libaio-devel
libgcc libgomp
libstdc++
libstdc++-devel
make
sysstat
unixODBC
unixODBC-devel
Here and below the information is get directly from Oracle Technical Network, Documentation section.
First and second packages are not need according to the documentation, but my personal experience show me they are need.
2. Configure OS
2.1. Set kernel parameters
this is the list of parameters you should set in /etc/sysctl.conf to make software run. If some ot the parameters exist in original file just set recommended values
fs.aio-max-nr = 1048576
fs.file-max = 6815744
kernel.shmall = 2097152
kernel.shmmax = 536870912
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048586
Do not forget to execute sysctl -p or reboot the server to get parameters set.
2.2. Add groups
oinstall, oper, dba, asmadmin, asmdba, asmoper
2.3. Create oracle user to have primary group oinstall and member of dba and oper and shell KornShell
2.4. Set in /etc/security/limits.conf number of files and number of processes for oracle user as follow
oracle soft nproc 2047
oracle hard nproc 16384
oracle soft nofile 1024
oracle hard nofile 65536
2.5. Add in /etc/profile the settings for ulimits for oracle user
if [ $USER = "oracle" ]; then
if [ $SHELL = "/bin/ksh" ]; then
ulimit -u 16384
ulimit -n 65536
else
ulimit -u 16384 -n 65536
fi
umask 022
fi
On my CentOS option, provided by Oracle documentation (ulimit -p 16384) because of version of ksh, so if you are with RHEL 5.x and if the version of ksh is like ksh-20080202-14.
_4.2 use ulimit -u 16384
3. Install Oracle ASM libraries and kernel modules. The packages should be downloaded from https://www.oracle.com/technetwork/database/enterprise-edition/downloads/oracle18c-linux-180000-5022980.html
Search for "Oracle Database XXX Grid Infrastructure"
Do not forget you should download and install libraries for your distribution and version of kernel. You can use this command to check the version of kernel
[root@rh-asm-ora rpm]# uname -r
2.6.18-164.15.1.
Oracle DB for system administrators, part8 (shell scripts)
In this part I will discuss some shell scripts you can create/use for work automation in Oracle database.
36. One very important, but very dangerous think is to create start and stop script for oracle.
Its important because if you want to stop and start the machine (and database) graceful you should execute serie of commands and always exist possibility to forget one of them. Because of this its good to have some script to stop and start Oracle DB.
36.1. Very important is to edit /etc/oratab file (here and below i will use locations of the files as they are in RHEL) and to have your instance(s) on this way:
[root@rh-or ~]# grep -v ^# /etc/oratab
orcl:/home/oracle/11g2:Y
First value is name of the instance i.e. SID, second is the value of ORACLE_HOME and third one is Y - to start this instance and N do not start it. Lines, starting with # are comments
36.2. Next I will create sample start/stop script
[root@rh-or ~]# more /etc/init.d/oracle
#!/bin/bash
#
# oracle Startup script for start oracle database server
#
ORACLE_HOME=/home/oracle/11g2
ORACLE_SID=orcl
PATH=$PATH:/$ORACLE_HOME/bin
ORACLE=oracle # user to run oracle DB
export ORACLE_HOME ORACLE_SID PATH ORACLE
#
start() {
echo -n $"Starting oracle"
su - -c "dbstart" $ORACLE
su - -c "lsnrctl start" $ORACLE
}
stop() {
echo -n $"Stopping oracle"
su - -c "lsnrctl stop" oracle
su - -c "dbshut" oracle
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo $"Usage: $prog {start|stop|restart}"
exit 1
esac
I put my script in /etc/init.d because this is the place for such scripts in Linux, but do not create softlinks in rc.d directories to avoid auto start/restart because this is not a good idea. If You want You can do it
Of course I can use only dbstart and dbshut, but for this i should change those scripts and I personalty prefer do not touch them. And this give me better control over the precedence of start listener and database itself. Actually the only change is to define variable ORACLE_HOME_LISTNER (which in my case is equiv to ORACLE_HOME).
37. the next point is to automate execution of sql scripts from command line w/o starting sqlplus in interactive mode
I prepare one sample script:
[oracle@rh-or ~]$ cat date.sql
set head off
select sysdate from dual;
exit
and I will execute it on this way:
[oracle@rh-or ~]$ sqlplus -S romeo/pass1234@orcl @date.sql
24-MAR-10
[oracle@rh-or ~]$
As you see execution is not different from any shell script. Here I mention in command line explicitly the name of the SID, because this is very helpful in situation you execute script from server with installed oracle client against some oracle server
38. If Your sql script need some parameters to be entered you can enter them as parameters of command line. For script:
[oracle@rh-or ~]$ cat date.sql
set head off
set verify off
select '&1', sysdate from dual;
exit
I need to enter one parameter (usually by hand), but I will set it from command line
[oracle@rh-or ~]$ sqlplus -S romeo/pass1234@orcl @date.sql "Today is "
Today is 24-MAR-10
[oracle@rh-or ~]$
36. One very important, but very dangerous think is to create start and stop script for oracle.
Its important because if you want to stop and start the machine (and database) graceful you should execute serie of commands and always exist possibility to forget one of them. Because of this its good to have some script to stop and start Oracle DB.
36.1. Very important is to edit /etc/oratab file (here and below i will use locations of the files as they are in RHEL) and to have your instance(s) on this way:
[root@rh-or ~]# grep -v ^# /etc/oratab
orcl:/home/oracle/11g2:Y
First value is name of the instance i.e. SID, second is the value of ORACLE_HOME and third one is Y - to start this instance and N do not start it. Lines, starting with # are comments
36.2. Next I will create sample start/stop script
[root@rh-or ~]# more /etc/init.d/oracle
#!/bin/bash
#
# oracle Startup script for start oracle database server
#
ORACLE_HOME=/home/oracle/11g2
ORACLE_SID=orcl
PATH=$PATH:/$ORACLE_HOME/bin
ORACLE=oracle # user to run oracle DB
export ORACLE_HOME ORACLE_SID PATH ORACLE
#
start() {
echo -n $"Starting oracle"
su - -c "dbstart" $ORACLE
su - -c "lsnrctl start" $ORACLE
}
stop() {
echo -n $"Stopping oracle"
su - -c "lsnrctl stop" oracle
su - -c "dbshut" oracle
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo $"Usage: $prog {start|stop|restart}"
exit 1
esac
I put my script in /etc/init.d because this is the place for such scripts in Linux, but do not create softlinks in rc.d directories to avoid auto start/restart because this is not a good idea. If You want You can do it
Of course I can use only dbstart and dbshut, but for this i should change those scripts and I personalty prefer do not touch them. And this give me better control over the precedence of start listener and database itself. Actually the only change is to define variable ORACLE_HOME_LISTNER (which in my case is equiv to ORACLE_HOME).
37. the next point is to automate execution of sql scripts from command line w/o starting sqlplus in interactive mode
I prepare one sample script:
[oracle@rh-or ~]$ cat date.sql
set head off
select sysdate from dual;
exit
and I will execute it on this way:
[oracle@rh-or ~]$ sqlplus -S romeo/pass1234@orcl @date.sql
24-MAR-10
[oracle@rh-or ~]$
As you see execution is not different from any shell script. Here I mention in command line explicitly the name of the SID, because this is very helpful in situation you execute script from server with installed oracle client against some oracle server
38. If Your sql script need some parameters to be entered you can enter them as parameters of command line. For script:
[oracle@rh-or ~]$ cat date.sql
set head off
set verify off
select '&1', sysdate from dual;
exit
I need to enter one parameter (usually by hand), but I will set it from command line
[oracle@rh-or ~]$ sqlplus -S romeo/pass1234@orcl @date.sql "Today is "
Today is 24-MAR-10
[oracle@rh-or ~]$
Oracle DB for system administrators, part7
In previous posts I use only commands to retrieve information. Now i time to change something in our database.
31. Insert new employee - long way
SQL> INSERT INTO HR (NOM, FNAME, LNAME, HIREDATE, JOB, SAL, MGR, DEPTNO)
VALUES (501, 'Romeo', 'Ninov', to_date('2010-01-01', 'YYYY-MM-DD'), 'sysadmin', 9000, 999, 210); 2
1 row created.
SQL>
Here I explicitly define mapping between column and value and fill all the columns.
32. So next is to insert new employee - short way
SQL> INSERT INTO HR VALUES (501, 'Test1', 'User1', NULL, NULL, to_date('2010-01-01', 'YYYY-MM-DD'), 9000, 210);
INSERT INTO HR VALUES (501, 'Test1', 'User1', NULL, NULL, to_date('2010-01-01', 'YYYY-MM-DD'), 9000, 210)
*
ERROR at line 1:
ORA-00001: unique constraint (ROMEO.SYS_C0011794) violated
Ha, i get a error, so lets try to investigate whats happen. If you go back to the creation of table HR you will see NOM column is a primary key and should be unique, so lets rewrite this insert and try again
SQL> INSERT INTO HR VALUES (502, 'Test1', 'User1', NULL, NULL, to_date('2010-01-01', 'YYYY-MM-DD'), 9000, 210);
1 row created.
SQL>
Voila, we insert another user.
33. Next we will create user similar to existing one. I will use user Test1 as template
SQL> INSERT INTO hr (nom, fname, lname, job, mgr, hiredate, sal, deptno) select 503 , 'Test2', 'User2', job, mgr, hiredate, sal, deptno from hr where nom=502;
1 row created.
And lets check what is the content of the table
SQL> select * from hr where nom>501;
NOM FNAME LNAME JOB MGR HIREDATE
---------- --------------- --------------- ---------- ---------- ---------
SAL DEPTNO
---------- ----------
502 Test1 User1 01-JAN-10
9000 210
503 Test2 User2 01-JAN-10
9000 210
So the work is done.
34. But I want to increase salary of employee Romeo by 3000
SQL> UPDATE hr SET sal = (select sal from hr where nom=501)+3000 WHERE nom=501;
1 row updated.
and check the new salary
SQL> select sal from hr where nom=501;
SAL
----------
12000
35. And I want to delete the employee Test1 and Test2
SQL> delete hr where nom=502 or nom=503;
2 rows deleted.
36. In case of usage of operations change the information to use command COMMIT or ROLLBACK to finish the transaction or return to previous status respectively. Be aware when you exit from sqlplus the commit command will be executed automatically. If you loose connection to the machine i.e broke connection to sqlplus rollback command will be executed. So I want to confirm changes and store the information
SQL> commit;
Commit complete.
31. Insert new employee - long way
SQL> INSERT INTO HR (NOM, FNAME, LNAME, HIREDATE, JOB, SAL, MGR, DEPTNO)
VALUES (501, 'Romeo', 'Ninov', to_date('2010-01-01', 'YYYY-MM-DD'), 'sysadmin', 9000, 999, 210); 2
1 row created.
SQL>
Here I explicitly define mapping between column and value and fill all the columns.
32. So next is to insert new employee - short way
SQL> INSERT INTO HR VALUES (501, 'Test1', 'User1', NULL, NULL, to_date('2010-01-01', 'YYYY-MM-DD'), 9000, 210);
INSERT INTO HR VALUES (501, 'Test1', 'User1', NULL, NULL, to_date('2010-01-01', 'YYYY-MM-DD'), 9000, 210)
*
ERROR at line 1:
ORA-00001: unique constraint (ROMEO.SYS_C0011794) violated
Ha, i get a error, so lets try to investigate whats happen. If you go back to the creation of table HR you will see NOM column is a primary key and should be unique, so lets rewrite this insert and try again
SQL> INSERT INTO HR VALUES (502, 'Test1', 'User1', NULL, NULL, to_date('2010-01-01', 'YYYY-MM-DD'), 9000, 210);
1 row created.
SQL>
Voila, we insert another user.
33. Next we will create user similar to existing one. I will use user Test1 as template
SQL> INSERT INTO hr (nom, fname, lname, job, mgr, hiredate, sal, deptno) select 503 , 'Test2', 'User2', job, mgr, hiredate, sal, deptno from hr where nom=502;
1 row created.
And lets check what is the content of the table
SQL> select * from hr where nom>501;
NOM FNAME LNAME JOB MGR HIREDATE
---------- --------------- --------------- ---------- ---------- ---------
SAL DEPTNO
---------- ----------
502 Test1 User1 01-JAN-10
9000 210
503 Test2 User2 01-JAN-10
9000 210
So the work is done.
34. But I want to increase salary of employee Romeo by 3000
SQL> UPDATE hr SET sal = (select sal from hr where nom=501)+3000 WHERE nom=501;
1 row updated.
and check the new salary
SQL> select sal from hr where nom=501;
SAL
----------
12000
35. And I want to delete the employee Test1 and Test2
SQL> delete hr where nom=502 or nom=503;
2 rows deleted.
36. In case of usage of operations change the information to use command COMMIT or ROLLBACK to finish the transaction or return to previous status respectively. Be aware when you exit from sqlplus the commit command will be executed automatically. If you loose connection to the machine i.e broke connection to sqlplus rollback command will be executed. So I want to confirm changes and store the information
SQL> commit;
Commit complete.
Oracle DB for system administrators, part6
26. Next I want to see all employees, having salary over average. This will be done using subquery. The idea is to create some selection from table and use the result as source for other select
SQL> SELECT fname, lname, sal FROM hr WHERE sal > (SELECT AVG(sal) FROM hr);
FNAME LNAME SAL
--------------- --------------- ----------
Michael Hartstein 13000
Susan Mavris 6500
Hermann Baer 10000
Shelley Higgins 12008
... snip ...
Alyssa Hutton 8800
Jonathon Taylor 8600
Jack Livingston 8400
50 rows selected.
As you see the subquery is placed within parentheses. You can use 255 levels ob subquery which is very big number for any kind of data.
27. I want to see the list of departments having average salary under maximum of average salary for departments
SQL> SELECT deptno, AVG(sal) FROM hr GROUP BY deptno HAVING AVG(sal) < (SELECT MAX(AVG(sal)) FROM hr GROUP BY deptno) ORDER BY deptno;
DEPTNO AVG(SAL)
---------- ----------
10 4400
20 9500
30 4150
40 6500
50 3475.55556
60 5760
70 10000
80 8955.88235
100 8601.33333
110 10154
10 rows selected.
and to be sure let see the maximum average salary of department.
SQL> select max(avg(sal)) from hr group by deptno;
MAX(AVG(SAL))
-------------
19333.3333
I you can see i use HAVING clause to filter group of rows. It is used because I mix multirow select (SELECT deptno) with single row function (AVG(sal)). If you try w/o this clause you will receive error
Wrong:
SQL> select deptno, avg(sal) from hr where avg(sal) >10000 group by deptno;
select deptno, avg(sal) from hr where avg(sal) >10000 group by deptno
*
ERROR at line 1:
ORA-00934: group function is not allowed here
Correct:
SQL> select deptno, avg(sal) from hr group by deptno having avg(sal) > 10000;
DEPTNO AVG(SAL)
---------- ----------
90 19333.3333
110 10154
29. Next I will try to use wildcard to select only people having TH combination of symbols in first name
SQL> select fname, lname from hr where fname like '%th%';
FNAME LNAME
--------------- ---------------
Matthew Weiss
Sarath Sewall
Elizabeth Bates
Jonathon Taylor
Martha Sullivan
Anthony Cabrio
Timothy Gates
7 rows selected.
SQL>
30. And as last from the points of retrieve information i want to get average salary by department plus average for the company
SQL> SELECT deptno, to_char(avg(sal), 99999.99) FROM hr GROUP BY ROLLUP(deptno) ORDER BY deptno;
DEPTNO TO_CHAR(A
---------- ---------
10 4400.00
20 9500.00
30 4150.00
40 6500.00
50 3475.56
60 5760.00
70 10000.00
80 8955.88
90 19333.33
100 8601.33
110 10154.00
6456.75
12 rows selected.
As you see the last line have no department number and actually is average salary for entire company
SQL> SELECT fname, lname, sal FROM hr WHERE sal > (SELECT AVG(sal) FROM hr);
FNAME LNAME SAL
--------------- --------------- ----------
Michael Hartstein 13000
Susan Mavris 6500
Hermann Baer 10000
Shelley Higgins 12008
... snip ...
Alyssa Hutton 8800
Jonathon Taylor 8600
Jack Livingston 8400
50 rows selected.
As you see the subquery is placed within parentheses. You can use 255 levels ob subquery which is very big number for any kind of data.
27. I want to see the list of departments having average salary under maximum of average salary for departments
SQL> SELECT deptno, AVG(sal) FROM hr GROUP BY deptno HAVING AVG(sal) < (SELECT MAX(AVG(sal)) FROM hr GROUP BY deptno) ORDER BY deptno;
DEPTNO AVG(SAL)
---------- ----------
10 4400
20 9500
30 4150
40 6500
50 3475.55556
60 5760
70 10000
80 8955.88235
100 8601.33333
110 10154
10 rows selected.
and to be sure let see the maximum average salary of department.
SQL> select max(avg(sal)) from hr group by deptno;
MAX(AVG(SAL))
-------------
19333.3333
I you can see i use HAVING clause to filter group of rows. It is used because I mix multirow select (SELECT deptno) with single row function (AVG(sal)). If you try w/o this clause you will receive error
Wrong:
SQL> select deptno, avg(sal) from hr where avg(sal) >10000 group by deptno;
select deptno, avg(sal) from hr where avg(sal) >10000 group by deptno
*
ERROR at line 1:
ORA-00934: group function is not allowed here
Correct:
SQL> select deptno, avg(sal) from hr group by deptno having avg(sal) > 10000;
DEPTNO AVG(SAL)
---------- ----------
90 19333.3333
110 10154
29. Next I will try to use wildcard to select only people having TH combination of symbols in first name
SQL> select fname, lname from hr where fname like '%th%';
FNAME LNAME
--------------- ---------------
Matthew Weiss
Sarath Sewall
Elizabeth Bates
Jonathon Taylor
Martha Sullivan
Anthony Cabrio
Timothy Gates
7 rows selected.
SQL>
30. And as last from the points of retrieve information i want to get average salary by department plus average for the company
SQL> SELECT deptno, to_char(avg(sal), 99999.99) FROM hr GROUP BY ROLLUP(deptno) ORDER BY deptno;
DEPTNO TO_CHAR(A
---------- ---------
10 4400.00
20 9500.00
30 4150.00
40 6500.00
50 3475.56
60 5760.00
70 10000.00
80 8955.88
90 19333.33
100 8601.33
110 10154.00
6456.75
12 rows selected.
As you see the last line have no department number and actually is average salary for entire company
Oracle DB for system administrators, part5
On previous parts I use only sample selects from single table. But this is just the begin, so lets create another table and link the tables
22. create new table
CREATE TABLE "ROMEO"."DEPT"
(
"DEPTNO" NUMBER(2,0),
"DNAME" VARCHAR2(14 BYTE),
"LOC" VARCHAR2(13 BYTE)
)
TABLESPACE "TEST01" ;
and fill it with data so will have name and location of departments
SQL> select * from dept;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL>
23. So lets select first name, last name of employee and name of department
SQL> SELECT hr.fname, hr.lname, dept.dname FROM hr, dept;
FNAME LNAME DNAME
--------------- --------------- --------------
Donald OConnell ACCOUNTING
Douglas Grant ACCOUNTING
Jennifer Whalen ACCOUNTING
...snip...
Kevin Feeney OPERATIONS
424 rows selected.
Hm, somethings wrong, we want to see only names of the person and name of department where he or she work. But see too many lines and very strange output. In this case we create so named Cartesian product or search. This is full combination of all rows from both tables. Lets imagine we have two tables, 1st with 100000 lines and second with 1000 lines. Cartesian search will produce 100 million of lines and we will overload the server. So be careful :)
Here I demonstrate how to use the exact column from table. The format is [Name of table].[Name of column] This help when you have columns with the same name in different tables.
24, So lets restrict the search and join both tables, mapping number of the department from table HR to the department number from table DEPT
SQL> SELECT hr.fname, hr.lname, dept.dname FROM hr, dept WHERE hr.deptno = dept.deptno;
FNAME LNAME DNAME
--------------- --------------- --------------
Jennifer Whalen ACCOUNTING
Michael Hartstein RESEARCH
Pat Fay RESEARCH
Susan Mavris OPERATIONS
Den Raphaely SALES
Alexander Khoo SALES
Shelli Baida SALES
Sigal Tobias SALES
Guy Himuro SALES
Karen Colmenares SALES
10 rows selected.
Hm, strange again, I see only 10 employees, but I have much more records in HR table
SQL> select count(*) from hr;
COUNT(*)
----------
106
SQL>
So lets check the DEPTNO form table HR and the same from table DEPT
SQL> select distinct deptno from hr;
DEPTNO
----------
100
30
20
70
90
110
50
40
80
10
60
11 rows selected.
SQL> select distinct deptno from dept;
DEPTNO
----------
30
20
40
10
SQL>
Aha, in table DEPT I have information only for few departments, not all. Here as you see I use distinct keyword to get only unique department ID.
25. And at the end complicate the select, searching for employee with salary > 10000 (from known departments) and get name of employee, name of department and location
SQL> SELECT hr.fname || ' ' || hr.lname "Employee", dept.dname "Department", dept.loc "Location" FROM hr, dept WHERE hr.deptno = dept.deptno AND sal > 10000;
Employee Department Location
------------------------------- -------------- -------------
Michael Hartstein RESEARCH DALLAS
Den Raphaely SALES CHICAGO
Here I "rename" the names of columns to make output a little bit pretty and make it easy readable
22. create new table
CREATE TABLE "ROMEO"."DEPT"
(
"DEPTNO" NUMBER(2,0),
"DNAME" VARCHAR2(14 BYTE),
"LOC" VARCHAR2(13 BYTE)
)
TABLESPACE "TEST01" ;
and fill it with data so will have name and location of departments
SQL> select * from dept;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL>
23. So lets select first name, last name of employee and name of department
SQL> SELECT hr.fname, hr.lname, dept.dname FROM hr, dept;
FNAME LNAME DNAME
--------------- --------------- --------------
Donald OConnell ACCOUNTING
Douglas Grant ACCOUNTING
Jennifer Whalen ACCOUNTING
...snip...
Kevin Feeney OPERATIONS
424 rows selected.
Hm, somethings wrong, we want to see only names of the person and name of department where he or she work. But see too many lines and very strange output. In this case we create so named Cartesian product or search. This is full combination of all rows from both tables. Lets imagine we have two tables, 1st with 100000 lines and second with 1000 lines. Cartesian search will produce 100 million of lines and we will overload the server. So be careful :)
Here I demonstrate how to use the exact column from table. The format is [Name of table].[Name of column] This help when you have columns with the same name in different tables.
24, So lets restrict the search and join both tables, mapping number of the department from table HR to the department number from table DEPT
SQL> SELECT hr.fname, hr.lname, dept.dname FROM hr, dept WHERE hr.deptno = dept.deptno;
FNAME LNAME DNAME
--------------- --------------- --------------
Jennifer Whalen ACCOUNTING
Michael Hartstein RESEARCH
Pat Fay RESEARCH
Susan Mavris OPERATIONS
Den Raphaely SALES
Alexander Khoo SALES
Shelli Baida SALES
Sigal Tobias SALES
Guy Himuro SALES
Karen Colmenares SALES
10 rows selected.
Hm, strange again, I see only 10 employees, but I have much more records in HR table
SQL> select count(*) from hr;
COUNT(*)
----------
106
SQL>
So lets check the DEPTNO form table HR and the same from table DEPT
SQL> select distinct deptno from hr;
DEPTNO
----------
100
30
20
70
90
110
50
40
80
10
60
11 rows selected.
SQL> select distinct deptno from dept;
DEPTNO
----------
30
20
40
10
SQL>
Aha, in table DEPT I have information only for few departments, not all. Here as you see I use distinct keyword to get only unique department ID.
25. And at the end complicate the select, searching for employee with salary > 10000 (from known departments) and get name of employee, name of department and location
SQL> SELECT hr.fname || ' ' || hr.lname "Employee", dept.dname "Department", dept.loc "Location" FROM hr, dept WHERE hr.deptno = dept.deptno AND sal > 10000;
Employee Department Location
------------------------------- -------------- -------------
Michael Hartstein RESEARCH DALLAS
Den Raphaely SALES CHICAGO
Here I "rename" the names of columns to make output a little bit pretty and make it easy readable
Oracle DB for system administrators, part4
15. I will use command describe to see how I defined the table hr
SQL> describe hr;
Name Null? Type
----------------------------------------- -------- ----------------------------
NOM NOT NULL NUMBER(5)
FNAME NOT NULL VARCHAR2(15)
LNAME VARCHAR2(15)
JOB VARCHAR2(10)
MGR NUMBER(5)
HIREDATE DATE
SAL NOT NULL NUMBER(7,2)
DEPTNO NOT NULL NUMBER(3)
SQL>
this give me the name of columns, null status of column (can be empty or not), type (number, char, LOB, date, etc.) and length
16. I want to examine one special table, named dual
SQL> desc dual
Name Null? Type
----------------------------------------- -------- ----------------------------
DUMMY VARCHAR2(1)
SQL>
looks very strange, but i will get system date and time using select from this table
17. get system date and time
SQL> set head off
SQL> select to_char(sysdate, 'DD-Mon-YYYY HH24:MI:SS') from dual;
18-Mar-2010 19:34:42
SQL>
Here i set do not see head (set head off) information, only data
18. lets complicate our select and get only few columns and people with salary > 10000
SQL> set head on
SQL> select nom, fname, lname, deptno, sal from hr where sal > 10000;
NOM FNAME LNAME DEPTNO SAL
---------- --------------- --------------- ---------- ----------
201 Michael Hartstein 20 13000
205 Shelley Higgins 110 12008
100 Steven King 90 24000
101 Neena Kochhar 90 17000
102 Lex De Haan 90 17000
108 Nancy Greenberg 100 12008
114 Den Raphaely 30 11000
145 John Russell 80 14000
146 Karen Partners 80 13500
147 Alberto Errazuriz 80 12000
148 Gerald Cambrault 80 11000
NOM FNAME LNAME DEPTNO SAL
---------- --------------- --------------- ---------- ----------
149 Eleni Zlotkey 80 10500
162 Clara Vishney 80 10500
168 Lisa Ozer 80 11500
174 Ellen Abel 80 11000
15 rows selected.
SQL>
19. I will resort the result by salary and want to see the bigger salary on the top
SQL> select nom, fname, lname, deptno, sal from hr where sal > 10000 order by sal desc;
NOM FNAME LNAME DEPTNO SAL
---------- --------------- --------------- ---------- ----------
100 Steven King 90 24000
101 Neena Kochhar 90 17000
102 Lex De Haan 90 17000
145 John Russell 80 14000
146 Karen Partners 80 13500
201 Michael Hartstein 20 13000
108 Nancy Greenberg 100 12008
205 Shelley Higgins 110 12008
147 Alberto Errazuriz 80 12000
168 Lisa Ozer 80 11500
174 Ellen Abel 80 11000
NOM FNAME LNAME DEPTNO SAL
---------- --------------- --------------- ---------- ----------
148 Gerald Cambrault 80 11000
114 Den Raphaely 30 11000
149 Eleni Zlotkey 80 10500
162 Clara Vishney 80 10500
15 rows selected.
SQL>
20. let me get the average salary for people, who have salary >10000
SQL> select avg(sal) from hr where sal >10000;
AVG(SAL)
----------
13334.4
SQL>
21. And let me get average salary, but by department
SQL> select to_char( avg(sal), '99999.99') , deptno from hr group by deptno;
TO_CHAR(A DEPTNO
--------- ----------
8601.33 100
4150.00 30
9500.00 20
10000.00 70
19333.33 90
10154.00 110
3475.56 50
6500.00 40
8955.88 80
4400.00 10
5760.00 60
11 rows selected.
SQL>
SQL> describe hr;
Name Null? Type
----------------------------------------- -------- ----------------------------
NOM NOT NULL NUMBER(5)
FNAME NOT NULL VARCHAR2(15)
LNAME VARCHAR2(15)
JOB VARCHAR2(10)
MGR NUMBER(5)
HIREDATE DATE
SAL NOT NULL NUMBER(7,2)
DEPTNO NOT NULL NUMBER(3)
SQL>
this give me the name of columns, null status of column (can be empty or not), type (number, char, LOB, date, etc.) and length
16. I want to examine one special table, named dual
SQL> desc dual
Name Null? Type
----------------------------------------- -------- ----------------------------
DUMMY VARCHAR2(1)
SQL>
looks very strange, but i will get system date and time using select from this table
17. get system date and time
SQL> set head off
SQL> select to_char(sysdate, 'DD-Mon-YYYY HH24:MI:SS') from dual;
18-Mar-2010 19:34:42
SQL>
Here i set do not see head (set head off) information, only data
18. lets complicate our select and get only few columns and people with salary > 10000
SQL> set head on
SQL> select nom, fname, lname, deptno, sal from hr where sal > 10000;
NOM FNAME LNAME DEPTNO SAL
---------- --------------- --------------- ---------- ----------
201 Michael Hartstein 20 13000
205 Shelley Higgins 110 12008
100 Steven King 90 24000
101 Neena Kochhar 90 17000
102 Lex De Haan 90 17000
108 Nancy Greenberg 100 12008
114 Den Raphaely 30 11000
145 John Russell 80 14000
146 Karen Partners 80 13500
147 Alberto Errazuriz 80 12000
148 Gerald Cambrault 80 11000
NOM FNAME LNAME DEPTNO SAL
---------- --------------- --------------- ---------- ----------
149 Eleni Zlotkey 80 10500
162 Clara Vishney 80 10500
168 Lisa Ozer 80 11500
174 Ellen Abel 80 11000
15 rows selected.
SQL>
19. I will resort the result by salary and want to see the bigger salary on the top
SQL> select nom, fname, lname, deptno, sal from hr where sal > 10000 order by sal desc;
NOM FNAME LNAME DEPTNO SAL
---------- --------------- --------------- ---------- ----------
100 Steven King 90 24000
101 Neena Kochhar 90 17000
102 Lex De Haan 90 17000
145 John Russell 80 14000
146 Karen Partners 80 13500
201 Michael Hartstein 20 13000
108 Nancy Greenberg 100 12008
205 Shelley Higgins 110 12008
147 Alberto Errazuriz 80 12000
168 Lisa Ozer 80 11500
174 Ellen Abel 80 11000
NOM FNAME LNAME DEPTNO SAL
---------- --------------- --------------- ---------- ----------
148 Gerald Cambrault 80 11000
114 Den Raphaely 30 11000
149 Eleni Zlotkey 80 10500
162 Clara Vishney 80 10500
15 rows selected.
SQL>
20. let me get the average salary for people, who have salary >10000
SQL> select avg(sal) from hr where sal >10000;
AVG(SAL)
----------
13334.4
SQL>
21. And let me get average salary, but by department
SQL> select to_char( avg(sal), '99999.99') , deptno from hr group by deptno;
TO_CHAR(A DEPTNO
--------- ----------
8601.33 100
4150.00 30
9500.00 20
10000.00 70
19333.33 90
10154.00 110
3475.56 50
6500.00 40
8955.88 80
4400.00 10
5760.00 60
11 rows selected.
SQL>
Oracle DB for system administrators, part3
11. Lets login as user romeo and check from other console the connection
[oracle@rh-or ~]$ sqlplus romeo/pass1234
SQL*Plus: Release 11.2.0.1.0 Production on Sun Mar 14 07:31:14 2010
Copyright (c) 1982, 2009, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL>
and check from other console the connection
SQL> select username,status, saddr from v$session where username is not null;
USERNAME STATUS SADDR
------------------------------ -------- --------
ROMEO INACTIVE 38A9DDA8
SYS ACTIVE 38A88A48
SQL>
12. Next step is to create one table.
I will make HR table (usual example) with fields:
NOM - unique identification number of employee
FNAME - his or her first name (cant be empty)
LNAME - his or her last name
JOB - job description
MGR - ID of his or her manager (see NOM)
HIREDATE - date on which this employee is hired. By default will be get system date when record is inserted
SAL - salary of employee, cant be empty
DEPTNO - number of department where employee work, cant be empty (similar to NOM)
SQL> CREATE TABLE hr (
nom NUMBER(5) PRIMARY KEY,
fname VARCHAR2(15) NOT NULL,
lname VARCHAR2(15),
job VARCHAR2(10),
mgr NUMBER(5),
hiredate DATE DEFAULT (sysdate),
sal NUMBER(7,2) NOT NULL,
deptno NUMBER(3) NOT NULL)
TABLESPACE TEST01; 2 3 4 5 6 7 8 9 10
Table created.
SQL>
and check the status of this database
SQL> select * from hr;
no rows selected
SQL>
13. The next step will be to fill this table with data
Here are possible two ways (actually many, but i try to simplify and not go indeep)
13.1. Using direct enter of data via INSERT commands
INSERT INTO HR (NOM, FNAME, LNAME, HIREDATE, JOB, SAL, MGR, DEPTNO)
VALUES (198.0, 'Donald', 'OConnell', to_date('2007-06-21', 'YYYY-MM-DD'), 'SH_CLERK', 2600.0, 124.0, 50.0);
INSERT INTO HR (NOM, FNAME, LNAME, HIREDATE, JOB, SAL, MGR, DEPTNO)
VALUES (199.0, 'Douglas', 'Grant', to_date('2008-01-13', 'YYYY-MM-DD'), 'SH_CLERK', 2600.0, 124.0, 50.0);
... snip....
but this method can be boring if you have more that 10 records.
13.2. Other way is to use SQL*Loader to create mass import of data
Here is how data looks like:
[oracle@rh-or ~]$ cat EMPLOYEES.csv
NOM,FNAME,LNAME,HIREDATE,JOB,SAL,MGR,DEPTNO
198,Donald,OConnell,2007-06-21,SH_CLERK,2600,124,50
199,Douglas,Grant,2008-01-13,SH_CLERK,2600,124,50
... snip ...
I prepare two files, one shell file to start the program
[oracle@rh-or ~]$ cat EMPLOYEES.sh
sqlldr USERID=romeo/pass1234 CONTROL=EMPLOYEES.ctl skip=1
where sqlldr is the name of the program, USERID is username and password CONTROL is the name of control file and skip is becasue i do not want to insert header ot CSV file in to the table.
This is control file
[oracle@rh-or ~]$ cat EMPLOYEES.ctl
load data
infile 'EMPLOYEES.csv' "str '\r\n'"
append
into table HR
fields terminated by ','
OPTIONALLY ENCLOSED BY '"'
trailing nullcols
( NOM CHAR(4000),
FNAME CHAR(4000),
LNAME CHAR(4000),
HIREDATE DATE "YYYY-MM-DD",
JOB CHAR(4000),
SAL CHAR(4000),
MGR CHAR(4000),
DEPTNO CHAR(4000)
)
It just define serie of commands to be executed be SQL*Loader as filename from where to get the date, name of the table where the data will be inserted, field separator, format of the date, etc.
And here is the result:
[oracle@rh-or ~]$ sh EMPLOYEES.sh
SQL*Loader: Release 11.2.0.1.0 - Production on Sun Mar 14 08:09:20 2010
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Commit point reached - logical record count 9
Commit point reached - logical record count 18
Commit point reached - logical record count 27
Commit point reached - logical record count 36
Commit point reached - logical record count 45
Commit point reached - logical record count 54
Commit point reached - logical record count 63
Commit point reached - logical record count 72
Commit point reached - logical record count 81
Commit point reached - logical record count 90
Commit point reached - logical record count 99
Commit point reached - logical record count 107
[oracle@rh-or ~]$
14. And lets check what is content of this table
SQL> select * from hr;
198 Donald OConnell SH_CLERK 124 21-JUN-07
2600 50
199 Douglas Grant SH_CLERK 124 13-JAN-08
2600 50
200 Jennifer Whalen AD_ASST 101 17-SEP-03
4400 10
REMARK: Data, used in above example is selection from sample database, provided by Oracle as part of Oracle 11g2 software
[oracle@rh-or ~]$ sqlplus romeo/pass1234
SQL*Plus: Release 11.2.0.1.0 Production on Sun Mar 14 07:31:14 2010
Copyright (c) 1982, 2009, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL>
and check from other console the connection
SQL> select username,status, saddr from v$session where username is not null;
USERNAME STATUS SADDR
------------------------------ -------- --------
ROMEO INACTIVE 38A9DDA8
SYS ACTIVE 38A88A48
SQL>
12. Next step is to create one table.
I will make HR table (usual example) with fields:
NOM - unique identification number of employee
FNAME - his or her first name (cant be empty)
LNAME - his or her last name
JOB - job description
MGR - ID of his or her manager (see NOM)
HIREDATE - date on which this employee is hired. By default will be get system date when record is inserted
SAL - salary of employee, cant be empty
DEPTNO - number of department where employee work, cant be empty (similar to NOM)
SQL> CREATE TABLE hr (
nom NUMBER(5) PRIMARY KEY,
fname VARCHAR2(15) NOT NULL,
lname VARCHAR2(15),
job VARCHAR2(10),
mgr NUMBER(5),
hiredate DATE DEFAULT (sysdate),
sal NUMBER(7,2) NOT NULL,
deptno NUMBER(3) NOT NULL)
TABLESPACE TEST01; 2 3 4 5 6 7 8 9 10
Table created.
SQL>
and check the status of this database
SQL> select * from hr;
no rows selected
SQL>
13. The next step will be to fill this table with data
Here are possible two ways (actually many, but i try to simplify and not go indeep)
13.1. Using direct enter of data via INSERT commands
INSERT INTO HR (NOM, FNAME, LNAME, HIREDATE, JOB, SAL, MGR, DEPTNO)
VALUES (198.0, 'Donald', 'OConnell', to_date('2007-06-21', 'YYYY-MM-DD'), 'SH_CLERK', 2600.0, 124.0, 50.0);
INSERT INTO HR (NOM, FNAME, LNAME, HIREDATE, JOB, SAL, MGR, DEPTNO)
VALUES (199.0, 'Douglas', 'Grant', to_date('2008-01-13', 'YYYY-MM-DD'), 'SH_CLERK', 2600.0, 124.0, 50.0);
... snip....
but this method can be boring if you have more that 10 records.
13.2. Other way is to use SQL*Loader to create mass import of data
Here is how data looks like:
[oracle@rh-or ~]$ cat EMPLOYEES.csv
NOM,FNAME,LNAME,HIREDATE,JOB,SAL,MGR,DEPTNO
198,Donald,OConnell,2007-06-21,SH_CLERK,2600,124,50
199,Douglas,Grant,2008-01-13,SH_CLERK,2600,124,50
... snip ...
I prepare two files, one shell file to start the program
[oracle@rh-or ~]$ cat EMPLOYEES.sh
sqlldr USERID=romeo/pass1234 CONTROL=EMPLOYEES.ctl skip=1
where sqlldr is the name of the program, USERID is username and password CONTROL is the name of control file and skip is becasue i do not want to insert header ot CSV file in to the table.
This is control file
[oracle@rh-or ~]$ cat EMPLOYEES.ctl
load data
infile 'EMPLOYEES.csv' "str '\r\n'"
append
into table HR
fields terminated by ','
OPTIONALLY ENCLOSED BY '"'
trailing nullcols
( NOM CHAR(4000),
FNAME CHAR(4000),
LNAME CHAR(4000),
HIREDATE DATE "YYYY-MM-DD",
JOB CHAR(4000),
SAL CHAR(4000),
MGR CHAR(4000),
DEPTNO CHAR(4000)
)
It just define serie of commands to be executed be SQL*Loader as filename from where to get the date, name of the table where the data will be inserted, field separator, format of the date, etc.
And here is the result:
[oracle@rh-or ~]$ sh EMPLOYEES.sh
SQL*Loader: Release 11.2.0.1.0 - Production on Sun Mar 14 08:09:20 2010
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Commit point reached - logical record count 9
Commit point reached - logical record count 18
Commit point reached - logical record count 27
Commit point reached - logical record count 36
Commit point reached - logical record count 45
Commit point reached - logical record count 54
Commit point reached - logical record count 63
Commit point reached - logical record count 72
Commit point reached - logical record count 81
Commit point reached - logical record count 90
Commit point reached - logical record count 99
Commit point reached - logical record count 107
[oracle@rh-or ~]$
14. And lets check what is content of this table
SQL> select * from hr;
198 Donald OConnell SH_CLERK 124 21-JUN-07
2600 50
199 Douglas Grant SH_CLERK 124 13-JAN-08
2600 50
200 Jennifer Whalen AD_ASST 101 17-SEP-03
4400 10
REMARK: Data, used in above example is selection from sample database, provided by Oracle as part of Oracle 11g2 software
Oracle DB for system administrators, part2
5. lets login and see the list of tablespaces
SQL> select * from v$tablespace;
TS# NAME INC BIG FLA ENC
---------- ------------------------------ --- --- --- ---
0 SYSTEM YES NO YES
1 SYSAUX YES NO YES
2 UNDOTBS1 YES NO YES
4 USERS YES NO YES
3 TEMP NO NO YES
6 EXAMPLE YES NO YES
6 rows selected.
SQL>
6. Next we will add new tablespace for tests
SQL> create tablespace test01 datafile '/home/oracle/base/data/orcl/test01.dbf' size 500M extent management local;
Tablespace created.
SQL>
7. And check if its created
SQL> select * from v$tablespace where name = 'TEST01';
TS# NAME INC BIG FLA ENC
---------- ------------------------------ --- --- --- ---
8 TEST01 YES NO YES
SQL>
8. Lets create user
SQL> create user romeo profile default identified by pass1234 default tablespace TEST01 ;
User created.
SQL>
The user is named romeo, have password pass1234 and default tablespace test01
9. And unlock the user
SQL> alter user romeo account unlock;
User altered.
SQL>
10. give him/her rights to connect and other common privileges
SQL> grant resource, connect to romeo;
Grant succeeded.
SQL>
P.S. For detailed explanation of terminology and concept of Oracle database please consult appropriate documentation
SQL> select * from v$tablespace;
TS# NAME INC BIG FLA ENC
---------- ------------------------------ --- --- --- ---
0 SYSTEM YES NO YES
1 SYSAUX YES NO YES
2 UNDOTBS1 YES NO YES
4 USERS YES NO YES
3 TEMP NO NO YES
6 EXAMPLE YES NO YES
6 rows selected.
SQL>
6. Next we will add new tablespace for tests
SQL> create tablespace test01 datafile '/home/oracle/base/data/orcl/test01.dbf' size 500M extent management local;
Tablespace created.
SQL>
7. And check if its created
SQL> select * from v$tablespace where name = 'TEST01';
TS# NAME INC BIG FLA ENC
---------- ------------------------------ --- --- --- ---
8 TEST01 YES NO YES
SQL>
8. Lets create user
SQL> create user romeo profile default identified by pass1234 default tablespace TEST01 ;
User created.
SQL>
The user is named romeo, have password pass1234 and default tablespace test01
9. And unlock the user
SQL> alter user romeo account unlock;
User altered.
SQL>
10. give him/her rights to connect and other common privileges
SQL> grant resource, connect to romeo;
Grant succeeded.
SQL>
P.S. For detailed explanation of terminology and concept of Oracle database please consult appropriate documentation
Oracle DB for system administrators, part1
This serie of posts is intended to give kickstart overview on oracle database for system administrators. For more deep knowledge please consult oracle documentation Here I will use only command line utilities (much elegant for automation). If you prefer you can use many other tools like OEM, Toad, SQL Developer, etc.
1. Let start the database I asume you are login as oracle user, or any other user, member of DBA group
1.1 First start listener
[oracle@rh-or ~]$ lsnrctl start
LSNRCTL for Linux: Version 11.2.0.1.0 - Production on 07-MAR-2010 13:05:50 Copyright (c) 1991, 2009, Oracle. All rights reserved. Starting /home/oracle/11g2/bin/tnslsnr: please wait... TNSLSNR for Linux: Version 11.2.0.1.0 - Production System parameter file is /home/oracle/11g2/network/admin/listener.ora Log messages written to /home/oracle/base/diag/tnslsnr/rh-or/listener/alert/log.xml Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521))) Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=rh-or)(PORT=1521))) Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521))) STATUS of the LISTENER ------------------------ Alias LISTENER Version TNSLSNR for Linux: Version 11.2.0.1.0 - Production Start Date 07-MAR-2010 13:05:50 Uptime 0 days 0 hr. 0 min. 2 sec Trace Level off Security ON: Local OS Authentication SNMP OFF Listener Parameter File /home/oracle/11g2/network/admin/listener.ora Listener Log File /home/oracle/base/diag/tnslsnr/rh-or/listener/alert/log.xml Listening Endpoints Summary... (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521))) (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=rh-or)(PORT=1521))) The listener supports no services The command completed successfully
1.2 Then start the database itself
[oracle@rh-or ~]$ sqlplus / as sysdba
SQL*Plus: Release 11.2.0.1.0 Production on Sun Mar 7 13:06:37 2010 Copyright (c) 1982, 2009, Oracle. All rights reserved. Connected to an idle instance.
SQL> startup
ORACLE instance started. Total System Global Area 422670336 bytes Fixed Size 1336960 bytes Variable Size 318769536 bytes Database Buffers 96468992 bytes Redo Buffers 6094848 bytes Database mounted. Database opened.
SQL>
2. Check if database and listener are run
[oracle@rh-or ~]$ ps -efl|grep lsnr
0 S oracle 10324 1 0 75 0 - 10527 stext 13:05 ? 00:00:00 /home/oracle/11g2/bin/tnslsnr LISTENER -inherit
0 R oracle 10473 3892 0 79 0 - 428 - 13:07 pts/0 00:00:00 grep lsnr
[oracle@rh-or ~]$ ps -efl|grep ora_
0 S oracle 10376 1 0 75 0 - 142554 - 13:06 ? 00:00:00 ora_pmon_orcl
0 S oracle 10378 1 0 58 - - 142388 - 13:06 ? 00:00:00 ora_vktm_orcl
0 S oracle 10382 1 0 75 0 - 142388 - 13:06 ? 00:00:00 ora_gen0_orcl
0 S oracle 10384 1 0 78 0 - 142388 - 13:06 ? 00:00:00 ora_diag_orcl
0 S oracle 10386 1 0 75 0 - 142390 - 13:06 ? 00:00:00 ora_dbrm_orcl
0 S oracle 10388 1 0 75 0 - 142388 - 13:06 ? 00:00:00 ora_psp0_orcl
0 S oracle 10390 1 0 78 0 - 142516 - 13:06 ? 00:00:00 ora_dia0_orcl
0 S oracle 10392 1 0 78 0 - 142388 - 13:06 ? 00:00:00 ora_mman_orcl
0 S oracle 10394 1 0 75 0 - 143363 - 13:06 ? 00:00:00 ora_dbw0_orcl
0 S oracle 10396 1 0 75 0 - 146276 - 13:06 ? 00:00:00 ora_lgwr_orcl
0 S oracle 10398 1 0 76 0 - 142388 - 13:06 ? 00:00:00 ora_ckpt_orcl
0 S oracle 10400 1 0 75 0 - 142395 - 13:06 ? 00:00:00 ora_smon_orcl
0 S oracle 10402 1 0 75 0 - 142389 - 13:06 ? 00:00:00 ora_reco_orcl
3. Lets try to login to database
[oracle@rh-or ~]$ sqlplus user/password@SID
SQL*Plus: Release 11.2.0.1.0 Production on Sun Mar 7 13:01:43 2010 Copyright (c) 1982, 2009, Oracle. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL>
where user is the username you want to login, password is the password for this user and SID is the the SID identifier of this instance of Oracle database. SID can be name of the SID, hostname or IP address. Above we are login on different way which is possible only if you are login on the same host as database and you are user Oracle DB start 4. Lets make our first retrieve of information from database
SQL> select username,user_id from dba_users;
USERNAME USER_ID ------------------------------ ---------- SYSTEM 5 SYS 0 MGMT_VIEW 74 DBSNMP 30 SYSMAN 72 OUTLN 9 OLAPSYS 61 SI_INFORMTN_SCHEMA 56
Here we select columns username and user_id from table of users, defined in database, named dba_users
1. Let start the database I asume you are login as oracle user, or any other user, member of DBA group
1.1 First start listener
[oracle@rh-or ~]$ lsnrctl start
LSNRCTL for Linux: Version 11.2.0.1.0 - Production on 07-MAR-2010 13:05:50 Copyright (c) 1991, 2009, Oracle. All rights reserved. Starting /home/oracle/11g2/bin/tnslsnr: please wait... TNSLSNR for Linux: Version 11.2.0.1.0 - Production System parameter file is /home/oracle/11g2/network/admin/listener.ora Log messages written to /home/oracle/base/diag/tnslsnr/rh-or/listener/alert/log.xml Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521))) Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=rh-or)(PORT=1521))) Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521))) STATUS of the LISTENER ------------------------ Alias LISTENER Version TNSLSNR for Linux: Version 11.2.0.1.0 - Production Start Date 07-MAR-2010 13:05:50 Uptime 0 days 0 hr. 0 min. 2 sec Trace Level off Security ON: Local OS Authentication SNMP OFF Listener Parameter File /home/oracle/11g2/network/admin/listener.ora Listener Log File /home/oracle/base/diag/tnslsnr/rh-or/listener/alert/log.xml Listening Endpoints Summary... (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521))) (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=rh-or)(PORT=1521))) The listener supports no services The command completed successfully
1.2 Then start the database itself
[oracle@rh-or ~]$ sqlplus / as sysdba
SQL*Plus: Release 11.2.0.1.0 Production on Sun Mar 7 13:06:37 2010 Copyright (c) 1982, 2009, Oracle. All rights reserved. Connected to an idle instance.
SQL> startup
ORACLE instance started. Total System Global Area 422670336 bytes Fixed Size 1336960 bytes Variable Size 318769536 bytes Database Buffers 96468992 bytes Redo Buffers 6094848 bytes Database mounted. Database opened.
SQL>
2. Check if database and listener are run
[oracle@rh-or ~]$ ps -efl|grep lsnr
0 S oracle 10324 1 0 75 0 - 10527 stext 13:05 ? 00:00:00 /home/oracle/11g2/bin/tnslsnr LISTENER -inherit
0 R oracle 10473 3892 0 79 0 - 428 - 13:07 pts/0 00:00:00 grep lsnr
[oracle@rh-or ~]$ ps -efl|grep ora_
0 S oracle 10376 1 0 75 0 - 142554 - 13:06 ? 00:00:00 ora_pmon_orcl
0 S oracle 10378 1 0 58 - - 142388 - 13:06 ? 00:00:00 ora_vktm_orcl
0 S oracle 10382 1 0 75 0 - 142388 - 13:06 ? 00:00:00 ora_gen0_orcl
0 S oracle 10384 1 0 78 0 - 142388 - 13:06 ? 00:00:00 ora_diag_orcl
0 S oracle 10386 1 0 75 0 - 142390 - 13:06 ? 00:00:00 ora_dbrm_orcl
0 S oracle 10388 1 0 75 0 - 142388 - 13:06 ? 00:00:00 ora_psp0_orcl
0 S oracle 10390 1 0 78 0 - 142516 - 13:06 ? 00:00:00 ora_dia0_orcl
0 S oracle 10392 1 0 78 0 - 142388 - 13:06 ? 00:00:00 ora_mman_orcl
0 S oracle 10394 1 0 75 0 - 143363 - 13:06 ? 00:00:00 ora_dbw0_orcl
0 S oracle 10396 1 0 75 0 - 146276 - 13:06 ? 00:00:00 ora_lgwr_orcl
0 S oracle 10398 1 0 76 0 - 142388 - 13:06 ? 00:00:00 ora_ckpt_orcl
0 S oracle 10400 1 0 75 0 - 142395 - 13:06 ? 00:00:00 ora_smon_orcl
0 S oracle 10402 1 0 75 0 - 142389 - 13:06 ? 00:00:00 ora_reco_orcl
3. Lets try to login to database
[oracle@rh-or ~]$ sqlplus user/password@SID
SQL*Plus: Release 11.2.0.1.0 Production on Sun Mar 7 13:01:43 2010 Copyright (c) 1982, 2009, Oracle. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL>
where user is the username you want to login, password is the password for this user and SID is the the SID identifier of this instance of Oracle database. SID can be name of the SID, hostname or IP address. Above we are login on different way which is possible only if you are login on the same host as database and you are user Oracle DB start 4. Lets make our first retrieve of information from database
SQL> select username,user_id from dba_users;
USERNAME USER_ID ------------------------------ ---------- SYSTEM 5 SYS 0 MGMT_VIEW 74 DBSNMP 30 SYSMAN 72 OUTLN 9 OLAPSYS 61 SI_INFORMTN_SCHEMA 56
Here we select columns username and user_id from table of users, defined in database, named dba_users
Subscribe to:
Posts (Atom)
Compressed tar archive
There are some cases when you want to create compressed tar archive but you do not have enough disk space to keep original files and tar arc...
-
To build firewall under AIX is sample, but as each host based firewall should be done careful 1. Prerequisites To start firewall in AIX yo...
-
4. Its time for some system administrator tasks. Oracle ASM need special mark of disks will work with 4.1. Because of some reason (i don...
-
There are some cases when you want to create compressed tar archive but you do not have enough disk space to keep original files and tar arc...