Database Journal
MS SQL Oracle DB2 Access MySQL PostgreSQL Sybase PHP SQL Etc SQL Scripts & Samples Links Database Forum

» Database Journal Home
» Database Articles
» Database Tutorials
MS SQL
Oracle
DB2
MS Access
MySQL
» RESOURCES
Database Tools
SQL Scripts & Samples
Links
» Database Forum
» Sitemap
Free Newsletters:
DatabaseDaily  
News Via RSS Feed


follow us on Twitter
Database Journal |DBA Support |SQLCourse |SQLCourse2
 

Featured Database Articles

Oracle

Posted Apr 12, 2006

Combining Overloading and Session Management in Oracle

By Steve Callan

One feature often times overlooked by developers is PL/SQL's ability to allow overloading. As in other programming languages, overloading occurs when a program uses the same name for a function or procedure, and the way the program differentiates which version being called is based on the types and numbers of parameters being passed in. By taking advantage of some basic features of PL/SQL, a DBA can quickly and easily build a versatile session management tool, which can manage one or many sessions.

A typical example of overloading

One of the simplest examples often seen in C, C++ and Java programming examples involves computing the area of rectangle. The area of a rectangle is simply the width multiplied by the length, so a function that returns the area would need two parameters passed in. In the special case of when the width and length are the same, all that is needed to compute the area is either parameter. In this case, our prototype function needs only one parameter. The two functions, or the overloaded function with differing signatures, could easily be constructed as follows:

create function compute_area 
  (width number, length number) 
  return number is
  area number;
begin
  area:= width * length;
  return area;
end;
/
create function compute_area 
  (side number) 
  return number is
  area number;
begin
  area:=side*side;
  return area;
end;
/

Would it be correct to say that the usage is as simple as "select compute_area(5, 3) from dual" or "select compute_area(5) from dual?" The answer is yes – and no. Let's start with the no part first.

Does Oracle allow objects to share the same name? The example as shown above, if run as depicted, results in an error:

create function compute_area 
  (side number) 
  return number is
                *
ERROR at line 1:
ORA-00955: name is already used 
  by an existing object

What if the create statement used "create or replace" instead of "create" by itself? The last statement would then be the only one in effect. You could then compute the area of a square, but would have lost the more general "compute the area of a rectangle" functionality.

As standalone, differently named functions, the "yes" side of the answer is as shown.

To use the overloading feature, these functions need to be part of a package. Coming back to how overloading can be useful to a DBA, the functions will now become procedures which output kill session statements for input based on a SID or a username. The procedure name will be the same for both cases, but the input – a number or a username – will serve as the signature (i.e., what the procedure expects as input). With the addition of one more parameter (a flag to signal Oracle whether to perform the kills or just output the statements), you can easily add more flexibility to these procedures.

Being able to kill a single session based on the user's SID is obviously useful for managing individual users. Being able to kill multiple users - all with the same username, which is very common when working with Web applications – is a handy feature or functionality to have around when you need to shut down, so to speak, part of an OLTP database without having to shut down the entire database.

Code the package and package body

Okay, this article is also a gentle introduction to packages. Without packages, no overloading is allowed. The first step is to create the package specification (what the package contains: names of functions and procedures with their signatures). The second step is to create the package body, which is nothing more than the code behind the procedures and functions listed in the package specification. An example of how one could code the package and package body is shown below.


create or replace package manage_users as
  procedure kill_user(the_sid in number);
  procedure kill_user(the_user in varchar2);
end manage_users;
/
create or replace package body manage_users as
  procedure kill_user(the_sid in number) as
    v_str varchar2(50) := 'alter system kill session '||chr(39);
    v_serial number;
  begin
    dbms_output.put_line(chr(10));
    dbms_output.put_line('Session to be killed:');
    dbms_output.put_line('---------------------');
    select serial# into v_serial
    from v$session
    where sid = the_sid;
    v_str := v_str||the_sid||','||v_serial||chr(39)||';';
    dbms_output.put_line(v_str);
    exception
    when no_data_found then
      dbms_output.put_line('No such session.');
  end;
  procedure kill_user(the_user in varchar2) as
    v_str varchar2(50) := 'alter system kill session '||chr(39);
    v_statement varchar2(50);
    cursor user_cur is
    select sid, serial#
    from v$session
    where username = upper(the_user);
  begin
    dbms_output.put_line(chr(10));
    dbms_output.put_line('Sessions to be killed:');
    dbms_output.put_line('----------------------');
    for user_rec in user_cur loop
     v_statement := v_str||user_rec.sid||','||user_rec.serial#||chr(39)||';';
     dbms_output.put_line(v_statement);
     v_statement := null;
    end loop;
  end;
end manage_users;
/

Examples of invoking or executing the package_name.package_element (manage_users.kill_user) are shown below. As what was shown in the code source, one version of the kill_user procedure accepts a name (varchar2), and the other a number.

SQL> exec manage_users.kill_user('scott');
Sessions to be killed:
----------------------
alter system kill session '141,8';
alter system kill session '142,213';
alter system kill session '145,37';
PL/SQL procedure successfully completed.
SQL> exec manage_users.kill_user(141);
Session to be killed:
---------------------
alter system kill session '141,8';
PL/SQL procedure successfully completed.

The statements are cut and paste ready inside of a SQL*Plus session.

So far, the unstated user invoking these procedures is System. Just like non-packaged functions and procedures, users needing to execute package elements need the appropriate roles and privileges. If DML or DDL is performed within the package, the calling user needs the appropriate permission/grant/role.

In Closing

Overloading allows the DBA or developer to re-purpose code and make use of existing names for functions and procedures. If an application changes (key input is now based on a different datatype, or a different number of parameters), but both the old and new versions need to be supported, it may be possible to re-purpose existing code by using overloading.

» See All Articles by Columnist Steve Callan



Oracle Archives

Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 




Latest Forum Threads
Oracle Forum
Topic By Replies Updated
Oracle Data Mining: Classification jan.hasller 0 July 5th, 07:19 AM
Find duplicates - Unique IDs Lava 5 July 2nd, 08:30 AM
no matching unique or primary key rcanter 1 April 25th, 12:32 PM
Update values of one table based on condition of values in other table using Trigger Gladiator 3 February 29th, 06:01 PM


















Thanks for your registration, follow us on our social networks to keep up-to-date