私は、ユーザー定義型を含む2つの関連するストアドプロシージャを持っています。最初のオブジェクトはオブジェクトIDを受け取り、それに対応するユーザー定義型のインスタンスを返します。 2つ目は、同じユーザー定義型のインスタンスを受け取り、そのインスタンスで何かを実行します。ユーザー定義型を入力としてストアドプロシージャに渡すにはどうすればよいですか?
私はJava、JDBC、および少しのSpring JDBCを使用しています。私は正常に最初のストアドプロシージャを完了しました。 DBから自分のユーザー定義型のインスタンスを取得できますが、2番目のストアドプロシージャを動作させることはできません。
ここで私がこれまで持っているものの基本的なアウトラインです:
スキーマ(PL/SQL)
create or replace type example_obj as object
(ID NUMBER,
NAME VARCHAR2(100))
create or replace type example_tab as table of example_obj
create or replace package
example as
procedure getExample
(p_id in number,
p_example out example_tab);
procedure useExample
(p_example in example_tab);
end example;
エンティティ(ジャワ) - Javaの
にpublic class Example {
public BigDecimal ID;
public String Name;
}
をユーザー定義型を表しますが、
Mapper(Java) - SQL型からJava型に戻ってマップする
public class ExampleMapper extends Example implements SQLData {
public static final String SQL_OBJECT_TYPE_NAME = "example_obj";
public static final String SQL_TABLE_TYPE_NAME = "example_tab";
@Override
public String getSQLTypeName() throws SQLException {
return SQL_TABLE_TYPE_NAME;
}
@Override
public void readSQL(SQLInput stream, String typeName) throws SQLException {
ID = stream.readBigDecimal();
Name = stream.readString();
}
@Override
public void writeSQL(SQLOutput stream) throws SQLException {
stream.writeBigDecimal(ID);
stream.writeString(Name);
}
}
まずストアドプロシージャ(Javaは) - 私は先に述べたように、そのID
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import org.springframework.jdbc.core.JdbcTemplate;
public Example getExample(BigDecimal ID) throws SQLException {
String query = "begin example.getExample(?, ?); end;";
Connection connection = jdbcTemplate.getDataSource().getConnection();
CallableStatement callableStatement = connection.prepareCall(query);
callableStatement.setBigDecimal("p_id", ID);
Map<String, Class<?>> typeMap = connection.getTypeMap();
typeMap.put(Example.SQL_OBJECT_TYPE_NAME, ExampleMapper.class);
callableStatement.registerOutParameter("p_example", Types.ARRAY, Example.SQL_TABLE_TYPE_NAME);
connection.setTypeMap(typeMap);
callableStatement.execute();
Array array = (Array)callableStatement.getObject("p_example");
Object[] data = (Object[])array.getArray();
Example example = (Example)data[0]; // It's an ExampleMapper, but I only want Example
return example;
}
を与え例オブジェクトを取得し、最初のストアドプロシージャが正常に動作しています。データベースから取得されたオブジェクトは、対応するJavaオブジェクトに自動的にマップされます。次の手順では、このユーザー定義型のインスタンスを受け入れるストアドプロシージャを呼び出すことができます。手順(Java)のストアド
秒 - 例オブジェクトを使用 - 不完全
public void useExample(Example example) throws SQLException {
String query = "begin example.useExample(?); end;";
Connection connection = jdbcTemplate.getDataSource().getConnection();
CallableStatement callableStatement = connection.prepareCall(query);
// Is this required (as per getExample())?
Map<String, Class<?>> typeMap = connection.getTypeMap();
typeMap.put(Example.SQL_OBJECT_TYPE_NAME, ExampleMapper.class);
connection.setTypeMap(typeMap);
/***
*** What goes here to pass the object in as a parameter?
***/
callableStatement.setObject("p_example", ???);
callableStatement.execute();
}