Thursday 27 November 2008

PL/SQL


Reference:
http://www.comp.nus.edu.sg/~ooibc/courses/sql/plsql.htm

Overview

PL/SQL is the Oracle's extension to SQL with design features of programming languages. The data manipulation and query statements are included in the procedural units of codes. PL/SQL allows the applications to be written in a PL/SQL procedure or a package and stored at Oracle server, where these PL/SQL codes can be used as shared libraries, or applications, thus enhancing the integration and code reuse. Moreover, the Oracle  server pre-compiles PL/SQL codes prior to the actual code execution and thus improving the performance.
The basic PL/SQL code structure is :
  • DECLARE -- optional, which declares and define variables, cursors and user-defined exceptions.
  • BEGIN -- mandatory
- SQL statements
- PL/SQL statements
  • EXCEPTION -- optional, which specifies what actions to take when error occurs.
  • END; -- mandatory
For example, the following PL/SQL code block declares an integer v1, assigns it with value 3 and print out the value.
DECLARE
v1  NUMBER(3);

BEGIN
   v1 := 3;
   DBMS_OUTPUT.PUT_LINE('v1=' || v1);
END;
Note that DBMS_OUTPUT is an Oracle-supplied PL/SQL package and PUT_LINE is one of the packaged procedures. It displays the values on the SQL*Plus terminal  which must be enabled with SET SERVEROUTPUT ON first. To execute this code sample, login into SQL*Plus, and type
SQL> SET SERVEROUTPUT ON
DECLARE
v1  NUMBER(3);

BEGIN
   v1 := 3;
   DBMS_OUTPUT.PUT_LINE('v1= ' || v1);
END;

/
Note that a PL/SQL block is terminated by a slash / or a line byitself.

Handling Variables

  • Variables must be declared first before the usage. The PL/SQL variables can be a scalar type such as DATE, NUMBER, VARCHAR(2), DATE, BOOLEAN, LONG and CHAR, or a composite type, such  array type VARRAY.
  • Only TRUE and FALSE can be assigned to BOOLEAN type of variables.
  • AND, OR, NOT operators can be used to connect BOOLEAN values.
  • % TYPE attribute can be used to define a variable which is of type the same as a database column's type definition.
  • Users can customize the variable types by using TYPE ... IS ... statement.
The following code block illustrates the use of TYPE..IS... and VARRAY. In this sample, a type v_arr is defined as an variable array of maximum 25 elements which are of type NUMBER(3).  Then a variable v1 is defined as type v_arr .    This sample code also demonstrates the use of %TYPE attribute.
DECLARE
TYPE v_arr IS VARRAY(25) of NUMBER(3);

v1 v_arr;
v_empno employee.empno%TYPE;

BEGIN

    v1(2) := 3;
    DBMS_OUTPUT.PUT_LINE('The Value of v1(2) = ' || v1(2)); 

      v_empno  := 4;
END;

Coding Guidelines

  • Single-line comments are prefixed with two dashes --.
  • Multiple-line comments can be enclosed with the symbols /* and */.
  • Variables and function identifiers can contain up to 30 characters, and should not have the same name as a database column name.
  • Identifiers must begin with an alphanumerical character.
  • SQL functions can be used in PL/SQL.
  • Code blocks can be nested and unqualified variables can locally scoped.
  • It is recommended that variable names are prefixed by v_, and parameter names in procedures/functions are prefixed by _p.

SQL Statements in PL/SQL

The following code block shows how to run DML statements in PL/SQL. Basically they look similar to the SQL. Note that the SELECT statement retrieves the single-row value and store into a variable using INTO clause.
DECLARE
    v_sal employee.sal%TYPE;
BEGIN


    INSERT INTO employee VALUES (6, 'TOM LEE', 10000);


    UPDATE employee SET sal = sal + 5000 WHERE empno = 6;

      SELECT sal INTO v_sal FROM employee WHERE empno = 6;
    DBMS_OUTPUT.PUT_LINE('Salary increased to ' || v_sal); 
    DELETE FROM employee WHERE empno = 6;
      COMMIT;
END;

/


Control Structures

  • Conditions checking
IF THEN
[ELSIF THEN]
[ELSE THEN]
END IF;
  • Basic loops.
LOOP
...
EXIT WHEN
END LOOP;
  • FOR loop.
FOR counter IN lower_bound .. upper_bound
...
END LOOP;
  • WHILE loop.
