如何使用 simplejdbccall 将 VARRAY(oracle PL/SQL) 参数传递给过程?
How pass VARRAY(oracle PL/SQL) param to procedure with simplejdbccall?
这里是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;
这里是简单的jdbccall(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)
我试过
- 整数数组 例如:new Integer[3];
- Linken 列表例如:new LinkedList<>();
- int 数组 例如:new int[]{1,2,3};
没有任何效果,我每次都遇到同样的错误。
不幸的是,您需要一些特定于供应商的魔法才能使其与 JDBC 一起使用(不特定于 Spring JDBC)。
这里有一个class我们使用的叫做OracleSqlArrayValue。它基本上是从已失效的 Spring JDBC 扩展 library 中删除的,尽管它可以正确处理解包连接。由于 OracleConnection 的导入,编译期间您的 class 路径中需要 Oracle JDBC 驱动程序。
不久前,我还在 SO 上另外发布了很多内容。
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);
这里是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;
这里是简单的jdbccall(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)
我试过
- 整数数组 例如:new Integer[3];
- Linken 列表例如:new LinkedList<>();
- int 数组 例如:new int[]{1,2,3};
没有任何效果,我每次都遇到同样的错误。
不幸的是,您需要一些特定于供应商的魔法才能使其与 JDBC 一起使用(不特定于 Spring JDBC)。
这里有一个class我们使用的叫做OracleSqlArrayValue。它基本上是从已失效的 Spring JDBC 扩展 library 中删除的,尽管它可以正确处理解包连接。由于 OracleConnection 的导入,编译期间您的 class 路径中需要 Oracle JDBC 驱动程序。
不久前,我还在 SO
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);