Adsense

Sunday, November 30, 2014

How to display the number of rows affected in DB2 INSERT / DELETE / UPDATE / MERGE commands

 By default, DB2 does not print the number of records affected when we run the DML  commands like INSERT,  DELETE, UPDATE or MERGE in the command prompt. So to display number of records affected when you run the above DML commands, you can use  following options.

You  can use the option m, in the command itself as given below

db2 -m update employee set payscale='42000-3%-72000' where doj<='1976-01-01'
  Number of rows affected : 50
DB20000I  The SQL command completed successfully.


Also, You can use the below db2set command to set the command options "m" permanently for all instances and databases,


db2set DB2OPTIONS=-m

db2stop

db2start




Or you can update the options m to ON  permanently using the update command options.

db2 update command options using m ON

            In windows, if you may get the  below error OR your changes done to the command option may not be  retained when you run the above command,

error :   db2 update command options using m ON SQL0104N  An unexpected token "m" was found following "USING".  Expected tokens may include:  "A".  SQLSTATE=42601. Solution will be

Just go to db2 prompt.

db2=> update command options using m ON

You can cehck the command options using the below command

list command options


db2 => delete from Employee where emp_code='E1022'
  Number of rows affected : 1
DB20000I  The SQL command completed successfully.



Saturday, November 15, 2014

DB2 Gui Tools and Commands to start GUI tools

DB2 Universal Database (UDB) has many graphical tools that make the DBA’s database management job easier and it improves the productivity of the developer in application development. The following are the Gui Tools available in DB2 UDB. 1. Control Center , 2. Command Center , 3. Configuration Assistance , 4. Health Center, 5. Task Center , 6. Development Center , 7. Journal , 8. Memory Visualizer , 9. Information Center , 10. Replication Center

Now We are going to the use of db2 gui tools and how to invoke these Tools
All the GUI tools can be run through Control Center. It is better to invoke the GUI tools directly from the command line. 

1. Control Center : Using the Control Center, We can perform administrative tasks, monitor systems, and develop applications.This is the Master of all DB2 graphical tools We can invoke various DB2 GUI tools directly from the Control Center. Command to invoke Contral Center : db2cc

2. Command Center : Allows you to write and execute DB2 commands and SQL statements interactively. It also lets you write scripts containing DB2 commands &amp; SQL statements and run them immediately or schedule for later execution. Command to invoke Command Center : db2cmdctr

3. Task Center :  Tool to manage the scheduling and execution of DB2 Command and OS scripts. Upon completion of a job, it can create notifications to be sent to e-mail or pager. Command to invoke Task Center : db2tc

4. Journal:  Keeps a running history of all interactive command and script executions submitted using the DB2 GUI tools. Command to invoke Journal : db2journal

5. Memory Visualizer :  Used to monitor the memory allocation of a DB2instance. Command to invoke Memory Visualizer : db2memvis 

6. Health Center: Used to monitor the state and utilization of many parts of the database manager, the databases, and user agents. Command to invoke Health Center : db2hc

7. Development Center :  It has the features and functions that make it easier for developers to build and deploy applications for either Java or Microsoft environments. The Stored Procedure Builder has been included in the Development Center. Command to invoke Development Cente : db2dc 

8. Configure Assistance :  The Configuration Assistant has many new features. One is to connect &amp; access the remote data base locally using TCP/IP . Command to invoke Configure Assistance : db2memvis

9. Replication Center :  We can use to set up and administer our replication environment which include DB2-to-DB2 replication and DB2 and non-DB2 relational databases. Command to invoke Replication Center : db2rc 

10. Information Center : Provides quick access to DB2 product information and is available on all OS for which the DB2 administration tools are available. Command to invoke Information Center : db2ic 

11. Data Studio Client : In latest version, DB2 control center in replaced with Data Studio Client. You may need to install the Data Studio Client separately.

 To start, Data Studio Client, Change to the home directory where you have installed DataStudio. Then run eclipse.exe 

For example : F:\Program Files\IBM\DSWC4.1>Eclipse.exe


Commands in Brief :

Control Center : db2cc 
Command Center : db2cmdctr 
Configuration Assistance : db2ca 
Health Center : db2hc 
Task Center : db2tc 
Development Center : db2dc 
Journal :  db2journal 
Memory Visualizer : db2memvis 
Information Center : db2ic 
Replication Center : db2rc 
Data Studio : eclipse.exe

The commands can be used in both Linux &amp; Windows environment. The command can be run in db2 command prompt window .

In windows you can get the command prompt (command line processor (CLP)) by running the command db2cmd.