WHILE LOOP
...
END LOOP;
The code samples making use of the control structures will be given in the following.

SQL Cursor 

A SQL cursor is a private Oracle SQL working area. There are two types of SQL cursor: implicit or explicit cursor. The implicit cursor is used by Oracle server to test and parse the SQL statements and the explicit cursors are declared by the programmers.
Using the implicit cursor, we can test the outcome of SQL statements in PL/SQL. For example,
  • SQL%ROWCOUNT, return the number of rows affected;
  • SQL%FOUND, a BOOLEAN attribute indicating whether the recent SQL statement matches to any row;
  • SQL%NOTFOUND, a BOOLEAN attribute indicating whether the recent SQL statement does not match to any row;
  • SQL%ISOPEN, a BOOLEAN attribute and always evaluated as FALSE immediately after the SQL statement is executed.
To write the explicit cursor,  please refer to the following example. Note that a cursor definition can array a number of arguments.
For example,
        DECLARE
CURSOR csr_ac (p_name VARCHAR2) IS
SELECT empno, name, sal
FROM employee
WHERE name LIKE '%p_name%';
BEGIN
FOR rec_ac IN csr_ac ('LE')
LOOP
   DBMS_OUTPUT.PUT_LINE(
rec_ac.empno || ' ' ||rec_ac.name || ' '||v_sal); 
END LOOP ;

CLOSE csr_ac;
END;
/
Another way of writing the above code, is to use the basic loop and the SQL%NOTFOUND cursor, as shown in the following.
DECLARE
CURSOR csr_ac (p_name VARCHAR2) IS
SELECT empno, name, sal
FROM employee
WHERE name LIKE '%p_name%';

v_a employee.empno%TYPE;
v_b employee.name%TYPE;
v_c employee.sal%TYPE;
BEGIN
    OPEN 
csr_ac ('LE');
    LOOP
        FETCH 
csr_ac INTO a, b, c;
        EXIT WHEN csr_ac%NOTFOUND;                       

        DBMS_OUTPUT.PUT_LINE(v_a || ' ' || v_b || ' '||v_c);

    END LOOP;
    CLOSE csr_ac;
END; 

Writing PL/SQL Procedures/Functions

PL/SQL functions returns a scalar value and PL/SQL procedures return nothing. Both can take zero or more number of parameters as input or output. The special feature about PL/SQL is that a procedure/function argument can be of input (indicating the argument is read-only), output (indicating the argument is write-only) or both (both readable and writable).
For example, the following is a PL/SQL procedure and a function.
PROCEDURE hire_employee (emp_id INTEGER, name VARCHAR2) IS
BEGIN
    INSERT INTO employee VALUES (emp_id, name, 1000);
END hire_employee;
 
FUNCTION sal_ok (salary REAL, title REAL) RETURN BOOLEAN IS
   min_sal REAL;
   max_sal REAL;
BEGIN
   SELECT losal, hisal INTO min_sal, max_sal 
      FROM sals
      WHERE job = title;
   RETURN (salary >= min_sal) AND (salary <= max_sal);
END sal_ok;
   A function is called as part of an expression. For example, the function sal_ok might be called as follows:

    IF sal_ok(new_sal, new_title) THEN ...

Writing and Compiling PL/SQL Packages.

package is a database object that groups logically related PL/SQL types, objects, and subprograms. Packages usually have two parts, a specification and a body, although sometimes the body is unnecessary. The specification is the interface to your applications; it declares the types, variables, constants, exceptions, cursors, and subprograms available for use. The body fully defines cursors and subprograms, and so implements the specification.
Unlike subprograms, packages cannot be called, parameterized, or nested. Still, the format of a package is similar to that of a subprogram:
CREATE PACKAGE name AS  -- specification (visible part)
   -- public type and object declarations
   -- subprogram specifications
END [name];

CREATE PACKAGE BODY name AS  -- body (hidden part)
   -- private type and object declarations
   -- subprogram bodies
[BEGIN
   -- initialization statements]
END [name];
The specification holds public declarations, which are visible to your application. The body holds implementation details and private declarations, which are hidden from your application. As shown in the following figure, you can think of the specification as an operational interface and of the body as a "black box":

You can debug, enhance, or replace a package body without changing the interface (package specification) to the package body.
For example, we want to create a simple package providing three functions: hire_employee, fire_employee and raise_salary.
First we created the package specification.
CREATE OR REPLACE PACKAGE test AS -- package spec
    TYPE list IS VARRAY(25) of NUMBER(3);

    PROCEDURE hire_employee (emp_id INTEGER, name VARCHAR2);
    PROCEDURE fire_employee (emp_id INTEGER);
    PROCEDURE raise_salary (emp_id INTEGER, amount REAL);
