Thursday, August 29, 2019

Java: Passing Array to Oracle 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.ArrayDescriptorclass 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.

Tuesday, August 20, 2019

Memory Scope For ADF Managed Beans-As per Fusion Developer guide

Memory Scope of the managed bean is a very important aspect while developing applications, so it is necessary to clearly understand memory scope of managed bean-
As per Fusion Developer’s Guide for Oracle Application Development Framework 11g Release 1 (11.1.1)

Application Scope-
The application scope lasts until the application stops. Values that you store in a managed bean with this scope are available to every session and every request that uses the application.
Avoid using this scope in a task flow because it persists beyond the lifespan of the task flow.
Session Scope-
The session scope begins when a user first accesses a page in the application and ends when the user’s session times out due to inactivity, or when the application invalidates the session.
Use this scope only for information that is relevant to the whole session, such as user or context information. Avoid using it to pass values from one task flow to another. Instead, use parameters to pass values between task flows. Using parameters gives your task flow a clear contract with other task flows that call it or are called by it. Another reason to avoid the use of session scope is that it may persist beyond the lifespan of the task flow.
Pageflow Scope-
Choose this scope if you want the managed bean to be accessible across the activities within a task flow. A managed bean that has a pageFlow scope shares state with pages from the task flow that access it. A managed bean that has a pageFlow scope exists for the lifespan of the task flow. If another task flow’s page references the managed bean, the managed bean creates a separate instance of this object and adds it to the pageFlow scope of its task flow.
View Scope-
Use this scope for managed bean objects that are needed only within the current view activity and not across view activities. It defines the scope for each viewport that ADF Controller manages, for example, a root browser window or an ADF region.
The lifespan of this scope begins and ends when the current viewId of a viewport changes. If you specify view, the application retains managed bean objects used on a page as long as the user continues to interact with the page. These objects are automatically released when the user leaves the page.
 
Request Scope-
Use request scope when the managed bean does not need to persist longer than the current request.
Backing Bean Scope-
A backing bean is a convention to describe a managed bean that stores accessors for UI components and event handling code on a JSF page. It exists for the duration of a request and should not be used to maintain state.
Use this scope if it is possible that your task flow appears in two ADF regions on the same JSF page and you want to isolate each instance of ADF region.

Tuesday, August 13, 2019

single check box check at a time in a af:table

public void singleChk(ValueChangeEvent vce){
        vce.getComponent().processUpdates(FacesContext.getCurrentInstance());  
        
        DCBindingContainer bindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
        // Get an object representing the table and what may be selected within it
        DCIteratorBinding dcItteratorBindings1 = bindings.findIteratorBinding("DepartmentsVO1Iterator");
        // FacesContext context = FacesContext.getCurrentInstance();
        BindingContext bindingContext = BindingContext.getCurrent();
        DCDataControl dc =
            bindingContext.findDataControl("AppAMModuleDataControl"); // Name of application module in datacontrolBinding.cpx
        AppAMModuleImpl appM = (AppAMModuleImpl)dc.getDataProvider();
     
        ViewObject voTableData1= appM.findViewObject("DepartmentsVO1"); 
        Row currRow = voTableData1.getCurrentRow(); 
        Integer deptid = (Integer)currRow.getAttribute("DepartmentId");
        Row r[] = voTableData1.getFilteredRows("TSelect", "Y");
       if(r.length>0){
        for(Row rselect : r){
            Integer deptidSelect = (Integer)rselect.getAttribute("DepartmentId");
            if(deptid!=deptidSelect){
                rselect.setAttribute("TSelect", "N");
            }
        }
}
        
        AdfFacesContext.getCurrentInstance().addPartialTarget(sbc1);  
        AdfFacesContext.getCurrentInstance().addPartialTarget(t1);
    }



