<div class="information"> 사용된 개발환경

  • iBATIS : 2.3.0.677
  • Oracle : 10g
  • eclipse : wtp All-in-one R-1.5.4-200705021353

</div>

<div class="warning">

  • xml설정파일에서는 대소문자 구분이 의외로 굉장히 중요하다. 필자의 경우 jdbcType 의 값을 INTEGER로 줘야 하는데도 불구하고 Integer로 줘서 한참동안이나 고생을 했다.
  • Procedure에서는 Map을 사용할 경우 queryForObject 메소드의 반환 객체에 값이 셋팅되는것이 아니고 넘긴 객체에 값이 셋팅된다. 기본적으로 반환되는 Map객체는 null로 넘어온다. 프로시저에서 넘긴값을 인자로 넘긴 Map에 셋팅되니 이점에 유의해서 사용해야 한다.

</div>

  1. IN 타입 예제[1]
  2. OUT 타입 예제[2]
  3. INOUT 타입 예제[3]

IN타입[#1]#

  • IN파라미터란! : 호출자에 의해 프로시저에 전달되는 파라미터이고 읽기전용의 값이다. 즉 프로시저는 이 값을 변경할수는 없다.
  • 테스트 케이스 : 여기서는 IN타입으로 값을 받아와서 특정 테이블에 값을 입력하는 케이스를 보여준다.

프로시저#

CREATE OR REPLACE PROCEDURE procedurein (p_param IN NUMBERIS
BEGIN
   DBMS_OUTPUT.put_line (p_param);
   INSERT INTO tablein VALUES (p_param);
   commit;
END;
/

테이블 생성#

create table tablein(val number);

sqlMap파일#

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMap      
    PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"      
    "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Account">
  <procedure id="inProcedure" parameterClass="java.lang.Integer">
    call procedurein(#val#) }
  </procedure>
</sqlMap>

실행코드#

package com.mydomain.data;

.......................

public class SimpleExample {

  private static SqlMapClient sqlMapper;
  static {
    try {
      Reader reader = Resources.getResourceAsReader("com/mydomain/data/SqlMapConfig.xml");
      sqlMapper = SqlMapClientBuilder.buildSqlMapClient(reader);
      reader.close();
    catch (IOException e) {
      throw new RuntimeException("Something bad happened while building the SqlMapClient instance." + e, e);
    }
  }
  
  public static void callInTypeProcedure(int valthrows SQLException{
    sqlMapper.queryForObject("inProcedure"new Integer(val));
  }

  public static void main(String[] argsthrows SQLException {
    
    try {
      callInTypeProcedure(123);
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

결과#

SQL> select * from tableIN;

       VAL
----------
       123

SQL>

여기서 보면 인자로 123이라는 숫자값을 넘겼으며 프로시저에 정의된 내용대로 tableIN이라는 테이블에 값이 정상적으로 입력이 된것을 볼수 있다.

OUT타입[#2]#

  • OUT파라미터란! : 프로시저에서 값이 변경될수 있다. 이 파라미터는 프로시저가 다수의 정보를 호출자에게 반환시켜주어야 하는 경우에 주로 사용한다.
  • 테스트 케이스 : 여기서는 IN타입으로 입력된 숫자값에 3을 더한 값을 반환하는 것을 보여주는 예제이다.

프로시저#

CREATE OR REPLACE PROCEDURE procedure_out(p_inval in integer, p_outval out integerIS 
BEGIN
   p_outval := p_inval+3;
END;
/

sqlMap파일#

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMap      
    PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"      
    "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Account">
  <parameterMap id="outProcedureMap" class="java.util.Map">
    <parameter property="p_inval" javaType="java.lang.Integer" jdbcType="INTEGER" mode="IN" />
    <parameter property="p_outval" javaType="java.lang.Integer" jdbcType="INTEGER" mode="OUT" />
  </parameterMap>
  
  <procedure id="outProcedure" parameterMap="outProcedureMap">
    call procedure_out (?,?) }
  </procedure>
</sqlMap>

실행코드#

package com.mydomain.data;

.......................

public class SimpleExample {

  private static SqlMapClient sqlMapper;
  static {
    try {
      Reader reader = Resources.getResourceAsReader("com/mydomain/data/SqlMapConfig.xml");
      sqlMapper = SqlMapClientBuilder.buildSqlMapClient(reader);
      reader.close();
    catch (IOException e) {
      throw new RuntimeException("Something bad happened while building the SqlMapClient instance." + e, e);
    }
  }
  
  public static Map callOutTypeProcedure(Map mthrows SQLException{
    sqlMapper.queryForObject("outProcedure", m);
    return m;
  }

  public static void main(String[] argsthrows SQLException {    
    try {
      Map<String, Integer> m = new HashMap<String, Integer>(2);
      m.put("p_inval"new Integer(123));      
      Map result = SimpleExample.callOutTypeProcedure(m);
      System.out.println("result : " + Integer.parseInt(result.get("p_outval").toString()));    
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

결과#

result : 126

인자로 넘겨진 값인 123에 3을 더해 126이라는 값이 반환되었다.

INOUT타입[#3]#

  • INOUT파라미터란! : 프로시저가 읽고 쓰는 작업을 동시에 할수 있는 파라미터를 의미한다.
  • 테스트 케이스 : 여기서는 INOUT타입으로 값을 받아와서 값의 위치를 서로 바꿔서 값을 입력한 뒤 반환하는 케이스를 보여주는 예제이다.

프로시저#

CREATE OR REPLACE PROCEDURE procedure_inout(p_inout1 in out integer, p_inout2 in out integerIS
tmpVar NUMBER;
BEGIN
   tmpVar:=p_inout1;
   p_inout1:=p_inout2;
   p_inout2:=tmpVar;
END;
/

sqlMap파일#

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMap      
    PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"      
    "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Account">
  <parameterMap id="inoutProcedureMap" class="java.util.Map">
    <parameter property="p_inout1" javaType="java.lang.Integer" jdbcType="INTEGER" mode="INOUT" />
    <parameter property="p_inout2" javaType="java.lang.Integer" jdbcType="INTEGER" mode="INOUT" />
  </parameterMap>  
  
  <procedure id="inoutProcedure" resultClass="java.util.Map" parameterMap="inoutProcedureMap">
    call procedure_inout(?, ?) }
  </procedure>  
</sqlMap>

실행코드#

package com.mydomain.data;

.......................

public class SimpleExample {

  private static SqlMapClient sqlMapper;
  static {
    try {
      Reader reader = Resources.getResourceAsReader("com/mydomain/data/SqlMapConfig.xml");
      sqlMapper = SqlMapClientBuilder.buildSqlMapClient(reader);
      reader.close();
    catch (IOException e) {
      throw new RuntimeException("Something bad happened while building the SqlMapClient instance." + e, e);
    }
  }
  
  public static Map callProcedure(Map mthrows SQLException{
    sqlMapper.queryForObject("inoutProcedure", m);    
    return m;
  }

  public static void main(String[] argsthrows SQLException {
    
    try {
      Map<String, Integer> m = new HashMap<String, Integer>(2);
      m.put("p_inout1"new Integer(7));
      m.put("p_inout2"new Integer(5));
      System.out.println("인자로 넘어가는 값 \n"+m);
      Map map = (HashMap)SimpleExample.callProcedure(m);
      System.out.println("결과로 넘어온 값 \n"+m);
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

결과#

인자로 넘어가는 값 
{p_inout1=7, p_inout2=5}
결과로 넘어온 값 
{p_inout1=5, p_inout2=7}

보면 처음에 넘긴값은 p_inout1값이 7이고 p_inout2값인데 반환값은 반대로 5, 7이다. 즉 프로시저의 처리고 값이 정상적으로 바껴서 넘어온것이다.




출처 : http://ldg.pe.kr/Wiki.jsp?page=ProcedureExample

+ Recent posts