Friday, November 28, 2008

Calling Struts Action by Javascript

To call a struts action by Javascript on an event, you need to write a function which is invoked when the event occurs and this function makes an AJAX call. The AJAX call can send a request to the same URL which is provided in action attribute of form tag or html:form tag.

e.g. In case your action URL is something like
"/registerUserAction.do?action=forgetPasswordForward"
that you provide in action attribute of html:form, you can pass the same url to the mentioned code snippet below:


function makeRequest(url, callbackfunction)
{
var http_request = getXMLHttpObject();
url = url + "isComingFromAjax=true";

if (url.indexOf('?') != -1)
{
url = url + "&" ;
}
else
{
url = url + "?" ;
}

url = url + "isComingFromAjax=true";
http_request.onreadystatechange = callbackfunction;
http_request.open('POST', url.substring(0, url.indexOf('?')), true);
http_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
http_request.send(url.substring(url.indexOf('?') + 1));
}

Some of points to be considered in given code snippet:
1. callbackfunction is the function which will be invoked when response is received
2. "isComingFromAjax=true" parameter has been added as a extra parameter to differentiate between the normal action request and the AJAX request to do any special handling on the server side.

I have not covered details of creating XMLHttpRequest Object and other AJAX related things assuming you know it. You can write the logic for handling the response received from server in callbackfunction.

Wednesday, November 26, 2008

Oracle - Rank Function

Rank calculates the rank of a value in a group of values. Rows with equal values for the ranking criteria receive the same rank. Oracle then adds the number of tied rows to the tied rank to calculate the next rank. Therefore, the ranks may not be consecutive numbers.

Consider the following Schema

CREATE TABLE USER_TEST
(
user_id numeric(12),
first_name varchar2(32),
last_name varchar2(32),
age numeric(3),
salary numeric(7)
);

insert into user_test values(1, 'Pardeep', 'Kumar', 26, 20000);
insert into user_test values(2, 'Raj', 'Sharma', 23, 15000);
insert into user_test values(3, 'Jai', 'Singh', 30, 30000);
insert into user_test values(4, 'Rana', 'Pratap', 32, 35000);
insert into user_test values(5, 'Nakul', 'Gupta', 23, 16000);
insert into user_test values(6, 'Ritu', 'Kumar', 22, 10000);
insert into user_test values(7, 'Sita', 'Dikshit', 27, 22000);
insert into user_test values(8, 'Gurpal', 'Bhatia', 38, 49000);
insert into user_test values(9, 'Bhim', 'Kumar', 23, 19000);
insert into user_test values(10, 'Lokesh', 'Shriram', 22, 11500);

Aggregation

As an aggregate function, RANK calculates the rank of a hypothetical row identified by the arguments of the function with respect to a given sort specification.

The constant argument expressions and the expressions provided in the ORDER BY clause of the aggregate match by position. Therefore, the number of arguments must be the same and their types must be compatible.

Single Column RANK as Aggregation Function

Syntax:

RANK () WITHIN GROUP (ORDER BY NULLS )

Example:
The following query returns the rank for a user with salary 10,000SELECT RANK(20000) WITHIN GROUP
(ORDER BY salary DESC NULLS LAST) SAL_RANK
FROM user_test;

Result: SAL_RANK = 5

Multiple Column RANK as Aggregation Function

RANK () WITHIN GROUP (ORDER BY NULLS )

The following query returns the rank of a user a salary of 15,000 and age 23 years.

SELECT RANK(23, 15000) WITHIN GROUP
(ORDER BY age desc, salary desc) RANK
FROM user_test;

Result: Rank = 8


Analytic

As an analytic function, RANK computes the rank of each row returned from a query with respect to the other rows returned by the query, based on the values of the value_exprs in the order_by_clause.

RANK Analytic Function

RANK () OVER ()

Find the user with the 2nd highest salarySELECT * FROM (SELECT user_id, first_name, last_name, salary, RANK() OVER (ORDER BY salary DESC) userrank
FROM user_test) WHERE userrank = 2;

Result:

USER_ID FIRST_NAME LAST_NAME SALARY USERRANK
4 Rana Pratap 35000 2 RANK() OVER ( )

Arrange table by age and then salary

SELECT user_id,first_name, last_name, age, salary,
RANK() OVER (PARTITION BY age ORDER BY salary DESC) RANK
FROM user_test;

Result:

USER_ID FIRST_NAME LAST_NAME AGE SALARY RANK
10 Lokesh Shriram 22 11500 1
6 Ritu Kumar 22 10000 2
9 Bhim Kumar 23 19000 1
5 Nakul Gupta 23 16000 2
2 Raj Sharma 23 15000 3
1 Pardeep Kumar 26 20000 1
7 Sita Dikshit 27 22000 1
3 Jai Singh 30 30000 1
4 Rana Pratap 32 35000 1
8 Gurpal Bhatia 38 49000 1