END test;
/
Then we created the package body.
CREATE OR REPLACE PACKAGE BODY test AS -- package body
    PROCEDURE hire_employee (emp_id INTEGER, name VARCHAR2) IS
    BEGIN
        INSERT INTO employee VALUES (emp_id, name, 1000);
    END hire_employee;

    PROCEDURE fire_employee (emp_id INTEGER) IS
    BEGIN
        DELETE FROM employee WHERE empno = emp_id;
    END fire_employee;

    PROCEDURE raise_salary (emp_id INTEGER, amount REAL) IS
    BEGIN
        DBMS_OUTPUT.PUT_LINE('Increase Salary :' || to_char(amou
nt));
        UPDATE employee SET sal = sal + amount WHERE empno = emp_id;
    END raise_salary;
END test;

/
To compile the package, we can either type them into SQL*Plus terminal. And Oracle server will compile and store the package, or save them into separate files and compile them from SQL*Plus. Assume the package spec is stored in a file named spec, and the body is stored in another file named body. The following shows how to compile the package and make the procedure call at SQL*Plus.
SQL> SET SERVEROUTPUT ON
SQL> VARIABLE num NUMBER

SQL> @spec

SQL> @body

SQL> exec test.raise_salary(1,1000);



Reference :
http://www.comp.nus.edu.sg/~ooibc/courses/sql/plsql.htm

Saturday 22 November 2008

How to enable Log4j logging in Eclipse console window?

Problems:

Could not see the log message in eclipse console window but it shows following warning message


log4j:WARN No appenders could be found for logger (com.test.HelloWorld).

log4j:WARN Please initialize the log4j system properly.

Reasons:
Log4j is not initialised.


Solution:
Add a ConsoleAppender or Appender

Code Sample:
BasicConfigurator.configure();
or
PropertyConfigurator.configure("log4j.xml");


Ref:

Log4j Manual
Log4j API
BasicConfigurator
PropertyConfigurator

Thursday 20 November 2008

contactsheet : How to make friends by Telephone



http://contactsheet.org/junk/


http://contactsheet.org/junk/telephone1.html








Log4j warning message [log4j:WARN No appenders could be found for logger]

Log4j:

Log4j is a logging or tracing API, large number of applications and framework use Log4j for logging.


Problems:

Sometimes application do not generate log files and generate the following warning message.

log4j:WARN No appenders could be found for logger (com.test.HelloWorld).
log4j:WARN Please initialize the log4j system properly.


Reasons:

Log4j is not initialised properly. The Log4j library files are in application class path but Log4j configuration file is not in application class path.


Solution:

Add log4j configuration file [log4j.properties or log4j.xml] to class path.


More Info:

Log4j priority order,
FATAL: 50000
ERROR: 40000
WARN: 30000
INFO: 20000
DEBUG: 10000

Ref:
log4j Manual
log4j API

Tuesday 21 October 2008

Data Structures and Algorithms

Data Structure

