Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Java - Bagaimana cara memanggil prosedur Oracle dengan tipe khusus?

Pengaturan Oracle :

CREATE OR REPLACE TYPE BD_TB_STRUCT AS OBJECT(
  start_ts TIMESTAMP(3),
  end_ts   TIMESTAMP(3),
  time_type NUMBER(19),
  duration NUMBER(12)
) FINAL;
/

CREATE OR REPLACE PROCEDURE merge_time_bounds(
  s1_bd_t IN  bd_tb_struct,
  s2_bd_t IN  bd_tb_struct,
  r_bd_t  OUT bd_tb_struct
)
IS
  p_start TIMESTAMP(3) := LEAST(    s1_bd_t.start_ts,  s2_bd_t.start_ts );
  p_end   TIMESTAMP(3) := GREATEST( s1_bd_t.end_ts,    s2_bd_t.end_ts );
BEGIN
  r_bd_t := new BD_TB_STRUCT( 
                  p_start,
                  p_end,
                  COALESCE( s1_bd_t.time_type, s2_bd_t.time_type ),
                  ( CAST( p_end AS DATE ) - CAST( p_start AS DATE ) ) * 24 * 60 * 60
                );
END;
/

Kelas Data SQL Java :

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.SQLData;
import java.sql.SQLException;
import java.sql.SQLInput;
import java.sql.SQLOutput;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.ZoneOffset;

public class BoundsSQL implements SQLData
{
  public static final String SQL_TYPE = "BD_TB_STRUCT";
  public java.sql.Timestamp start;
  public java.sql.Timestamp end;
  public BigInteger type;
  public BigInteger duration;

  public BoundsSQL()
  {
  }

  public BoundsSQL(
      final int year,
      final int month,
      final int dayOfMonth,
      final int hour,
      final int minute,
      final int seconds,
      final long duration,
      final long type )
  {
    final long epochSeconds = LocalDateTime.of(
        year,
        month,
        dayOfMonth,
        hour,
        minute,
        seconds
      ).toEpochSecond( ZoneOffset.UTC );
    this.start    = new Timestamp( epochSeconds * 1000 );
    this.end      = new Timestamp( (epochSeconds + duration) * 1000 );
    this.duration = BigInteger.valueOf( duration );
    this.type = BigInteger.valueOf( type );
  }

  @Override
  public String getSQLTypeName() throws SQLException
  {
    return SQL_TYPE;
  }

  @Override
  public void readSQL( SQLInput stream,
      String typeName ) throws SQLException
  {
    start    = stream.readTimestamp();
    end      = stream.readTimestamp();
    type     = stream.readBigDecimal().toBigInteger();
    duration = stream.readBigDecimal().toBigInteger();
  }

  @Override
  public void writeSQL( SQLOutput stream ) throws SQLException
  {
    stream.writeTimestamp( start );
    stream.writeTimestamp( end );
    stream.writeBigDecimal( new BigDecimal( type ) );
    stream.writeBigDecimal( new BigDecimal( duration ) );
  }

  @Override
  public String toString()
  {
    return String.format(
        "Start:    %s\nEnd:      %s\nDuration: %s\nType:     %s",
        start,
        end,
        duration,
        type
    );
  }
}

Memanggil Prosedur Tersimpan dari Java :

Panggil prosedur tersimpan menggunakan OracleCallableStatement#setObject( int, Object ) untuk meneruskan parameter dan menempatkan kelas ke dalam peta tipe dan menggunakan OracleCallableStatement#registerOutParameter( int, int, string ) dan OracleCallableStatement#getObject( int ) untuk mengambil parameter.

import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Map;
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleTypes;

public class PassStructToProcedure
{

  public static void main( final String[] args ){
    OracleConnection con = null;
    try{
      Class.forName( "oracle.jdbc.OracleDriver" );

      con = (OracleConnection) DriverManager.getConnection(
          "jdbc:oracle:thin:@localhost:1521:orcl",
          "USERNAME",
          "PASSWORD"
      );

      BoundsSQL bound1 = new BoundsSQL( 2019, 1, 1, 0, 0, 0, 10, 1 );
      BoundsSQL bound2 = new BoundsSQL( 2019, 1, 1, 0, 0, 5, 10, 2 );

      OracleCallableStatement st = (OracleCallableStatement) con.prepareCall(
          "{ call MERGE_TIME_BOUNDS( ?, ?, ? ) }"
      );

      st.setObject( 1, bound1 );
      st.setObject( 2, bound2 );
      st.registerOutParameter( 3, OracleTypes.STRUCT, BoundsSQL.SQL_TYPE );
      st.execute();

      Map<String,Class<?>> typeMap = con.getTypeMap();
      typeMap.put( BoundsSQL.SQL_TYPE, BoundsSQL.class );

      BoundsSQL out = (BoundsSQL) st.getObject( 3 );

      System.out.println( out.toString() );

      st.close();
    } catch (ClassNotFoundException | SQLException ex) {
      System.out.println( ex.getMessage() );
      ex.printStackTrace();
    } finally {
      try{
        if ( con != null )
          con.close();
      }
      catch( SQLException e )
      {

      }
    }
  }
}

Keluaran :

Start:    2019-01-01 00:00:00.0
End:      2019-01-01 00:00:15.0
Duration: 15
Type:     1


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mengubah kata sandi SYS di RAC

  2. Ubah ukuran nama tabel/kolom/indeks di Oracle 11g atau 12c

  3. Mencari Teks dalam Prosedur Tersimpan Oracle

  4. Oracle:perbedaan antara max(id)+1 dan sequence.nextval

  5. Contoh APEX_ZIP