Posts Tagged ‘Stored procedure’

This tutorial guides us on how to pass Array objects from Java to stored procedures in Oracle and also, how to retrieve an array object in Java.

All PLSQL arrays can not be called from java. An array needs to be created as TYPE, at SCHEMA level in the database and then it can be used with ArrayDescriptor in Java, as oracle.sql.ArrayDescriptor class in Java can not access at package level.

Database Code

First, Create an array, at SCHEMA level. An example is shown below:

CREATE TYPE array_table AS TABLE OF VARCHAR2 (50); -- Array of String
CREATE TYPE array_int AS TABLE OF NUMBER;          -- Array of integers

Next, Create a procedure which takes an array as an input parameter and returns an array as its OUT parameter.

An example of one such procedure is shown below, which has 2 parameters –

  1. an array of String as its IN parameter – p_array
  2. an array of Integers as OUT parameter – p_arr_int
CREATE OR REPLACE PROCEDURE SchemaName.proc1 (p_array     IN     array_table,
                                              len            OUT NUMBER,
                                              p_arr_int      OUT array_int)
AS
   v_count   NUMBER;
BEGIN
   p_arr_int := NEW array_int ();
   p_arr_int.EXTEND (10);
   len := p_array.COUNT;
   v_count := 0;
   FOR i IN 1 .. p_array.COUNT
   LOOP
      DBMS_OUTPUT.put_line (p_array (i));
      p_arr_int (i) := v_count;
      v_count := v_count + 1;
   END LOOP;
END;
/

After this, Execution permission would be required to execute the procedure created by you:

GRANT EXECUTE ON SchemaNAme.proc1 TO UserName;

Java Code

Create a java class which makes a call to the procedure proc1, created before.

Below is an example which contains the whole flow from creating a connection with the database, to making a call to the stored procedure, passing an array to Oracle procedure, retrieving an array from an Oracle procedure and displaying the result.

import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Types;
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.internal.OracleTypes;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;
public class TestDatabase {
    
    public static void passArray()
    {
        try{
        
            Class.forName("oracle.jdbc.OracleDriver");         
            Connection con = DriverManager.getConnection("jdbc:oracle:thin:url ","UserName","Password");;
            
            String array[] = {"one", "two", "three","four"};
            
            ArrayDescriptor des = ArrayDescriptor.createDescriptor("SchemaName.ARRAY_TABLE", con);
            ARRAY array_to_pass = new ARRAY(des,con,array);
            
            CallableStatement st = con.prepareCall("call SchemaName.proc1(?,?,?)");
            // Passing an array to the procedure -
            st.setArray(1, array_to_pass);
            st.registerOutParameter(2, Types.INTEGER);
            st.registerOutParameter(3,OracleTypes.ARRAY,"SchemaName.ARRAY_INT");
            st.execute();
            
            System.out.println("size : "+st.getInt(2));
            // Retrieving array from the resultset of the procedure after execution -
            ARRAY arr = ((OracleCallableStatement)st).getARRAY(3);
             BigDecimal[] recievedArray = (BigDecimal[])(arr.getArray());
            for(int i=0;i<recievedArray.length;i++)
                System.out.println("element" + i + ":" + recievedArray[i] + "\n");
            
        } catch(Exception e) {
            System.out.println(e);
        }
    }
    public static void main(String args[]){
        passArray();
    }
}

Brief Explanations:

  1. Class.forName() – Returns the Class object associated with the class or interface with the given string name.
  2. DriverManager.getConnection() – Attempts to establish a connection to the given database URL.
  3. oracle.sql.ArrayDescriptor – Describes an array class
  4. ArrayDescriptor.createDescriptor() – Descriptor factory. Lookup the name in the database, and determine the characteristics of this array.
  5. oracle.sql.ARRAY – An Oracle implementation for generic JDBC Array interface.
  6. CallableStatement – The interface used to execute SQL stored procedures.

References

The Microsoft Visual Studio .NET logo.

Let us see how can we create and call Stored procedures, in a .NET Environment, i.e Visual Studio.We use .NET 2.0 and Visual Studio 2005 for all the examples.fs

Writing stored procedures has never been easy as Microsoft has almost integrated SQL Server with Visual Studio 2005. In the past most of the developers has wondered can’t we have a good editor for creating stored procedures. One of the main advantage of creating procedures in Visual Studio is it creates the basic stub for you and further more, it has inbuilt syntax checking which makes the job easier for us.

In order to create a stored procedure from Visual Studio, first you need to create a data connection from the Server Explorer and follow the below steps.

Step 1: Open Visual Studio 2005.

Step 2: Create a VB.NET / C# Windows / Web Application  Project.

Step 3: Open the Server Explorer by Selecting View -> Server Explorer.

stored_procedures_VB.NET

Step 4: Create a Data Connection to your server you can do this by Right Clicking on the Data Connection Tree and Selecting “Add New Connection”.

Step 5: It will Prompt for the Provider Type you can select .NET SQL Server Provider as it gives more performance.

Step 6: After giving all the credentials once the connection is active expand the database that you are having.

Step 7: Expand the Stored Procedure Tree.

Step 8: To Create a New Procedure Right Click and Select “Add New Procedure”.

Step 9: The IDE will give you a Stub where you can replace the Name of the Procedure and Arguments.

Those who are familiar with Visual Studio IDE would love to create procedures here rather then doing it in Query Analyzer or in SQL Enterprise Manager, though it doesn’t provide any fancy auto complete drop downs its still the best I believe to create stored procedures.

TIP: The Maximum number of parameters in a stored procedure is 2100.

Calling Stored Procedure

Hope everyone have used SQLCommand / OLEDB Command objects in .NET. Here we can call stored procedures in two different forms, one without using parameter objects which is not recommended for conventional development environments, the other one is the familiar model of using Parameters.

In the first method you can call the procedure using Exec command followed by the procedure name and the list of parameters, which doesn’t need any parameters.

Example:

Dim SQLCon As New SqlClient.SqlConnection
SQLCon.ConnectionString = “Data Source=Server;User ID=User;Password=Password;”
SQLCon.Open()

Calling Stored Procedures with Exec command

SQLCmd.CommandText = “Exec SelectRecords ‘Test’, ‘Test’, ‘Test'”
SQLCmd.Connection = SQLCon ‘Active Connection

The second most conventional method of calling stored procedures is to use the parameter objects and get the return values using them. In this method we need to set the “SQLCommandType” to “StoredProcedure” remember you need to set this explicitly as the the default type for SQLCommand is SQLQuery”.

Here is an example to call a simple stored procedure.

Example – I (A Stored Procedure Returns Single Value)

In order to get XML Results from the Stored Procedure you need to first ensure that your stored procedure is returning a valid XML. This can be achieved using FOR XML [AUTO | RAW | EXPLICIT] clause in the select statements. You can format XML using EXPLICIT Keyword, you need to alter your Query accordingly

‘Set up Connection object and Connection String for a SQL Client
Dim SQLCon As New SqlClient.SqlConnection
SQLCon.ConnectionString = “Data Source=Server;User ID=User;Password=Password;”
SQLCon.Open()SQLCmd.CommandText = “SelectRecords” ‘ Stored Procedure to Call
SQLCmd.CommandType = CommandType.StoredProcedure ‘Setup Command Type
SQLCmd.Connection = SQLCon ‘Active Connection

The procedure can be called by adding Parameters in at least two different methods, the simplest way to add parameters and respective values is using

SQLCmd.Parameters.AddWithValue(“S_Mobile”, “Test”)
SQLCmd.Parameters.AddWithValue(“S_Mesg”, “Test”)
SQLCmd.Parameters.AddWithValue(“LastMsgID”, “”)

In this above method, you doesn’t necessarily know the actually data type that you had in your procedure and all parameters are validated according to the type declared in your procedure but only thing is all the validations will occur in SQL and not in your client code.

We still need to declare the last parameter as Output and we need to do that explicitly as the default type is Input. So here we are going to declare the last parameter as Output by

SQLCmd.Parameters(“LastMsgID”).Direction = ParameterDirection.Outputfs

If you want to declare parameters properly then you need to use the below method to add all the parameters with its data type, direction. Also if you are using stored procedures to update all the rows in a dataset then you need to declare parameters in the below fashion and give SouceColumn value as the Column name in the DataTable.

SQLCmd.Parameters.Add(New SqlClient.SqlParameter(“S_Mobile”, SqlDbType.VarChar, 10, ParameterDirection.Input, False, 30, 0, “”, DataRowVersion.Current, “91000000000”))SQLCmd.Parameters.Add(New SqlClient.SqlParameter(“S_Mesg”, SqlDbType.VarChar, 160, ParameterDirection.Input, False, 30, 0, “”, DataRowVersion.Current, “Calling Stored Procedures from VB.NET”))

SQLCmd.Parameters.Add(New SqlClient.SqlParameter(“LastMsgID”, SqlDbType.BigInt, 5, ParameterDirection.Output, False, 5, 0, “”, DataRowVersion.Current, 0))

‘ The Above Procedure has two input parameters and one output parameter you can notice the same in the “Parameter Direction”
SQLCmd.ExecuteNonQuery() ‘We are executing the procedure here by calling Execute Non Query.

MsgBox(SQLCmd.Parameters(“LastMsgID”).Value) ‘You can have the returned value from the stored procedure from this statement. Its all similar to ASP / VB as the only difference is the program structure.

Example – II (Stored Procedure to get Table Result Set)

In order to get the result sets from the stored procedure, the best way is to use a DataReader to get the results. In this example we are getting the results from the Stored Procedure and filling the same in a DataTable.