In Linux,  to invoke the DB2 CLP or issue DB2 command directly from the Linux command prompt, we need to run the db2profile in the profile of the login user ID. For that we need to include the following line in login profile. INSTHOME/sqllib/db2profile Where INSTHOME is the DB2 instance home directory.

How to Write own Java user-defined functions in DB2 & call UDFs in DB2 SQL with Example Step by Steps

            User Defined Functions (UDFs) are own functions written by the user which can be used in SQL, DDL or DML statements. UDfs can be written in two ways on DB2 Universal Database. One is SQL UDFs which is based on procedural extensions to the SQL language, highly used by other DBMS. The Other one is External UDFs which is written host languages like Java and others. Now let us write a user defined function in Java which can be used in in SQL. For example, In oracle INITCAP function returns the first letter of each word in uppercase, all other letters will be in lowercase. This function may not be available in DB2. Now we can write this function in Java can be used in DB2 .

Steps involved to write, deploy and run the UDFs

1. Write program for initCaps in Java

import java.io.*;
import java.io.*;
public class initCaps
{
public static String firstCaps(String line)  throws IOException 
{
 StringReader in = new StringReader(line); 
 boolean isNextCharSpace = true;
 StringBuffer proper = new StringBuffer();    
int i=0;
     while((i=in.read())!=-1) 
 {      
      char c = (char)i;      
      if (c == ' ')  {      proper.append(c);      isNextCharSpace = true;     } 
......
.....
}
}


Now compile the above program .
E:\DB2\IBM\SQLLIB\java\jdk\bin> javac initCaps.java

You can have more function in the same java file. Please ensure the java file is compiled and running using the same java version.

Covert the class file to Jar file by using the following command
jar cf myjar6.jar initCaps.class

Now register the jar file in DB2 using the following steps
Open the DB2 command prompt , then run the following command

CALL SQLJ.INSTALL_JAR('file:E:\DB2\IBM\SQLLIB\java\jdk\bin\myjar6.jar',testjar);

      By running the above command, the testjar.jar is file is copied to E:\DB2\IBM\SQLLIB\FUNCTION\jar\Schema Name\

Now Create a user-defined function in Db2 using Create Function



CREATE FUNCTION firstCaps(source varchar(3000)) RETURNS varchar(3000) LANGUAGE JAVA DETERMINISTIC NO SQL NOT FENCED EXTERNAL NAME 'testjar:initCaps!firstCaps' PARAMETER STYLE JAVA NO EXTERNAL ACTION

              where firstCaps is the function name which accepts string variable and returns a string variable. testjar is the jarfile name. initCaps is the Class file name. Again firstCaps used in External Name is the Java Method name. The string variable passed to the firstCaps function is passed to Java Method then processed and returns the Proper case of the string.

Now let us write the SQL query using the above user defined function.

select SchemaName.firstCaps(empname) from emp

Some of the Trouble shooting :

         You may get the error : SQL4301N Java or .NET interpreter startup or communication failed, reason code "0". SQLSTATE=58004
          Please check JDK_PATH by the command

In windows :             db2 get dbm cfg | find "JDK".
In Linux :               db2 get dbm cfg | grep -i JDK


The JDK_PATH is one level up to bin directory. So Update the path using the following command.

db2 update dbm cfg using JDK_PATH = E:\DB2\IBM\SQLLIB\java\jdk

           If the above error with reaon code "4" means you can check JAVA_HEAP_SZ. It should be enough to handle the User Defined function / Stored Procedure. 512 may be enough to handle. You can change the value using the following command.

db2 update dbm cfg using JAVA_HEAP_SZ 4096

Java stored procedure or user-defined function could not load Java class reason code "1". SQLSTATE=42724

Class Name mentioned in the Create Function may be mis-spelled. This error may be generated using java.lang.UnsupportedClassError. You have to ensure you are compiling and running the java class file using the same jdk version. Error may be seen E:\DB2\IBM\SQLLIB\DB2\db2dialog.log.

If No errors, then the statement select SchemaName.firstCaps(empname) from emp will give the output. Suppose the database having the employee names akash kumar, Micky jen, jackson Durai.

The output will be
Akash Kumar
Micky Jen
Jackson Durai

Monday, November 10, 2014

How to call db2 stored procedure from java program with example?

JDBC provides three statement interface which is used to send an SQL statement to the database server.

1. Statement
2. PreparedStatement which extends Statement
3. CallableStatement which extends PreparedStatement

Vendors of JDBC Driver provide classes that implement the above interfaces. Without a JDBC driver, you cannot create objects based on these interfaces. Database connection is required to to create statement object. This tutorial explains about CallableStatement objects and also how to call a DB2 stored procedure from a java application. Please go through my earlier post on how to create stored procedure in db2. Stored procedure can be called using the SQL CALL statement in DB2. Now how to call the stored procedures located on the database server from your Java application?

Using CallableStatement interface in java:

      CallableStatement object enable you to call and execute stored procedures stored on the database server from your Java application. Three types of JDBC parameters are there. They are IN, OUT, and INOUT

1. IN - parameters used for input. You can set values to IN parameters with the setXXX() methods.
2. OUT - result parameter used for output which returns output value of the stored procedure.
3. INOUT - parameter used for both input and output values parameters

A question mark (?) symbol serves as a placeholder for a parameter. The call to invoke the Stored procedure is written in an JDBC escape syntax that may take the followings forms

1. {call procedure_name[(?, ?, ...)]} - which accepts input parameters but no result parameter
2. {? = call procedure_name[(?, ?, ...)]} which returns a result parameter
3. {call procedure_name} - for no input / output parameters

A CallableStatement can return one or multiple ResultSet objects. Multiple ResultSet objects are handled using operations inherited from Statement.
                            cstmt.getMoreResults(); -used to point to the second or next result set.

Now let us see the steps to create a CallableStatement Object. Before creating it, let us create a stored procedure in DB2. In our example, I have created two Stored procedures in db2.

Ist Stored Procedure (SP) example : to return all records matching with a given salesman_id and date of sale
      input - salesmanid, sales_date
      output - result set (salesman_id, salesman, item_name , sales_date, sales_amt)

Stored Procedure for the above problem is given below

Stored Procedure I:
    
CREATE PROCEDURE  ItemSalesBy (salesmanid  varchar(5), dateofsale date)     SPECIFIC sp10    DYNAMIC RESULT SETS 1 
P1: BEGIN
    DECLARE cursor1 CURSOR WITH RETURN FOR   select salesman_id, (select c.name from salesman c where c.salesman_id=b.salesman_id) SalesMan,  (select a.item_name from item_master a where a.item_code=b.item_code) ItemName, sales_date, sales_amt from salesmantxn b  where b.salesman_id=salesmanid and b.sales_date=dateofsale;
    OPEN cursor1;
END P1 
@


We can create and call (execute) the above stored procedure using command line processor (CLP) and through java program.

To create stored procedure using CLP, store above stored procedure in a file . for example salesman.sql . Now run the following commands

db2 connect to test
db2 -td@ -vf salesman.sql


to call the above SP through CLP

db2 call ItemSalesBy('101','2012-02-25'), where 101 is the salesman id, 2012-02-25 is the date of sale
Now let us create and call (execute) the above stored procedure using java program

To create CallableStatement object, the following statements are used

CallableStatement cstmt = null;
cstmt = conn.prepareCall ("{ call ItemSalesBy(?,?)}"); 
// Callablestatement object to call the stored procedure

           where ItemSalesBy is the SP name and two question mark (?,?) is used to pass input parametters. In our example, salesman_id , sales_date. The following java program drops the existing SP named ItemSalesBy and creates the same SP and executes with the given input parameters. The statement

              ResultSet rs = cstmt.executeQuery();       returns the result set returned by the SP.
    

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

public class CSPRS2 {
    static Connection conn; 
    public static void main(String[] args) {
     
       try {
                    //Class.forName("COM.ibm.db2.jdbc.app.DB2Driver");

                      Class.forName("com.ibm.db2.jcc.DB2Driver");

} catch (ClassNotFoundException e) 

                  {
                     e.printStackTrace();

                     return;

                   }

       try
        {
               conn = DriverManager.getConnection("jdbc:db2:test");
            }
        catch( Exception e )
        {
            e.printStackTrace();
            System.exit(1);
        }


  //  dropSP(); // to drop procedure if already exists  

    createSP();  // to create stored procedure (SP)


    callSP("101", "2012-02-25"); // to execute SP
    }


   private static void dropSP() {
        String str=null;
        Statement stmt = null;
        try 
        {
            stmt = conn.createStatement();
           str="drop procedure ItemSalesBy";
            stmt.executeUpdate (str);
        } 
        catch (SQLException e1) 
        { e1.printStackTrace();}
       }

 