A data structure is a way to store and organise data in computer that it can be used efficiently.
(http://en.wikipedia.org/wiki/Data_structure)

Abstract Data Types (ADTs)

Mathematical and logical model. Define data and operations but no implementation. 
(http://en.wikipedia.org/wiki/Abstract_data_type)

Ref:
http://en.wikipedia.org/wiki/Data_structure
http://en.wikipedia.org/wiki/Abstract_data_type
http://www.cs.princeton.edu/~rs/AlgsDS07/
http://en.wikipedia.org/wiki/Binary_search_tree



Friday 3 October 2008

Oracle Sql scripts

User , Role Privileges

select * from dba_tab_privs;
select * from dba_role_privs WHERE granted_ROLE= 'SHARED_USER';
select * from dba_sys_privs;
 
select * from all_tab_privs;
select * from all_role_privs;
select * from all_sys_privs;
 
select * from user_tab_privs;
select * from user_role_privs;
select * from user_sys_privs;
 
select * from role_tab_privs;
select * from role_role_privs;
select * from role_sys_privs;
 
 
select * from role_tab_privs where role = 'SHARED_USER';
select * from role_role_privs  where role = 'SHARED_USER';
select * from role_sys_privs  where role =  'SHARED_USER'
 
select count(*) from dba_users;
select * from user_role_privs;
select * from dba_roles where role = 'ADMIN'


Stats Details



-To verify stats
 
select * from user_tab_statistics;
select * from user_tab_col_statistics;



Force Index to use


To use a full scan or a range scan.
http://www.dba-oracle.com/t_v_sql_hint.htm
 
 
 
 
SELECT /*+ FULL(m)         */ b FROM mytable m WHERE b=10; -- full table scan
SELECT /*+ INDEX_RS_ASC(m) */ b FROM mytable m WHERE b=10; -- index range scan
SELECT /*+ INDEX_FFS(m)    */ b FROM mytable m WHERE b=10; -- index fast full scan



Get the Explain plan for sql query
select sql_id, child_number , s.*  
from gv$sql s 
WHERE upper(SQL_FULLTEXT) like '%TABLE_NAME%' 
order by last_active_time desc;

SELECT * 
FROM TABLE(dbms_xplan.display_cursor('frmxr4w3tb9wv', 0));



Check time consuming SQL queries in Oracle
SELECT * FROM
(SELECT
    sql_fulltext,
    sql_id,
    child_number,
    disk_reads,
    executions,
    first_load_time,
    last_load_time
FROM    v$sql
ORDER BY elapsed_time DESC)
WHERE ROWNUM < 20
 
 
 
SELECT Disk_Reads DiskReads, Executions, SQL_ID, SQL_Text SQLText,
   SQL_FullText SQLFullText
FROM
(
   SELECT Disk_Reads, Executions, SQL_ID, LTRIM(SQL_Text) SQL_Text,
      SQL_FullText, Operation, Options,
      Row_Number() OVER
         (Partition By sql_text ORDER BY Disk_Reads * Executions DESC)
         KeepHighSQL
   FROM
   (
       SELECT Avg(Disk_Reads) OVER (Partition By sql_text) Disk_Reads,
          Max(Executions) OVER (Partition By sql_text) Executions,
          t.SQL_ID, sql_text, sql_fulltext, p.operation,p.options
       FROM v$sql t, v$sql_plan p
       WHERE t.hash_value=p.hash_value AND p.operation='TABLE ACCESS'
       AND p.options='FULL' AND p.object_owner NOT IN ('SYS','SYSTEM')
       AND t.Executions > 1
   )
   ORDER BY DISK_READS * EXECUTIONS DESC
)
WHERE KeepHighSQL = 1
AND rownum <=5;
 
 
SELECT username,
       buffer_gets,
       disk_reads,
       executions,
       buffer_get_per_exec,
       parse_calls,
       sorts,
       rows_processed,
       hit_ratio,
       module,
       sql_text
       -- elapsed_time, cpu_time, user_io_wait_time, ,
  FROM (SELECT sql_text,
               b.username,
               a.disk_reads,
               a.buffer_gets,
               trunc(a.buffer_gets / a.executions) buffer_get_per_exec,
               a.parse_calls,
               a.sorts,
               a.executions,
               a.rows_processed,
               100 - ROUND (100 * a.disk_reads / a.buffer_gets, 2) hit_ratio,
               module
               -- cpu_time, elapsed_time, user_io_wait_time
          FROM v$sqlarea a, dba_users b
         WHERE a.parsing_user_id = b.user_id
           AND b.username NOT IN ('SYS', 'SYSTEM', 'RMAN','SYSMAN')
           AND a.buffer_gets > 10000
         ORDER BY buffer_get_per_exec DESC)
 WHERE ROWNUM <= 20


Dynamic Oracle Views
SELECT * FROM V$FIXED_VIEW_DEFINITION;
SELECT * FROM V$FIXED_TABLE;
SELECT NAME, TYPE FROM V$FIXED_TABLE WHERE NAME LIKE 'V$%';

LOCKED DATABASE OBJECTS

SELECT l.session_id || ',' || v.serial# sid_serial,      
       l.ORACLE_USERNAME ora_user,      
       o.object_name,      
       o.object_type,      
       DECODE(l.locked_mode,             
              0,
              'None',             
              1,
              'Null',             
              2,
              'Row-S (SS)',             
              3,
              'Row-X (SX)',             
              4,
              'Share',             
              5,
              'S/Row-X (SSX)',             
              6,
              'Exclusive',             
              TO_CHAR(l.locked_mode)             
              ) lock_mode,      
       o.status,      
       to_char(o.last_ddl_time, 'dd.mm.yy') last_ddl
  FROM dba_objects o, gv$locked_object l, v$session v
 WHERE o.object_id = l.object_id     
   and l.SESSION_ID = v.sid;


select a.sid, a.serial#, OBJECT_NAME , a.*
  from v$session a, v$locked_object b, dba_objects c
 where b.object_id = c.object_id
   and a.sid = b.session_id;
 
 
ALTER SYSTEM KILL SESSION 'sid,serial#';
 
 
--Dynamic spool name
column filename new_val filename
select 'alarm_query_'||  sys_context('userenv','db_name') || '_' || to_char(sysdate, 'yyyymmdd' ) filename from dual;
spool '&filename'
  
set heading OFF;
--set serveroutput on;
select 'User : ' || user from dual;
select 'Database : ' || ora_database_name from dual;





SQL

Tuesday 30 September 2008

Java Enumeration Testing


public enum DirectionEnum {
 NORTH("N", "North", 1), NORTH_EAST("NE", "North-East", 2), EAST("E", "East", 3), SOUTH_EAST("SE", "South-East", 4), SOUTH("S", "South", 5), SOUTH_WEST(
   "SW", "South-West", 6), WEST("W", "West", 7), NORTH_WEST("NW", "North-West", 8);

 private final String code;
 private final String description;
 private final short id;

 private DirectionEnum(String code, String description, int id) {
  this.code = code;
  this.description = description;
  this.id = (short) id;
 }

 public String getCode() {
  return code;
 }

 public String getDescription() {
  return description;
 }

 public short getId() {
  return id;
 }

 public static DirectionEnum findById(int id) {
  for (DirectionEnum dir : DirectionEnum.values()) {
   if (dir.getId() == id) {
    return dir;
   }
  }
  return null;
 }
}


public enum VehicleClassEnum {
 H("Heavy"), L("Light"), N("Not Specified");

 private String description;

 private VehicleClassEnum(String description) {
  this.description = description;
 }

 public String getDescription() {
  return description;
 }

 public void setDescription(String description) {
  this.description = description;
 }

}



import java.util.Vector;
import java.util.Enumeration;

public class EnumerationTester {

 public static void main(String args[]) {
  System.out.println(VehicleClassEnum.valueOf("H"));
  System.out.println(VehicleClassEnum.valueOf("H").toString());
  System.out.println(VehicleClassEnum.valueOf("H").getDescription());
  System.out.println(VehicleClassEnum.valueOf(VehicleClassEnumTest.class, VehicleClassEnum.L.getDescription()));
  System.out.println(VehicleClassEnum.values());
  for (VehicleClassEnum classEnum : VehicleClassEnum.values()) {
   System.out.println("VehicleClassEnum:" + classEnum + ", VehicleClassEnum.toStirng()" + classEnum.toString() + ", VehicleClassEnum.name():"
     + classEnum.name() + ", VehicleClassEnum.ordinal():" + classEnum.ordinal() + ", getDeclaringClass:" + classEnum.getDeclaringClass()
     + ", getDescription():" + classEnum.getDescription() + ", compareTo:" + classEnum.compareTo(VehicleClassEnum.L));
  }

  Enumeration days;
  Vector dayNames = new Vector();
  dayNames.add("Sunday");
  dayNames.add("Monday");
  dayNames.add("Tuesday");
  dayNames.add("Wednesday");
  dayNames.add("Thursday");
  dayNames.add("Friday");
  dayNames.add("Saturday");
  days = dayNames.elements();
  while (days.hasMoreElements()) {
   System.out.println(days.nextElement());
  }
 }
}



---------------OUTPUT---------------

H
H
Heavy
Light
[LVehicleClassEnum;@3ce53108
VehicleClassEnum:H, VehicleClassEnum.toStirng()H, VehicleClassEnum.name():H, VehicleClassEnum.ordinal():0, getDeclaringClass:class VehicleClassEnum, getDescription():Heavy, compareTo:-1
VehicleClassEnum:L, VehicleClassEnum.toStirng()L, VehicleClassEnum.name():L, VehicleClassEnum.ordinal():1, getDeclaringClass:class VehicleClassEnum, getDescription():Light, compareTo:0
VehicleClassEnum:N, VehicleClassEnum.toStirng()N, VehicleClassEnum.name():N, VehicleClassEnum.ordinal():2, getDeclaringClass:class VehicleClassEnum, getDescription():Not Specified, compareTo:1
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday