Tag Archives: SQL

Currently executing SQL in Oracle database

I was just asked by a junior administrator, how to determine what SQL is currently executing against her database. While this may seem a trivial task for those in the industry for some time, I thought it a very good question. The below SQL will display currently executing SQL within an Oracle RDBMS.

1. Logon to SQL*PLUS with dba privileges.

2. Execute the following SQL block against the v$sql and v$session tables. NOTE: in a grid environment, use the gv$ views.

select sql_text from v$sql where sql_id in
(select sql_id from v$session where status=’ACTIVE’);

3. Displayed results show currently executing SQL blocks.

SQL> select sql_text from v$sql where sql_id in
2 (select sql_id from v$session where status=’ACTIVE’);

SQL_TEXT
——————————————————————————–
select sql_text from v$sql where sql_id in (select sql_id from v$session where s
tatus=’ACTIVE’)

Larry Catt, OCP

Execution of Oracle SQL commands from within UNIX or LINUX shell scripts:

In the management of Oracle RDBMS, we frequently have the need to develop shell scripts to manage our databases. This article demonstrates the use of BASH shell script to connect to an Oracle database and execute PL/SQL and SQL statements from within the Oracle database. The following procedure will work on UNIX and LINUX machines.

1. Logon to your Oracle database server as the Oracle software owner.

2. Use vi to create a new file with the name sql_shell_test.sh

mylinux:> vi sql_shell_test.sh
“sql_shell_test.sh” [New file]

~
~

3. Press the ‘a’ key once (for append operations) and past the following text into your file.

sqlplus ‘/ as sysdba’ <

4. Press the keys : –> w –> q and hit the return key to save and exit vi.

5. Execute the chmod command to change you file status to read_write_execute for owner and group

mylinux:> chmod 770 sql_shell_test.sh
mylinux:>

6. As the Oracle software owner, execute the shell script sql_shell_test.sh with the following command.

mylinux:>./sql_shell_test.sh

7. Perform an ls command and you can see that the script has generated the output file test_shell_script_output.lst.

mylinux:>ls -lrt
-rwxrwxrwx 1 oracle dba 148 May 13 03:30 sql_shell_test.sql
-rw-r–r– 1 oracle dba 1391 May 13 03:32 test_shell_script_output.lst
mylinux:>

8. Perform a cat command to see the output of file test_shell_script_output.lst.

mylinux:>cat test_shell_script_output.lst
SQL> select * from v$instance;

INSTANCE_NUMBER INSTANCE_NAME
————— —————-
HOST_NAME
—————————————————————-
VERSION STARTUP_T STATUS PAR THREAD# ARCHIVE LOG_SWITCH_WAIT
—————– ——— ———— — ———- ——- —————
LOGINS SHU DATABASE_STATUS INSTANCE_ROLE ACTIVE_ST BLO
———- — —————– —————— ——— —
1 orcl
frankie
10.2.0.4.0 13-MAY-10 OPEN NO 1 STOPPED
ALLOWED NO ACTIVE PRIMARY_INSTANCE NORMAL NO

SQL> select name, open_mode from v$database;

NAME OPEN_MODE
——— ———-
ORCL READ WRITE

SQL> spool off
mylinux:>

This concludes the execution of Oracle SQL commands from within UNIX or LINUX shell scripts.

Larry J. Catt, OCP 9i, 10g
oracle@allcompute.com
www.allcompute.com

Oracle – Currently executing long SQL operations.

The Oracle RDBMS provides multiple views detailing the current activities within the database, which can be used to perform analysis on performance. This article covers the user of the views: V$SQL, V$SESSION_LONGOPS, and V$SESSION to determine the longest currently occurring SQL statements within our database and who is executing them. This procedure will work on any OS.

1. Logon to you Oracle database server.

2. Logon to SQLPLUS with sysdba privileges.


mylinux:> sqlplus ‘/ as sysdba’

SQL*Plus: Release 10.2.0.4.0 – Production on Sat Dec 26 08:08:39 2009

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 – 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>

3. Execute the following SQL statement.


select b.username, b.SID, b.SERIAL#, c.totalwork||’ ‘||c.units,
c.time_remaining, a.sql_text from v$sql a,
v$session b,
v$session_longops c
where a.address=b.sql_address
and b.status=’ACTIVE’
and b.SID||b.SERIAL#=c.SID||c.SERIAL#
and c.time_remaining>0 and b.username<>‘SYS’

4. The returned values are as follows:


USERNAME – User executing this statement.
SID – System ID of session executing.
SERIAL# – SERIAL# of session executing.
TOTALWORK+UNITS – Total Work and units of measure of work.
TIME_REMAINING – Estimate in seconds of time remaining.
SQL_TEXT – SQL being executed.

5. This information can be used to determine current performance and possible performance problems.

Larry J. Catt, OCP 9i, 10g
oracle@allcompute.com
www.allcompute.com

Recreate Oracle Roles

Oracle uses Roles to define the privileges and rights a user has in an Oracle database. By defining a Role with specific system and object privileges, we greatly reduce the complexity of creating a new user account within any system. This is accomplished by assigning all specific rights to a single Role then granting that Role to a new user, instead of granting all the rights individually to each new account. In this article we will review a script which will regenerate the DDL to recreate a specific role or just view the privileges which that role contains.

1. Connect to your Oracle database server and logon to SQL*PLUS.

MyLinux:>sqlplus ‘\ as sysdba’
SQL*Plus: Release 10.2.0.4.0 – Production on Tue Aug 05 17:42:43 2009

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 – 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL>

2. Create the role VIEW_ALL_SCOTT to demonstrate the generation of DDL.

Create role VIEW_ALL_SCOTT identified by password;
Grant connect to VIEW_ALL_SCOTT;
Grant create session to VIEW_ALL_SCOTT;
Grant select on scott.DEPT to VIEW_ALL_SCOTT;
Grant select on scott.EMP to VIEW_ALL_SCOTT;
Grant select on scott.BONUS to VIEW_ALL_SCOTT;
Grant select on scott.SALGRADE to VIEW_ALL_SCOTT;

3. Execute the following PL/SQL block to regenerate the DDL of the role VIEW_ALL_SCOTT.

set serveroutput on
spool ./create_role.sql

declare

v_role varchar2(30):= ‘VIEW_ALL_SCOTT’;
v_ct number;

begin

— Create original role definition

dbms_output.put_line(‘create role ‘||v_role||’ identified by
‘||v_role||’;’);

— Grant all roles defined for the role.

for role in(select * from dba_role_privs where grantee=v_role)
loop
if role.admin_option = ‘YES’
then
dbms_output.put_line(‘grant ‘||role.granted_role||’ to ‘||role.grantee||’ with
admin option’||’;’);
else
dbms_output.put_line(‘grant ‘||role.granted_role||’ to ‘||role.grantee||’;’);
end if;
end loop;

— Grant all system privileges for the role.

for sys_priv in(select * from dba_sys_privs where grantee=v_role)
loop
if sys_priv.admin_option = ‘YES’
then
dbms_output.put_line(‘grant ‘||sys_priv.privilege||’ to ‘||sys_priv.grantee||’
with admin option’||’;’);
else
dbms_output.put_line(‘grant ‘||sys_priv.privilege||’ to
‘||sys_priv.grantee||’;’);
end if;
end loop;

— Grant all object privileges for the role.

for tab_priv in(select * from dba_tab_privs where grantee=v_role)
loop
if tab_priv.grantable = ‘YES’
then
dbms_output.put_line(‘grant ‘||tab_priv.privilege||’ on
‘||tab_priv.owner||’.’||tab_priv.table_name||’ to ‘||tab_priv.grantee||’ with
grant option;’);
else
dbms_output.put_line(‘grant ‘||tab_priv.privilege||’ on
‘||tab_priv.owner||’.’||tab_priv.table_name||’ to ‘||tab_priv.grantee||’;’);
end if;
end loop;
end;
/

