将一个数字数组(TABLE OF NUMBER)Input Param传递给SpringJDBC中的Stored Proc调用

3j86kqsm  于 2023-09-29  发布在  Spring
关注(0)|答案(2)|浏览(85)

在SpringJDBC中,我需要调用一个参数为TABLE OF NUMBER类型的SP,即一组数字。

PROCEDURE MY_SP(              PARAM1                IN TABLE OF NUMBER,
                                PARAM2                IN NUMBER,

[1](1元素整数数组)的输入有效。但是当我试图通过这个参数的声明将它直接传递给OracleTypes.ARRAY

declareParameter(new SqlParameter("PARAM1", OracleTypes.ARRAY));

我得到

Caused by: java.sql.SQLException: Fail to convert to internal representation: [Ljava.lang.Integer;@16a25973
    at oracle.sql.ARRAY.toARRAY(ARRAY.java:308)

有一个old example here使用了已弃用的ArrayDescriptor并构建了一个SQL Array。这必须来自较旧的SpringJDBC。ArrayDescriptor已弃用,而且我无法访问connection。我使用现代的SpringJDBC方法来实现StoredProcedure接口(使用compile()),它不暴露connection。有什么想法吗?

@Component
public class MySP extends StoredProcedure {
    
    private RowMapper<List<Object>> rowMapper = new MyMapper();
    
    public MySP(@Autowired DataSource dataSource) {
        super(dataSource, "MYPACKAGE.MY_SP");

        declareParameter(new SqlParameter("PARAM1", OracleTypes.ARRAY));
        //...
        compile();
   }

   public String callSP(Integer[] intArray) {
        //intArray contains a 1-element integer array, e.g. [1]
        Map<String, Object> inputParameters = new HashMap<>();
        inputParameters.put("PARAM1", intArray);

        Map<String, Object> output = super.execute(inputParameters);
        // Process results...
   }
j2cgzkjk

j2cgzkjk1#

您可以使用JdbcTemplate访问连接并执行操作。创建数组如下:https://stackoverflow.com/a/76571542/7565792

import org.springframework.jdbc.core.JdbcTemplate;
    import java.sql.Connection;
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    // ...
    
    // Access the connection using JdbcTemplate
    Connection connection = jdbcTemplate.execute(con -> {
        // Here, you have access to the connection object.
        //create your array like mentioned in the link above: 
        return con;
    });
    connection.close();
lvmkulzt

lvmkulzt2#

如果您在Oracle中定义了自定义Array类型,例如以下:

create or replace TYPE   "REF_TYPE_ARRAY"  IS TABLE OF NUMBER

然后在Java的StoredProcedure实现中,你可以执行以下操作:您可以(1)打开OracleConnection,然后(2)执行createOracleArray

@Component
public class MyStoredProcedure extends StoredProcedure {

    public MyStoredProcedure(@Autowired DataSource dataSource) {
        super(dataSource, "MY_PKG.MY_STORED_PROC"); // Name

        declareParameter(new SqlParameter("itemIds", OracleTypes.ARRAY, "REF_TYPE_ARRAY"));
        // etc. other parameters

}

public void execute(ParamObject paramObject) throws Exception{
    Map<String, Object> inputParameters = new HashMap<>();
    
    OracleConnection oracleConnection = getJdbcTemplate().getDataSource().getConnection().unwrap(OracleConnection.class);
    Array array = oracleConnection.createOracleArray("REF_TYPE_ARRAY", referralTypeId);
    
    inputParameters.put("itemIds", array); 
    // etc. other params

这是可行的,但是我们偶尔会遇到一些泄漏的连接和JDBC问题。我们必须将SP重写为简单的CallableStatement,其中您直接将数组指定为

private static final String SQL = 
" {call MY_PKG.MY_SP(REF_TYPE_ARRAY(?),?,?) } ";

try(Connection conn = dataSource.getConnection(); CallableStatement cs = conn.prepareCall(SQL)) {
                    
        cs.setString(1, itemIds);
        //etc.

相关问题