6 Şubat 2018 Salı

JDBC CallableStatement Sınıfı - Stored Procedure Çağırmak İçindir

Giriş
Şu satırı dahil ederiz.
import java.sql.CallableStatement;
Not JDBC: CallableStatement yazısına göz atılabilir. 

Açıklaması şöyle
A CallableStatement in Java is an interface used to call stored procedures. As expected, it’s possible to configure a CallableStatement to accept the required input (IN) parameters by using its utility set<DATA_TYPE>() methods such as setInt(String parameterName, int x).

Conversely, you can also inform the output (OUT) parameters by registering them before a procedure call by using several overloaded registerOutParameter() methods such as registerOutParameter(int parameterIndex, int sqlType).

As soon as a CallableStatement and the corresponding PL/SQL stored procedure are executed, it’s possible to get the output parameters by using several get<DATA_TYPE>() methods, such as getString(int parameterIndex), and a REF CURSOR that is used to retrieve the result set.
Yani
1. CallableStatement ile Stored Procedure/Function çağırılabilir. 
2. Eğer in parametre varsa setXXX() metodları ile atanır
3. Eğer out parametrel varsa önce registerOutPrameter() çağrısı ile parametreler belirtilir. Daha sonra execute() veya executeUpdate() çağrısı ile stored procedure çalıştırılır. getXXX() çağrısı ile out parametrelere erişilir.

Kullanım
Örnek - Stored Procedure Çağırma
Aşağıdaki kodda bir stored procedure çağrılıyor.
String sql = "{call getEmpName (?, ?)}";  
cstmt = conn.prepareCall (sql);
Örnek - Stored Function Çağırma
Aşağıdaki kodda bir stored function çağrılıyor.
String sql = "{? = call getEmpName (?, ?)}";  
cstmt = conn.prepareCall (sql);
Örnek - In ve Out Parametre
Elimizde şöyle bir PL/SQL olsun
CREATE OR REPLACE PROCEDURE INSERT_EMPLOYEE_PRC
(
  in_emp_id IN EMPLOYEE.EMP_ID%TYPE,
  in_name IN EMPLOYEE.NAME%TYPE,
  in_role IN EMPLOYEE.ROLE%TYPE,
  in_department IN EMPLOYEE.DEPARTMENT%TYPE,
  in_building IN EMPLOYEE.BUILDING%TYPE,
  out_result OUT VARCHAR2)
AS
BEGIN
  INSERT INTO EMPLOYEE (EMP_ID, NAME, ROLE, DEPARTMENT, BUILDING)
  VALUES(in_emp_id, in_name, in_role, in_department, in_building);
  COMMIT;
  out_result := 'TRUE';
EXCEPTION
  WHEN OTHERS THEN
  out_result := 'FALSE';
  ROLLBACK;
END;
GRANT EXECUTE ON INSERT_EMPLOYEE_PRC TO JDBCSP_USER;
Şöyle yaparız
try (CallableStatement stmt = connection
      .prepareCall("{call ADMIN.INSERT_EMPLOYEE_PRC(?,?,?,?,?,?)}")) {

  // set IN parameters
  stmt.setInt(1, id);
  stmt.setString(2, name);
  stmt.setString(3, role);
  stmt.setString(4, department);
  stmt.setString(5, building);

  // register OUT parameter
  stmt.registerOutParameter(6, java.sql.Types.VARCHAR);

  stmt.executeUpdate();

  // get OUT parameter
  String result = stmt.getString(6);
  ...
}
? Parametreleri Nasıl Kullanılır
CallableStatement ile ? işaretlerini ile belirtilen parametrelere erişmek için indeks 1'den başlatılır.
Ayrıca JDBC ile sadece SQL tiplerine erişilebilir. PL/SQL ile yaratılan tiplere erişilemez.

Aşağıdaki kod parçasında 1. parametre in string olduğu için setString (1,"") ile değeri atanıyor.
2. parametre out olduğu için registerOutParameter ile integer olduğu belirtiliyor.
public String execStoredProcedure(){
  Connection conn = null;
  CallableStatement cs = null;
  ResultSet rs = null;            
  try{
   conn = getConnection();
   cs = conn.prepareCall("{call myproc (?,?)}");
   cs.registerOutParameter(2, -10);
   cs.setString(1, ApplicationProperties.loggedUser);
   cs.execute();
   rs = (ResultSet)l_CStatement.getObject(2);
  }catch (SQLException se){
     ...
  }
 }