  private static void createSP() {
        String strSP=null;
        Statement stmt = null;

   strSP="CREATE PROCEDURE  ItemSalesBy (salesmanid  varchar(5), dateofsale date)  SPECIFIC sp10    DYNAMIC RESULT SETS 1 \n" +
             "P1: BEGIN \n" +
             "DECLARE cursor1 CURSOR WITH RETURN FOR   select salesman_id, (select c.name from salesman c  where c.salesman_id=b.salesman_id) SalesMan,  (select a.item_name from item_master a where a.item_code=b.item_code) ItemName, sales_date, sales_amt from salesmantxn b  where  b.salesman_id=salesmanid and b.sales_date=dateofsale; \n" +
             "OPEN cursor1; \n" +
              "END P1 \n";
   

     try
        {
            stmt = conn.createStatement();
            stmt.executeUpdate (strSP);
            System.out.println("Stored Procedure created successfully\n");
        }
        catch (SQLException e)
        {
            System.out.println("Error in creating SP: " + e.toString());
            System.exit(1);
        }  
    }


    private static void callSP(String sid, String sdate) 
    {
        CallableStatement cstmt = null;
        try 
        {
            cstmt = conn.prepareCall ("{ call ItemSalesBy(?,?)}");  // CallableStatement object  to call the stored procedure 
            cstmt.setString(1,sid);
            cstmt.setDate(2, java.sql.Date.valueOf(sdate));
            ResultSet rs = cstmt.executeQuery();
            System.out.println("SALESMAN_ID SALESMAN              ITEMNAME      SALES_DATE    SALES_AMT\n");
            System.out.println("----------- ---------------- ------------------- ----------  ------------\n");
         

   if (rs != null) {        

          while (rs.next())
           {
             System.out.println(rs.getInt(1) + "             " + rs.getString(2) + "       " + rs.getString(3) + "      " + rs.getString(4) +"       "+rs.getString(5));
            }
           }
        } 
        catch (SQLException e) 
        {
            e.printStackTrace();
        }
    }
}
Output :


Stored Procedure II: To calculate wages for a salesman on a particular date based on sales_amt. wages is calculated with the following formula wages = total_sales_amt * 0.5 /100 + bonus ; and Rs. 100 bonus is added if the sales_amt &gt;10000 and sales_amt<=200000, Rs. 200 bonus if sales_amt>200000 and sales_amt<=300000 , Rs. 300/- bonus if sales_amt>300000 IN Parameter : salesman_id, Sales_date OUT parameter : wages Stored Procedure for the above problem is given below

    
CREATE PROCEDURE wagesCalc(IN salesmanid varchar(5),IN SalesDate date , OUT  wages  double)   LANGUAGE SQL
  BEGIN
     DECLARE bonus double;
     DECLARE sumsales double;
     DECLARE wages_temp double;
     DECLARE cursor1 CURSOR FOR SELECT SUM(SALES_AMT),  SUM(SALES_AMT)*0.5/100 FROM SALESMANTXN where SALESMAN_ID=salesmanid  and SALES_DATE=SalesDate;
      SET bonus= 0;
     OPEN cursor1;
     FETCH FROM cursor1 INTO sumsales, wages_temp;
    
  IF (sumsales&gt;300000) THEN
     set bonus=300;
  ELSEIF (sumsales&gt;200000 and sumsales<=300000) THEN
     set bonus=300;
  ELSEIF (sumsales&gt;100000 and sumsales<=200000) THEN
    set bonus=100;
  END IF;
     CLOSE cursor1;
 SET wages = wages_temp+ bonus; 
 END%  

               to create above SP using CLP , store above stored procedure in a file . eg. wages.sql . Now run the following commands db2 connect to test db2 -td% -vf wages.sql to call the above SP through CLP db2 call wagesCalc('101', '2012-02-25', ?), which returns wages for the saleman_id=101 and sales_date='2012-02-25' Now let us see how to call (execute) the above stored procedure using java program

     private static void callSP(String sid, String sdate) 
        {
          Double wages=0.0;
          CallableStatement cstmt = null;
        try 
        {
            cstmt = conn.prepareCall ("{ call wagesCalc(?,?,?)}");  // CallableStatement object  to call the stored procedure 
            cstmt.setString(1,sid);
            cstmt.setDate(2, java.sql.Date.valueOf(sdate));
            cstmt.registerOutParameter(3, Types.DOUBLE);
            cstmt.execute();
            wages  = cstmt.getDouble(3);
               System.out.println("Sales Man Id = " + sid  + " Wages= " + wages);
        } 
        catch (SQLException e) 
        {
            e.printStackTrace();
        }
    } 
         
   Output of the above program : 

D:\as2\JF5>java CSPRS4 Sales Man Id = 101 Wages= 650.0

          In the above program, registerOutParameter(3, Types.DOUBLE); Registers the OUT parameter in ordinal position parameterIndex to the JDBC type sqlType The execute() returns boolean value. if it returns false means, first result is an update count or there is no result; true means, the first result is a ResultSet object