Return all users with age 23 ordered by salary

SELECT user_id,first_name, last_name, age, salary,
RANK() OVER (PARTITION BY age ORDER BY salary DESC) RANK
FROM user_test where age = 23;

USER_ID FIRST_NAME LAST_NAME AGE SALARY RANK
9 Bhim Kumar 23 19000 1
5 Nakul Gupta 23 16000 2
2 Raj Sharma 23 15000 3

Although the examples quoted here may looks like that we are paying more cost for the same things that can be done by simple order by, but simple examples have been chosen to make it easy to understand how to use RANK.

Generating Image Thumbnails

When I started working on this initially, I started looking into open source tools for this, after spending couple of hours on open source tools I suddenly jumped into oracle site and was pleased to see a good support for image processing in oracle. Oracle provides support to create thumbnail of images stored as blob. Here is simplest way to create image thumbnails. Create a table that will store the original image and the thumbnail image content as blob.

CREATE TABLE test_thumbnail
(
id NUMERIC(12) PRIMARY KEY,
image_content BLOB,
thumbnail_content BLOB
);

Create a stored procedure that will update the thumbnail_content field after image is stored in the database.

create or replace PROCEDURE IMAGE_THUMB_PROCEDURE
(imgId IN NUMBER , imgAttribute IN varchar2) AS
imageId integer := 0; verb varchar2(100);
src_blob BLOB;
dst_blob BLOB;
BEGIN imageId := imgId; verb := imgAttribute;
update test_thumbnail set thumbnail_content=empty_blob() where id = imageId;
select image_content into src_blob from test_thumbnail where id = imageId;
select thumbnail_content into dst_blob from test_thumbnail where id = imageId for update; ordsys.ordimage.processCopy(src_blob ,verb ,dst_blob);
update test_thumbnail set thumbnail_content = dst_blob where id = imageId;
END IMAGE_THUMB_PROCEDURE;

Invoke the stored procedure passing the appropriate imgAttribute, passing different kind of image attributes you can process the original image content, for scaling down the image to a thumbnail of 100x100 pixels, pass the following parameter:

“maxscale=100 100 fileformat=jfif”

Maxscale is the size of the generated image and fileformat has its obvious meaning. The method ordsys.ordimage.processCopy(src_blob ,verb ,dst_blob) copy a source blob into a destination blob doing the processing as per attributes passed as verb.

For more details on oracle media solution support please read the following article: http://www.oracle.com/technology/sample_code/products/intermedia/index.html

Once the stored procedure is invoked image thumbnail is stored as blob in field thumbnail_content.

Difference between Delete, Drop and Truncate Statements

DELETE, DROP and TRUNCATE statements differ in their nature itself.
a. DELETE statement is a DML (DATA MANIPULATION LANGUAGE) statement.
b. DROP AND TRUNCATE statements are DDL (DATA definition language) statements.

A DML action can be rolled back if the data is not committed, but DDL actions cannot be rolled back until Oracle 9i. With Oracle 9i FLASH BACK enabled even some of the DDL statements can be rolled back.

Delete

A delete statement deletes the data from a table. A delete statement can have a “where” clause, which need to be satisfied for the data to be deleted from the table.

Actions of Delete statement


  • Deletes the data from the current table space.
  • Modifies the undo table space with the delete records.
  • Executes all the before / after statement and row level triggers.
  • Updates the indexes (makes the index empty if the where clause is omitted).
  • Constraint checks are performed before deleting the rows
Syntax of a delete Statement:
DELETE FROM table [WHERE condition]

Truncate

Truncate drops all the records in a table. But as it is a DDL statement data cannot be retrieved. Usually truncate is faster than delete statement because there is no need to change or update the UNDO table space with the deleted records. Truncate is an implicit commit Statement. Truncate statement deal locates the space.

Actions of Truncate Statement
a. Removes all the records from the current table space.
b. Updates the indexes.
c. High watermark of the truncated table is reset.
d. Integrity Constraint checks are performed

Syntax of a Truncate Statement:
TRUNCATE TABLE table_name;

DROP STATEMENT

A drop statement removes the table object from the database. Structure and the data will be removed from the database. Action cannot be rolled back (but only by FLASH BACK from Oracle 9i).

Actions of a Drop Statement:
a. Constraint checks are performed before dropping.
b. All the data and structure of the table will be removed.
c. Updates the corresponding data dictionary views like dba_objects, dba_tables, user_tables e.t.c
d. Updates the Status as “INVALID” for all the dependent objects.
e. Deallocates the Space

Syntax of a Drop Statement:
DROP TABLE table_name;
DROP TABLE table_name cascade constraints;

If “cascade constraints” is specified all foreign keys that reference the table are dropped and then table is dropped.