【问题标题】:How pass VARRAY(oracle PL/SQL) param to procedure with simplejdbccall?如何使用 simplejdbccall 将 VARRAY(oracle PL/SQL) 参数传递给过程?
【发布时间】:2020-10-20 23:51:19
【问题描述】:

这是 VARRAY 类型:

CREATE TYPE NUM_ARR IS VARRAY(3) OF NUMBER(0)
;

这是程序

PROCEDURE REGISTER_CONSENT(P_IPS_ACC_IBAN IN VARCHAR2,
                           P_IPS_BANK_BIC IN VARCHAR2,
                           P_STATUS_ID IN NUMBER,
                           P_PERMS IN NUM_ARR,
                           P_EXP_DATE IN DATE)
    IS
BEGIN

    FOR PERM_ID in P_PERMS.first ..P_PERMS.last
        LOOP
            INSERT INTO MLB_TEST.IPS_OB_CONSENT_PERMISSION(ID, CONSENT_ID, PERMISSION_ID, EXPIRATION_DATE)
            VALUES (IPS_OB_CONSENT_PERMISSION_SEQ.nextval,
                    IPS_OB_CONSENT_SEQ.currval,
                    PERM_ID,
                    P_EXP_DATE);
        END LOOP;

END;

这里是 simplejdbccall (java)

        SimpleJdbcCall caller = new SimpleJdbcCall(dataSource);
    caller.withSchemaName("MLB_TEST")
            .withCatalogName("MLB_OB")
            .withProcedureName("REGISTER_CONSENT")
            .declareParameters(new SqlParameter("P_PERMS", Types.ARRAY, "NUM_ARR"));
    MapSqlParameterSource param = new MapSqlParameterSource()
            .addValue("P_IPS_ACC_IBAN", consent.getIban())
            .addValue("P_IPS_BANK_BIC", consent.getBankBic())
            .addValue("P_STATUS_ID", consent.getConsentStatusId())
            .addValue("P_PERMS", consent.getPermissionsIdList(), Types.ARRAY, "NUM_ARR")
            .addValue("P_EXP_DATE", consent.getExpirationDate());
    caller.execute(param);

这是我得到的错误: 原因:java.sql.SQLException:无法转换为内部表示:[Ljava.lang.Integer;@40f5407d 在 oracle.sql.ARRAY.toARRAY(ARRAY.java:301)

我试过了

  • 整数数组 Ex : new Integer[3];
  • 链接列表 Ex : new LinkedList();
  • int 数组 Ex : new int[]{1,2,3};

没有任何效果,我每次都遇到同样的错误。

【问题讨论】:

    标签: java oracle stored-procedures plsql simplejdbccall


    【解决方案1】:

    不幸的是,您需要一些特定于供应商的魔法才能使其与 JDBC(不是特定于 Spring JDBC)一起使用。

    这是我们使用的一个名为 OracleSqlArrayValue 的类。它基本上是从已失效的 Spring JDBC 扩展 library 中提取的,尽管它可以正确处理解包连接。由于 OracleConnection 的导入,在编译期间您将需要在类路径中添加 Oracle JDBC 驱动程序。

    不久前,我还向 SO here 发布了以下大部分内容。

    import java.sql.Connection;
    import java.sql.SQLException;
    
    import org.springframework.dao.InvalidDataAccessApiUsageException;
    import org.springframework.jdbc.core.support.AbstractSqlTypeValue;
    
    import oracle.jdbc.OracleConnection;
    
    public class OracleSqlArrayValue<T> extends AbstractSqlTypeValue {
        private T[] values;
        private String defaultTypeName;
    
        public OracleSqlArrayValue(T[] values) {
            this.values = values;
        }
    
        public OracleSqlArrayValue(T[] values, String defaultTypeName) {
            this.values = values;
            this.defaultTypeName = defaultTypeName;
        }
    
        @Override
        protected Object createTypeValue(Connection conn, int sqlType,
                String typeName) throws SQLException {
    
            if (typeName == null && defaultTypeName == null) {
                throw new InvalidDataAccessApiUsageException(
                        "No type named defined. Instantiate class with default type name.");
            }
    
            if (!conn.isWrapperFor(OracleConnection.class)) {
                throw new InvalidDataAccessApiUsageException(
                        "Unable to unwrap OracleConnection. Ensure you are connecting to an Oracle DB.");
            }
    
            return conn.unwrap(OracleConnection.class).createOracleArray(
                    typeName != null ? typeName : defaultTypeName, values);
        }
    }
    

    然后你会像这样使用它。

    SimpleJdbcCall caller = new SimpleJdbcCall(dataSource);
    caller.withSchemaName("MLB_TEST")
            .withCatalogName("MLB_OB")
            .withProcedureName("REGISTER_CONSENT")
            .declareParameters(new SqlParameter("P_PERMS", Types.ARRAY, "NUM_ARR"));
    MapSqlParameterSource param = new MapSqlParameterSource()
            .addValue("P_IPS_ACC_IBAN", consent.getIban())
            .addValue("P_IPS_BANK_BIC", consent.getBankBic())
            .addValue("P_STATUS_ID", consent.getConsentStatusId())
            .addValue("P_PERMS", new OracleSqlArrayValue<Integer>(consent.getPermissionsIdList(), "NUM_ARR"))
            .addValue("P_EXP_DATE", consent.getExpirationDate());
    caller.execute(param);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-04
      • 2013-03-16
      • 2019-12-03
      • 2021-12-27
      • 1970-01-01
      相关资源
      最近更新 更多