SQL> spool ./create_role.sql
SQL>
SQL> declare
2
3 v_role varchar2(30):= ‘VIEW_ALL_SCOTT’;
4 v_ct number;
5
6 begin
7
8 — Create original role definition
9
10 dbms_output.put_line(‘create role ‘||v_role||’ identified by
11 ‘||v_role||’;’);
12
13
14
15 — Grant all roles defined for the role.
16
17 for role in(select * from dba_role_privs where grantee=v_role)
18 loop
19 if role.admin_option = ‘YES’
20 then
21 dbms_output.put_line(‘grant ‘||role.granted_role||’ to ‘||role.grantee||’ w
ith
22 admin option’||’;’);
23 else
24 dbms_output.put_line(‘grant ‘||role.granted_role||’ to ‘||role.grantee||’;’
);
25 end if;
26 end loop;
27
28
29 — Grant all system privileges for the role.
30
31 for sys_priv in(select * from dba_sys_privs where grantee=v_role)
32 loop
33 if sys_priv.admin_option = ‘YES’
34 then
35 dbms_output.put_line(‘grant ‘||sys_priv.privilege||’ to ‘||sys_priv.grantee
||’
36 with admin option’||’;’);
37 else
38 dbms_output.put_line(‘grant ‘||sys_priv.privilege||’ to
39 ‘||sys_priv.grantee||’;’);
40 end if;
41 end loop;
42
43 — Grant all object privileges for the role.
44
45 for tab_priv in(select * from dba_tab_privs where grantee=v_role)
46 loop
47 if tab_priv.grantable = ‘YES’
48 then
49 dbms_output.put_line(‘grant ‘||tab_priv.privilege||’ on
50 ‘||tab_priv.owner||’.’||tab_priv.table_name||’ to ‘||tab_priv.grantee||’ w
ith
51 grant option;’);
52 else
53 dbms_output.put_line(‘grant ‘||tab_priv.privilege||’ on
54 ‘||tab_priv.owner||’.’||tab_priv.table_name||’ to ‘||tab_priv.grantee||’;’)
;
55 end if;
56 end loop;
57 end;
58 /
create role VIEW_ALL_SCOTT identified by VIEW_ALL_SCOTT;
grant CONNECT to VIEW_ALL_SCOTT;
grant CREATE SESSION to VIEW_ALL_SCOTT;
grant SELECT on SCOTT.DEPT to VIEW_ALL_SCOTT;
grant SELECT on SCOTT.EMP to VIEW_ALL_SCOTT;
grant SELECT on SCOTT.BONUS to VIEW_ALL_SCOTT;
grant SELECT on SCOTT.SALGRADE to VIEW_ALL_SCOTT;

PL/SQL procedure successfully completed.

SQL>

4. Now you can use the DDL generated to recreate the role in another database or examine the DDL to find the specific rights a user will receive once they are granted the role.

Larry J. Catt, OCP 9i, 10g
oracle@allcompute.com
www.allcompute.com

Recreate Oracle RDBMS User accounts

With the advent of Oracle 10g Import and Export data pump utility, the need to recreate a user account from scratch has been greatly reduced. However, there are still situation when you may need the SQL to recreate a specific user within another Oracle environment or just desire to see the creation statements. The script below will generate the statements to create the user defined in the CURR variable from the current Oracle RDBMS environment.

1. First we will create a user named LJCATT with various roles and privileges.

SQL> create user LJCATT identified by LJCATT;
User created.
SQL> alter user LJCATT default tablespace USERS;
User altered.
SQL> alter user LJCATT temporary tablespace TEMP;
User altered.
SQL> alter user LJCATT profile DEFAULT;
User altered.
SQL> grant DBA to LJCATT;
Grant succeeded.
SQL> grant CREATE TABLE to LJCATT with admin option;
Grant succeeded.
SQL> grant UNLIMITED TABLESPACE to LJCATT;
Grant succeeded.
SQL> grant EXECUTE on SYS.UTL_FILE to LJCATT with grant option;
Grant succeeded.
SQL>

