列表作为存储过程的参数
List as parameter to stored procedure
嘿,我正在开发 JSF/PF5/Mybatis/Oracle 应用程序。
我正在努力想办法。
我正在尝试发送一个整数列表作为存储过程的参数。
我在 运行 测试时收到此错误:
Caused by: java.sql.SQLException: invalid name pattern: SSLS_WMS.INT_ARRAY
有人可以帮我解决这个问题吗?
(我已经浏览了几个问题,例如 this )
我创建了一个测试包:
CREATE OR REPLACE PACKAGE SSLS_WMS.pkg_test
as
C_PKG_NAME CONSTANT tracer.T_CALL_NAME := sys_context('USERENV','CURRENT_SCHEMA') || '.pkg_test.';
TYPE INT_ARRAY is table of SSLS_WMS.ORDERS.ORDER_ID%type;
procedure pMergeOrders(
pMergeType INTEGER,
pToMerge IN INT_ARRAY,
pParentOrderId orders.order_id%type,
pParentOrderNo orders.order_no%type,
p_do_it pls_integer default 1
);
end pkg_test;
/
CREATE OR REPLACE PACKAGE body SSLS_WMS.pkg_test
as
procedure pMergeOrders(
pMergeType INTEGER,
pToMerge INT_ARRAY,
pParentOrderId orders.order_id%type,
pParentOrderNo orders.order_no%type,
p_do_it pls_integer default 1
)
AS
v_prog_name tracer.t_call_name := C_PKG_NAME||'pMergeOrders';
v_prog_params tracer.t_params := 'pParentOrderId='||pParentOrderId||
'p_do_it='||p_do_it;
BEGIN
insert into ssls_wms.TEST_THEO2(ORDER_ID) values (pParentOrderId);
for currOrderId in (select column_value FROM TABLE(pToMerge))
loop
insert into ssls_wms.TEST_THEO2(ORDER_ID) values (currOrderId.column_value);
end loop;
COMMIT;
end pMergeOrders;
end pkg_test;
映射器更新语句:
<update id="mergeOrders" parameterType="java.util.Map"
statementType="CALLABLE">
{CALL SSLS_WMS.PKG_TEST.PMERGEORDERS(
#{p_mergeType,
jdbcType=INTEGER},
#{p_toMerge, javaType=java.util.List,
jdbcType=ARRAY,
jdbcTypeName=INT_ARRAY, mode=IN,
typeHandler=com.mybatis.thandlers.IntArrayTypeHandler},
#{p_parentOrdId,
jdbcType=INTEGER},
#{p_parentOrdNo,jdbcType=VARCHAR},
#{p_do_it,
jdbcType=VARCHAR}
)
}
</update>
这就是我调用的过程:
@Test
public void _testOrderMerger() {
OrderMergerService service = new OrderMergerService();
List<Integer> orders = new ArrayList<Integer>();
orders.add(13648);
orders.add(136500);
Map<String, Object> params = new HashMap<String, Object>();
params.put("p_mergeType", 1);
params.put("p_toMerge", orders);
params.put("p_parentOrdId", 13652);
params.put("p_do_it", 1);
SQLResult result = service.merge(params);
if (result.isOk()) {
System.out.println("SUCCES");
} else
System.out.println("NOT GOOD");
}
我很确定问题与我的类型处理程序实现有关:
public class IntArrayTypeHandler implements TypeHandler<Object> {
@SuppressWarnings("unchecked")
@Override
public void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
List<Integer> objects = (List<Integer>) parameter;
ArrayDescriptor desc = ArrayDescriptor.createDescriptor("SSLS_WMS.PKG_TEST.INT_ARRAY", ps.getConnection());
ARRAY oracleArray = new ARRAY(desc, ps.getConnection(), objects);
ps.setArray(i, oracleArray);
}
... etc
使用JDBC,您无法访问打包类型。 This answer 可能会有帮助。
您可以在架构级别定义您的类型(通过提供列类型,因为您不能在此处使用 %type):
CREATE OR REPLACE TYPE TA_ORDER_ID AS TABLE OF NUMBER(15);
然后将其用作,
ArrayDescriptor desc = ArrayDescriptor.createDescriptor("SSLS_WMS.TA_ORDER_ID", ps.getConnection());
或者,您可以为您的类型创建一个 public 同义词,授予授权,然后在您的 TypeHandler 中使用该同义词。
CREATE OR REPLACE PUBLIC SYNONYM S_INT_ARRAY FOR SSLS_WMS.PKG_TEST.INT_ARRAY;
嘿,我正在开发 JSF/PF5/Mybatis/Oracle 应用程序。
我正在努力想办法。
我正在尝试发送一个整数列表作为存储过程的参数。
我在 运行 测试时收到此错误:
Caused by: java.sql.SQLException: invalid name pattern: SSLS_WMS.INT_ARRAY
有人可以帮我解决这个问题吗?
(我已经浏览了几个问题,例如 this )
我创建了一个测试包:
CREATE OR REPLACE PACKAGE SSLS_WMS.pkg_test
as
C_PKG_NAME CONSTANT tracer.T_CALL_NAME := sys_context('USERENV','CURRENT_SCHEMA') || '.pkg_test.';
TYPE INT_ARRAY is table of SSLS_WMS.ORDERS.ORDER_ID%type;
procedure pMergeOrders(
pMergeType INTEGER,
pToMerge IN INT_ARRAY,
pParentOrderId orders.order_id%type,
pParentOrderNo orders.order_no%type,
p_do_it pls_integer default 1
);
end pkg_test;
/
CREATE OR REPLACE PACKAGE body SSLS_WMS.pkg_test
as
procedure pMergeOrders(
pMergeType INTEGER,
pToMerge INT_ARRAY,
pParentOrderId orders.order_id%type,
pParentOrderNo orders.order_no%type,
p_do_it pls_integer default 1
)
AS
v_prog_name tracer.t_call_name := C_PKG_NAME||'pMergeOrders';
v_prog_params tracer.t_params := 'pParentOrderId='||pParentOrderId||
'p_do_it='||p_do_it;
BEGIN
insert into ssls_wms.TEST_THEO2(ORDER_ID) values (pParentOrderId);
for currOrderId in (select column_value FROM TABLE(pToMerge))
loop
insert into ssls_wms.TEST_THEO2(ORDER_ID) values (currOrderId.column_value);
end loop;
COMMIT;
end pMergeOrders;
end pkg_test;
映射器更新语句:
<update id="mergeOrders" parameterType="java.util.Map"
statementType="CALLABLE">
{CALL SSLS_WMS.PKG_TEST.PMERGEORDERS(
#{p_mergeType,
jdbcType=INTEGER},
#{p_toMerge, javaType=java.util.List,
jdbcType=ARRAY,
jdbcTypeName=INT_ARRAY, mode=IN,
typeHandler=com.mybatis.thandlers.IntArrayTypeHandler},
#{p_parentOrdId,
jdbcType=INTEGER},
#{p_parentOrdNo,jdbcType=VARCHAR},
#{p_do_it,
jdbcType=VARCHAR}
)
}
</update>
这就是我调用的过程:
@Test
public void _testOrderMerger() {
OrderMergerService service = new OrderMergerService();
List<Integer> orders = new ArrayList<Integer>();
orders.add(13648);
orders.add(136500);
Map<String, Object> params = new HashMap<String, Object>();
params.put("p_mergeType", 1);
params.put("p_toMerge", orders);
params.put("p_parentOrdId", 13652);
params.put("p_do_it", 1);
SQLResult result = service.merge(params);
if (result.isOk()) {
System.out.println("SUCCES");
} else
System.out.println("NOT GOOD");
}
我很确定问题与我的类型处理程序实现有关:
public class IntArrayTypeHandler implements TypeHandler<Object> {
@SuppressWarnings("unchecked")
@Override
public void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
List<Integer> objects = (List<Integer>) parameter;
ArrayDescriptor desc = ArrayDescriptor.createDescriptor("SSLS_WMS.PKG_TEST.INT_ARRAY", ps.getConnection());
ARRAY oracleArray = new ARRAY(desc, ps.getConnection(), objects);
ps.setArray(i, oracleArray);
}
... etc
使用JDBC,您无法访问打包类型。 This answer 可能会有帮助。
您可以在架构级别定义您的类型(通过提供列类型,因为您不能在此处使用 %type):
CREATE OR REPLACE TYPE TA_ORDER_ID AS TABLE OF NUMBER(15);
然后将其用作,
ArrayDescriptor desc = ArrayDescriptor.createDescriptor("SSLS_WMS.TA_ORDER_ID", ps.getConnection());
或者,您可以为您的类型创建一个 public 同义词,授予授权,然后在您的 TypeHandler 中使用该同义词。
CREATE OR REPLACE PUBLIC SYNONYM S_INT_ARRAY FOR SSLS_WMS.PKG_TEST.INT_ARRAY;