constructor
Örnek
Parametresiz Stored Procedure için şöyle yaparız.
CallableStatement cs = con.prepareCall("{call your_procedure()}");
Örnek
İki parametre alan Stored Procedure için şöyle yaparız.
CallableStatement cs = con.prepareCall("{call your_procedure(?,?)}");
Örnek
Elimizde iki tane parametre alan stored procedure olsun.
CREATE PROCEDURE show_data(IN FULLNAME VARCHAR(50), IN ADDRESS VARCHAR(50))
PARAMETER STYLE JAVA
LANGUAGE JAVA
READS SQL DATA
EXTERNAL NAME 'Frame.searchButton'
BEGIN

INSERT INTO SAMPLEONLY("FULLNAME", "ADDRESS") 
  VALUES (FULLNAME , ADDRESS);  

  COMMIT;

END;
Çağırmak için şöyle yaparız.
String storedProc = "{call show_data(?,?)}";
Connection conn = ...;
CallableStatement cst = con.prepareCall(storedProc);
execute metodu
Select yapan stored procedure çağrısını işletir. Şöyle yaparız.
cst.execute();
executeUpdate metodu
Veri tabanına güncelleme yapan (insert,update) stored procedure metodunu işletir.
// execute store procedure
cst .executeUpdate(); 
getArray metodu
Şöyle yaparız.
cs.registerOutParameter (4, OracleTypes.ARRAY,"NUMBER_TAB_TYPE");
...
cs.execute();
java.sql.Array arr = cs.getArray (4);
İçindeki nesneleri Java nesnelerine çevirmek için şöyle yaparız.
BigDecimal[] projDetailsId = (BigDecimal[])arr.getArray();
registerOutParameter metodu
Örnek
Şöyle yaparız.
cts.registerOutParameter(2, Types.INTEGER);
Sonucu şöyle alırız.
int result = cts.getInt(2);
Örnek
Şöyle yaparız.
cst.registerOutParameter(2, Types.VARCHAR);
Örnek
Şöyle yaparız.
cst.registerOutParameter(2, java.sql.Types.ARRAY);
Sonucu getArray () ile alırız.

Örnek
Veri tabanından en fazla 1000 tane uzunluğunda dbms_output dizisi çekmek için şöyle yaparız. Burada dbms_output ile debug satırları alınıyor.
try (Connection c = DriverManager.getConnection(url, properties);
  Statement s = c.createStatement()) {

  try {
    s.executeUpdate("begin dbms_output.enable(); end;"); //Enable output
    s.executeUpdate("begin dbms_output.put_line('abc'); end;"); //Add msg to debug
    s.executeUpdate("begin dbms_output.put_line('hello'); end;"); //or call stored proc
    s.executeUpdate("begin dbms_output.put_line('so cool'); end;");

    try (CallableStatement call = c.prepareCall(
      "declare "
      + "  num integer := 1000;"
      + "begin "
      + "  dbms_output.get_lines(?, num);"//Get output      + "end;"
    )) {
      call.registerOutParameter(1, Types.ARRAY, "DBMSOUTPUT_LINESARRAY");
      call.execute();

      Array array = null;
      try {
        array = call.getArray(1);
        System.out.println(Arrays.asList((Object[]) array.getArray()));
      }
      finally {
        if (array != null)
          array.free();
      }
    }
  }
  finally {
      s.executeUpdate("begin dbms_output.disable(); end;"); //Disable output
  }
}
setArray metodu
java.sql.Array tipinden parametre alır. Parametreyi yaratmak için şöyle yaparız.
Integer[] id = {2, 14, 4};
Array array = connection.createArrayOf("INTEGER", id);
Örnek
Şöyle yaparız.
cst.setArray(1,...);
setInt metodu
Şöyle yaparız.
int Id = ...;
cst.setInt(1, Id);
setString metodu
Şöyle yaparız.
String username = ...;
cst.setString(3, username);



Hiç yorum yok:

Yorum Gönder