2. Now we will execute the following PL/SQL block to regenerate the statements to recreate the user from the data dictionary.

set serveroutput on
spool ./create_user_account.sql

declare

curr varchar2(30):= ‘LJCATT’;
v_ext varchar2(3);

begin

— Create original user definition
for user in(select * from dba_users where username = curr)
loop
dbms_output.put_line(‘create user ‘||user.username||’ identified by
‘||user.username||’;’);
dbms_output.put_line(‘alter user ‘||user.username||’ default tablespace
‘||user.default_tablespace||’;’);
dbms_output.put_line(‘alter user ‘||user.username||’ temporary tablespace
‘||user.temporary_tablespace||’;’);
dbms_output.put_line(‘alter user ‘||user.username||’ profile
‘||user.profile||’;’);
if user.account_status<>‘OPEN’
then
dbms_output.put_line(‘alter user ‘||user.username||’ account lock;’);
end if;
end loop;

— Grant all roles defined for the user.

for role in(select * from dba_role_privs where grantee=curr)
loop
if role.admin_option = ‘YES’
then
dbms_output.put_line(‘grant ‘||role.granted_role||’ to ‘||role.grantee||’ with
admin option’||’;’);
else
dbms_output.put_line(‘grant ‘||role.granted_role||’ to ‘||role.grantee||’;’);
end if;
end loop;

— Grant all system privileges for the user.

for sys_priv in(select * from dba_sys_privs where grantee=curr)
loop
if sys_priv.admin_option = ‘YES’
then
dbms_output.put_line(‘grant ‘||sys_priv.privilege||’ to ‘||sys_priv.grantee||’
with admin option’||’;’);
else
dbms_output.put_line(‘grant ‘||sys_priv.privilege||’ to
‘||sys_priv.grantee||’;’);
end if;
end loop;

— Grant all object privileges for the user.

for tab_priv in(select * from dba_tab_privs where grantee=curr)
loop
if tab_priv.grantable = ‘YES’
then
dbms_output.put_line(‘grant ‘||tab_priv.privilege||’ on
‘||tab_priv.owner||’.’||tab_priv.table_name||’ to ‘||tab_priv.grantee||’ with
grant option;’);
else
dbms_output.put_line(‘grant ‘||tab_priv.privilege||’ on
‘||tab_priv.owner||’.’||tab_priv.table_name||’ to ‘||tab_priv.grantee||’;’);
end if;
end loop;
end;
/

spool off

Sample Output results:

47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
create user LJCATT identified by LJCATT;
alter user LJCATT default tablespace USERS;
alter user LJCATT temporary tablespace TEMP;
alter user LJCATT profile DEFAULT;
grant DBA to LJCATT;
grant CREATE TABLE to LJCATT with admin option;
grant UNLIMITED TABLESPACE to LJCATT;
grant EXECUTE on SYS.UTL_FILE to LJCATT with grant option;

PL/SQL procedure successfully completed.

SQL>

3. The above SQL statements can now be used against any other Oracle database to recreate the user account with the same rights which exist in this database. NOTE: There exist several dependencies in the above statements, such as: tablespaces, profiles, roles, and object privileges. For example, we need to take care that a default tablespace defined in the alter user statement truly exist in the destination database.

Larry J Catt, OCP 9i, 10g
oracle@allcompute.com
www.allcompute.com

Gathering SQL statements in Oracle 10g

Oracle 10g allows for increase amount of information to be extracted about SQL statements executed against the database since last instance startup. In Oracle 10g we have the new V$BIND_VALUE_CAPTURE, which allows you see the bind variables attached to most SQL statements executed in the database. Additionally, the view V$SQL has several improvements over it’s 9i counterpart to include: Full contents of the SQL statement; last execution time in date format; and actually username of parsing user. This article will cover how to extract previously and currently executed SQL statements with a few different definable variables from you Oracle 10g database.