Here we need to additionally declare a SQLDataReader and DataTable

Dim SQLDBDataReader As SqlClient.SqlDataReader
Dim SQLDataTable As New DataTableSQLCmd.CommandText = “GetAuthors”
SQLCmd.CommandType = CommandType.StoredProcedure
SQLCmd.Connection = SQLCon
SQLCmd.Parameters.Add(New SqlClient.SqlParameter(“AuthorName”, SqlDbType.VarChar, 100, ParameterDirection.Input, False, 30, 0, “”, DataRowVersion.Current, “Y%”)) SQLDBDataReader = SQLCmd.ExecuteReader() SQLDataTable.Columns.Add(“AuthorName”, GetType(Int32), “”) SQLDataTable.Columns.Add(“AuthorLocation”, GetType(String), “”)

Dim FieldValues(1) As Object ‘A Temporary Variable to retrieve all columns in a row and fill them in Object array

While (SQLDBDataReader.Read)
SQLDBDataReader.GetValues(FieldValues)
SQLDataTable.Rows.Add(FieldValues)

End While

Example – III (Calling Simple Stored Procedure to get XML Result Set)

In order to get XML Results from the Stored Procedure you need to first ensure that your stored procedure is returning a valid XML. This can be achieved using FOR XML [AUTO | RAW | EXPLICIT] clause in the select statements. You can format XML using EXPLICIT Keyword, you need to alter your Query accordingly.

CREATE PROCEDURE GetRecordsXML (@AuthorName varchar(100))
ASSelect Author_ID, Author_Name, Author_Location Where Author_Name LIKE  @AuthorName from Authors FOR XML AUTO

RETURN

When you use the above procedure you can get XML Results with TableName as Element and Fields as Attributes

Dim SQLXMLReader As Xml.XmlReader

SQLCmd.CommandText = “GetAuthorsXML”
SQLCmd.CommandType = CommandType.StoredProcedure
SQLCmd.Connection = SQLCon
SQLCmd.Parameters.Add(New SqlClient.SqlParameter(“AuthorName”, SqlDbType.VarChar, 100, ParameterDirection.Input, False, 30, 0, “”, DataRowVersion.Current, “Y%”))
SQLDBDataReader = SQLCmd.ExecuteReader()

SQLXMLReader = SQLCmd.ExecuteXmlReader()
While (SQLXMLReader.Read)
MsgBox(SQLXMLReader.ReadOuterXml)
End While

You can further process this XML or write XSL to display results in a formatted manner. But in order to get formatted XML Results, we need to use EXPLICIT case which we can see in our next article on SQL Queries & XML.

  

import java.sql.CallableStatement;

import java.sql.Connection;

import java.sql.DriverManager;

public class Main {

  public static void main(String[] argsthrows Exception {

    Connection conn = getOracleConnection();

    // Step-2: identify the stored procedure

    String proc3StoredProcedure = “{ call proc3(?, ?, ?) }”;

    // Step-3: prepare the callable statement

    CallableStatement cs = conn.prepareCall(proc3StoredProcedure);

    // Step-4: set input parameters …

    // first input argument

    cs.setString(1“abcd”);

    // third input argument

    cs.setInt(310);

    // Step-5: register output parameters …

    cs.registerOutParameter(2, java.sql.Types.VARCHAR);

    cs.registerOutParameter(3, java.sql.Types.INTEGER);

    // Step-6: execute the stored procedures: proc3

    cs.execute();

    // Step-7: extract the output parameters

    // get parameter 2 as output

    String param2 = cs.getString(2);

    // get parameter 3 as output

    int param3 = cs.getInt(3);

    System.out.println(“param2=” + param2);

    System.out.println(“param3=” + param3);

    conn.close();

  }

  private static Connection getHSQLConnection() throws Exception {

    Class.forName(“org.hsqldb.jdbcDriver”);

    System.out.println(“Driver Loaded.”);

    String url = “jdbc:hsqldb:data/tutorial”;

    return DriverManager.getConnection(url, “sa”“”);

  }

  public static Connection getMySqlConnection() throws Exception {

    String driver = “org.gjt.mm.mysql.Driver”;

    String url = “jdbc:mysql://localhost/demo2s”;

    String username = “oost”;

    String password = “oost”;

    Class.forName(driver);

    Connection conn = DriverManager.getConnection(url, username, password);

    return conn;

  }

  public static Connection getOracleConnection() throws Exception {

    String driver = “oracle.jdbc.driver.OracleDriver”;

    String url = “jdbc:oracle:thin:@localhost:1521:caspian”;

    String username = “mp”;

    String password = “mp2”;

    Class.forName(driver)// load Oracle driver

    Connection conn = DriverManager.getConnection(url, username, password);

    return conn;

  }

}

           

         

    

  

CallStoresProcedureInOracleAndPassInOutParameters.zip( 3,849 k)