-------------------------------
below one failing in few cases
public void chk_vc(ValueChangeEvent vce) {
     
     
        try{
        vce.getComponent().processUpdates(FacesContext.getCurrentInstance());
          ViewObject vo=  ReusableMethodsClassCredit.getAM().findViewObject("WriteoffReviewDtlVO1");
          Row r1=  ReusableMethodsClassCredit.getCurrentRowFromVO("WriteoffReviewDtlVO1");
   
        String chk = (String)r1.getAttribute("TselectALLNONE");
            System.out.println(" r1 chk "+chk);
        if ("Y".equals(chk)) {
       
            int cnt = vo.getRowCount();
            System.out.println("current row count "+cnt);
            Row r = null;
            for (int i = 1; i <= cnt; i++) {
                if (i == 1) {
                    System.out.println("going to first ");
                    r = vo.first();
                  //  System.out.println("going to first "+r.getAttribute("AcctNo"));
                } else {
                    System.out.println("going to next ");
                    r = vo.next();
                 //   System.out.println("going to next "+r.getAttribute("AcctNo"));
                }
           
                r.setAttribute("TselectALLNONE", "N");
               // System.out.println("---note gen afterset --TselectPend- r-" + r.getAttribute("TselectPend")+r.getAttribute("AcctNo"));
                RichSelectBooleanCheckbox box =this.getSbc1();
               // box.setValue("N");
            }
            r1.setAttribute("TselectALLNONE", "Y");
         //   System.out.println("---note gen afterset --TselectPend- r1-" + r1.getAttribute("TselectPend")+r1.getAttribute("AcctNo"));
         
           AdfFacesContext.getCurrentInstance().addPartialTarget(sbc5);
            AdfFacesContext.getCurrentInstance().addPartialTarget(t1);
        }
        }catch (Exception e) {
                BindingContext bctx = BindingContext.getCurrent();
                ((DCBindingContainer)bctx.getCurrentBindingsEntry()).reportException(e);
         
        }
    }

Monday, August 5, 2019

Duplicate checking

    public boolean dupValidate(String p_prodcode) {        
 System.out.println("Duplicate Validtion 1");         
ViewObjectImpl vo = (ViewObjectImpl)CommonCode.getAM().findViewObject("PiProdPriceDefnVO2");         Row cRow = vo.getCurrentRow();         // Create a Iterator to Iterate Over the ViewObject Vo         
// There is a also a method called vo.getRowSetIterator() but it is advised to use //vo.createRowSetIterator(null)         
Integer count = 0;        
 RowSetIterator rsi = vo.createRowSetIterator(null);         
while (rsi.hasNext()) {             
Row rw = rsi.next();             
if(rw != cRow){                
 if (rw.getAttribute("ProdCode") != null) {                   
String prod = (String)rw.getAttribute("ProdCode");                    
 System.out.println("getattrib " + prod + " vceprod " + p_prodcode);                     if(prod.equalsIgnoreCase(p_prodcode)){                     
count = 1;                     
}                
 }             
}       
  }        
 // Closing the iterator is advised after the use          
rsi.closeRowSetIterator();                 
 if(count == 1){            
 CommonCode.errmsg("Product code "+p_prodcode+" cannot be duplicate","");             
return true;        
 }         
return false;         
    }
------------------------------------
checking at ValueChangeEvent
   ------------------------------
                if (dupValidate((String)vce.getNewValue())) { // checking duplicate rows                    System.out.println("Trying to clear product");               
                setProdCodeNull(rdtl);                   
                return;          
       }
--------------------------------
    public void setProdCodeNull(Row currenttFow){         
currenttFow.setAttribute("ProdCode",null);        
 currenttFow.setAttribute("CurPrice",null);         
currenttFow.setAttribute("CurFromDt",null);         
currenttFow.setAttribute("CurToDt",null);         AdfFacesContext.getCurrentInstance().addPartialTarget(getProdCodeId());       //  AdfFacesContext.getCurrentInstance().addPartialTarget(getT1());   
          }