1. Logon to your Oracle 10g database as sysdba.

MyLinux:>sqlplus ‘/ as sysdba’
SQL*Plus: Release 10.2.0.4.0 – Production on Tue Aug 16 13:30:13 2009

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 – 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>

2. To extract all SQL executed since the last system startup, execute the following PL/SQL block. NOTE: This may contain a lot of information, so you should spool the contents of this execution to an OS layer file with the command: spool ./

/********************
// Larry Catt
// 15 AUG 2009
// All SQL since instance startup.
//
// 10g version
/***********************/

set serveroutput on size 1000000

declare
v_ct number;
v_bind varchar2(4000);
begin

for v_sql in(select sql_id, PARSING_SCHEMA_NAME, SQL_TEXT,
to_char(LAST_ACTIVE_TIME, ‘DD-MON-YYYY HH:MI:SS’) as v_time
from v$sql order by LAST_ACTIVE_TIME)
loop

dbms_output.put_line(‘##########################’);
dbms_output.put_line(‘#’);
dbms_output.put_line(v_sql.parsing_schema_name);
dbms_output.put_line(v_sql.sql_text);
dbms_output.put_line(v_sql.v_time);

for v_b in(select VALUE_STRING from V$SQL_BIND_CAPTURE where sql_id=v_sql.sql_id
order by position)
loop

dbms_output.put_line(v_b.value_string);

end loop;
end loop;
end;
/

3. The following PL/SQL block will give you all the SQL for a particular user defined by the variable V_USER.

/********************
// Larry Catt
// 15 AUG 2009
// ALL SQL from a particular user defined as the variable V_USER.
//
// 10g version
/***********************/

set serveroutput on size 1000000
declare
v_ct number;
v_bind varchar2(4000);
v_user varchar2(30):=’SYS’;

begin

for v_sql in(select sql_id, PARSING_SCHEMA_NAME, SQL_TEXT,
to_char(LAST_ACTIVE_TIME, ‘DD-MON-YYYY HH:MI:SS’) as v_time
from v$sql where parsing_schema_name= v_user order by LAST_ACTIVE_TIME)
loop

dbms_output.put_line(‘##########################’);
dbms_output.put_line(‘#’);
dbms_output.put_line(v_sql.parsing_schema_name);
dbms_output.put_line(v_sql.sql_text);
dbms_output.put_line(v_sql.v_time);

for v_b in(select VALUE_STRING from V$SQL_BIND_CAPTURE where sql_id=v_sql.sql_id
order by position)
loop

dbms_output.put_line(v_b.value_string);
end loop;
end loop;
end;
/

4. The following PL/SQL block will give you all the SQL statements executed during the time range of variables V_START_TIME and V_END_TIME.

/********************
// Larry Catt
// 15 Aug 2009
// All SQL statements executed between the times V_START_TIME and V_END_TIME.
//
// 10g version
/***********************/

set serveroutput on size 1000000

declare

v_ct number;
v_bind varchar2(4000);
v_start_time date := to_date(’15-AUG-2009 13:15:00′,’DD-MON-YYYY HH24:MI:SS’);
v_end_time date:=to_date(’15-AUG-2009 15:15:00′,’DD-MON-YYYY HH24:MI:SS’);

begin

for v_sql in(select sql_id, PARSING_SCHEMA_NAME, SQL_TEXT,
to_char(LAST_ACTIVE_TIME, ‘DD-MON-YYYY HH:MI:SS’) as v_time
from v$sql where LAST_ACTIVE_TIME between v_start_time and
v_end_time order by LAST_ACTIVE_TIME)
loop

dbms_output.put_line(‘##########################’);
dbms_output.put_line(‘#’);
dbms_output.put_line(v_sql.parsing_schema_name);
dbms_output.put_line(v_sql.sql_text);
dbms_output.put_line(v_sql.v_time);

for v_b in(select VALUE_STRING from V$SQL_BIND_CAPTURE where sql_id=v_sql.sql_id
order by position)
loop

dbms_output.put_line(v_b.value_string);

end loop;
end loop;
end;
/

5. The following PL/SQL block will give you all the SQL statements currently being executed in the system.

/********************
// Larry Catt
// 15 Aug 2009
// All SQL statements currently executing.
//
// 10g version
/***********************/

set serveroutput on size 1000000

declare

v_ct number;
v_bind varchar2(4000);

begin

for v_sql in(select sql_id, PARSING_SCHEMA_NAME, SQL_TEXT,
to_char(LAST_ACTIVE_TIME, ‘DD-MON-YYYY HH:MI:SS’) as v_time
from v$sql where address in
(select sql_address from v$session where status=’ACTIVE’) order by
LAST_ACTIVE_TIME)
loop

dbms_output.put_line(‘##########################’);
dbms_output.put_line(‘#’);
dbms_output.put_line(v_sql.parsing_schema_name);
dbms_output.put_line(v_sql.sql_text);
dbms_output.put_line(v_sql.v_time);

for v_b in(select VALUE_STRING from V$SQL_BIND_CAPTURE where sql_id=v_sql.sql_id
order by position)
loop

dbms_output.put_line(v_b.value_string);

end loop;
end loop;
end;
/

6. This completes extraction of Oracle SQL statements in Oracle 10g.

Larry J Catt, OCP 9i, 10g
oracle@allcompute.com
www.allcompute.com

Gathering SQL statements in Oracle 9i

Oracle 9i provides a way of gathering previously executed SQL in a system when tracing was not enabled. This feature is possible through the system view V$SQL, while not as robust as the newer Oracle releases, it still provides the DBA with the ability to view the exact user activities which are occurring in the database. Viewing previously executed statements during and after a system slowdown is highly valuable in determining the cause of certain system problems. In this article we will review the system view V$SQL and the columns in it which would allow you to regenerate previously executed statements.

1. Logon to SQL*PLUS as sysdba.

mylinux$ sqlplus ‘/ as sysdba’
SQL*Plus: Release 9.2.0.8.0 – Production on Tue Aug 16 10:53:45 2009

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

Connected to:
Oracle9i Enterprise Edition Release 9.2.0.8.0 – 64bit Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.8.0 – Production
SQL>

2. Describe the system view V$SQL and you will find three columns of interest for extraction of SQL are: SQL_TEXT, PARSING_USER_ID, and LAST_LOAD_TIME. SQL_TEXT provides the first 1000 characters of the SQL statement executed. NOTE: this may not be the entire SQL text. PARSING_USER_ID provides the User ID which last successfully parsed the statement. NOTE: This may not be the last person to execute the statement. Finally, LAST_LOAD_TIME provides you the time of last execution.

SQL> desc v$sql
Name Null? Type
—————————————– ——– —————
SQL_TEXT VARCHAR2(1000)
PARSING_USER_ID NUMBER
LAST_LOAD_TIME VARCHAR2(19)


3. Due to the limitation of DBMS_OUTPUT package in 9i we will create a dummy table to temporarily hold our SQL extracts. Execute the collowing DDL to create the table SQL_LONG.

SQL> create table sql_long(sql_text long, exec_time varchar2(19));

Table created.

SQL>

4. To extract all SQL in your database since instance startup, execute the following PL/SQL Block to populate your dummy table SQL_LONG.

set serveroutput on size 1000000
declare

v_ct number;

begin

for v_sql in(select SQL_TEXT, LAST_LOAD_TIME from v$sql order by last_load_time)
loop

insert into sql_long(sql_text, exec_time) values(v_sql.sql_text,
v_sql.last_load_time);

end loop;
end;
/

5. Now the only thing left is to extract the SQL from your dummy table. NOTE: You do not have to order by time of execution, because the SQL was inserted in ordered fashion.

set long 10000
select * from sql_long;

6. To retrieve the currently executing SQL statements issue the following PL/SQL block. NOTE: truncate the table SQL_LONG before every execution to ensure that you only received the information from the previous block.

Truncate table sql_long;

set serveroutput on size 1000000
declare

v_ct number;

begin

for v_sql in(select SQL_TEXT, LAST_LOAD_TIME from v$sql where address in
(select sql_address from v$session where status=’ACTIVE’) order by
last_load_time)
loop

insert into sql_long(sql_text, exec_time) values(v_sql.sql_text,
v_sql.last_load_time);

end loop;
end;
/

set long 10000
select * from sql_long;

Larry Catt, OCP 9i, 10g
oracle@allcompute.com
www.allcompute.com

Recreate Oracle View

Oracle provides views to allow you to hide the structures of under lying tables, to combine multiple tables into a single logical structure, and to reduce the complexity of SQL being generated against a database. Views allow the developer the flexibility to give users the look and feel of the database they desire, while maintaining a normalized structure under the covers. In this article we will review the SQL to generate a view’s DDL for review or transport.

1. Connect to your Oracle database server and logon to SQL*PLUS.

MyLinux:>sqlplus ‘\ as sysdba’
SQL*Plus: Release 10.2.0.4.0 – Production on Tue Jul 20 23:51:33 2009

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 – 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL>

2. Logon as the user SCOTT and generate the view TEST_VIEW to demonstrate the DDL extraction.

SQL> grant create view to scott;

Grant succeeded.

SQL> connect scott/tiger
Connected.
SQL> create view TEST_VIEW as
2 select emp.ename as employee, dept.dname as department, bonus.sal as salary
from
3 dept, emp, bonus where dept.deptno=emp.deptno and emp.ename=bonus.ename;

View created.

SQL>

3. Execute the following PL/SQL block to generate your DDL.

set serveroutput on
declare

v_ct number;
v_owner varchar2(30):=’SCOTT’;

begin

for v_view in(select view_name, text from dba_views where owner=v_owner)
loop

dbms_output.put_line(‘create view ‘||v_view.view_name||’ as’);
dbms_output.put_line(v_view.text||’;’);

end loop;
end;
/

SQL> connect / as sysdba
Connected.
SQL>
SQL> set serveroutput on
SQL> declare
2
3 v_ct number;
4 v_owner varchar2(30):=’SCOTT’;
5
6 begin
7
8 for v_view in(select view_name, text from dba_views where owner=v_owner)
9 loop
10
11 dbms_output.put_line(‘create view ‘||v_view.view_name||’ as’);
12 dbms_output.put_line(v_view.text||’;’);
13
14 end loop;
15 end;
16 /
create view TEST_VIEW as
select emp.ename as employee, dept.dname as department, bonus.sal as salary from
dept, emp, bonus where dept.deptno=emp.deptno and emp.ename=bonus.ename;

PL/SQL procedure successfully completed.

SQL>
SQL>

Larry J Catt, OCP 9i, 10g
oracle@allcompute.com
www.allcompute.com

Oracle auditing insert, update, and delete on a table

Oracle provides the ability to audit a great range of activities within the Oracle RDBMS environment. Care should be taken on what you wish to audit, due to the amount of disk space required to store all of this information. In this article we will discuss the auditing of insert, update, and deletes by user account access.

1. Logon to SQL*PLUS as sysdba

mylinux:>sqlplus ‘/ as sysdba’

SQL*Plus: Release 10.2.0.4.0 – Production on Fri Jul 03 19:18:21 2009

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 – 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>

2. Ensure that audit_trail is set to DB_EXTENDED and audit_sys_operations parameter is set to TRUE. Note: It is important to realize that setting the AUDIT_TRAIL to DB_EXTENDED will dramatically increase storage, so monitor this closely.

SQL> show parameter audit

NAME TYPE VALUE
———————————— ———– ——————————
audit_file_dest string /U01/ORACLE/PRODUCT/10.2.0/ADMIN
/ORCL10G/ADUMP
audit_sys_operations boolean FALSE
audit_trail string NONE

SQL>

System altered.

SQL> alter system set audit_sys_operations= TRUE scope=spfile;

System altered.

SQL>

3. Restart the database if you had to edit the init parameters.

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup open
ORACLE instance started.

Total System Global Area 612368384 bytes
Fixed Size 1250428 bytes
Variable Size 209718148 bytes
Database Buffers 394264576 bytes
Redo Buffers 7135232 bytes
Database mounted.
Database opened.
SQL>

4. Ensure that the new values took effect.

SQL> show parameter audit

NAME TYPE VALUE
———————————— ———– ——————————
audit_file_dest string /U01/ORACLE/PRODUCT/10.2.0/ADMIN
/ORCL10G/ADUMP
audit_sys_operations boolean TRUE
audit_trail string TRUE
SQL>

5. Execute the audit command below to begin monitoring changes to the table SCOTT.DEPT.

SQL> audit insert, update, delete on scott.dept by session;

Audit succeeded.

SQL>

6. Connect to the database as the user LJCATT and perform a insert, update and delete operation on the table scott.dept.

SQL> connect ljcatt/ljcatt
Connected.
SQL> insert into scott.dept(deptno, dname, loc) values(50,’PARTNERS’,’NEW YORK’)
;

1 row created.

SQL> commit;

Commit complete.

SQL> update scott.dept set loc=’WASHINGTON’ where deptno=50;

1 row updated.

SQL> commit;

Commit complete.

SQL> delete from scott.dept where deptno=50;

1 row deleted.

SQL> commit;

Commit complete.

SQL>

7. Login as sysdba again.

SQL> connect sys as sysdba
SQL>

8. Execute the following SQL to extract the statements executed by LJCATT.
“select timestamp, sql_text from dba_audit_object where username=’LJCATT’;”

SQL> select timestamp, sql_text from dba_audit_object where username=’LJCATT’;

TIMESTAMP SQL_TEXT
——— ——————————————————-
27-AUG-09 update scott.dept set loc=’WASHINGTON’ where deptno=50
27-AUG-09 insert into scott.dept(deptno, dname, loc) values(50,’PARTNERS’,’NEW YORK’)
27-AUG-09 delete from scott.dept where deptno=50

SQL>

9. That completes the use of Oracle Auditing to monitor the changes to the Oracle database by users.

Larry J. Catt, OCP 9i, 10g
oracle@allcompute.com
www.allcompute.com

UNIX CRON – Shell script errors with [10]: sqlplus: not found

In normal administration of an Oracle RDBMS on UNIX or LINUX operating systems, the DBA will be required to develop shell and SQL scripts to maintain his/her RDBMS. In fact, to be considered a mid to senior DBA you will need to be well versed in scripting at the OS layer. In this article we will review a common error which occurs in a shell script called by CRON due to a lack of properly set variables.

1. In a normal scenario, the DBA has developed a shell script which calls and executes a SQL script to perform a certain maintenance task. In testing, the DBA executes the script as the oracle software owner and the script performs perfectly. However, when placed in the OS CRON for execution, the following error occurs.

[10]: sqlplus: not found

2. The error occurs because the environmental variables are not being read. Thus, the OS does not know where to find the executable: sqlplus.

3. The solution is to update your shell script and hard code the directory structure for the command sqlplus. An example would be if sqlplus is located in the following path /u01/opt/app/oracle/bin then perform the following:

Replace:

sqlplus

With:

/u01/opt/app/oracle/bin/sqlplus

This completes resolving the error message [10]: sqlplus: not found in a shell script called through CRON.

Larry J. Catt, OCP 9i, 10g
oracle@allcompute.com
www.allcompute.com