Oracle 存储过程 - Spring 集成 - OUT 类型对象
Oracle Stored Procedure - Spring Integration - OUT Type Object
是否可以将 Oracle 类型对象作为存储过程的输出,使用 spring 集成调用相同的对象?
例如,我在数据库中有以下内容:
create or replace TYPE ESP_TRAINING_REQ_OBJ AS OBJECT
(
v_param1 varchar2(25),
v_param2 varchar2(25)
);
create or replace TYPE ESP_TRAINING_RESP_OBJ AS OBJECT
(
v_param1 varchar2(25),
v_param2 varchar2(25)
);
create or replace PROCEDURE TEST_PROC (
v_req_obj IN ESP_TRAINING_REQ_OBJ,
v_resp_obj OUT ESP_TRAINING_RESP_OBJ
) AS
BEGIN
v_resp_obj := ESP_TRAINING_RESP_OBJ(v_req_obj.v_param2, v_req_obj.v_param1);
dbms_output.put_line('TEST_PROC');
END;
但是,当我尝试调用它时,出现以下异常:
PLS-00306: wrong number or types of arguments in call to 'TEST_PROC'
请在下面找到 spring 集成配置:
<int-jdbc:stored-proc-outbound-gateway
id="ESP_TRAINING" request-channel="inputChannel"
stored-procedure-name="TEST_PROC" data-source="dataSource"
reply-channel="outputChannel"
skip-undeclared-results="false" ignore-column-meta-data="true">
<int-jdbc:sql-parameter-definition name="v_req_obj" direction="IN" type="STRUCT" />
<int-jdbc:sql-parameter-definition name="v_resp_obj" direction="OUT" type="STRUCT" />
<int-jdbc:parameter name="v_req_obj" expression="payload.v_req_obj"/>
</int-jdbc:stored-proc-outbound-gateway>
请注意,如果我们更改上面的 SP 声明,它工作正常,仅在请求中使用 STRUCT,例如将 ESP_TRAINING_RESP_OBJ 替换为 VARCHAR 或任何其他 Oracle 原始数据类型。
例如:
create or replace PROCEDURE TEST_PROC (
v_req_obj IN ESP_TRAINING_REQ_OBJ,
v_status OUT VARCHAR2
) AS
BEGIN
v_status := v_req_obj.v_param1 || ' and ' || v_req_obj.v_param2;
dbms_output.put_line('TEST_PROC');
END;
return-type
on the <int-jdbc:sql-parameter-definition>
for OUT
param and SqlReturnStruct
一定能帮您解决问题。
框架源代码中的测试用例包含用于 CLOB
处理的示例:
<int-jdbc:stored-proc-outbound-gateway request-channel="getMessageChannel"
data-source="dataSource"
stored-procedure-name="GET_MESSAGE"
ignore-column-meta-data="true"
expect-single-result="true"
reply-channel="output2Channel">
<int-jdbc:sql-parameter-definition name="message_id"/>
<int-jdbc:sql-parameter-definition name="message_json" type="CLOB" direction="OUT" type-name="" return-type="clobSqlReturnType"/>
<int-jdbc:parameter name="message_id" expression="payload"/>
</int-jdbc:stored-proc-outbound-gateway>
<bean id="clobSqlReturnType" class="org.mockito.Mockito" factory-method="spy">
<constructor-arg>
<bean class="org.springframework.integration.jdbc.storedproc.ClobSqlReturnType"/>
</constructor-arg>
</bean>
我已通过以下方式修复它:
已将 spring 集成版本更新为 3.0。0.RELEASE,
在 sql-parameter-definition.
中支持 type-name 和 return-type 属性
更新存储过程声明如下:
<int-jdbc:stored-proc-outbound-gateway
id="ESP_TRAINING" request-channel="inputChannel"
stored-procedure-name="TEST_PROC" data-source="dataSource"
reply-channel="outputChannel"
skip-undeclared-results="false" ignore-column-meta-data="true">
<int-jdbc:sql-parameter-definition name="v_req_obj" direction="IN" type="STRUCT" />
<int-jdbc:sql-parameter-definition name="v_resp_obj" direction="OUT" type="STRUCT" type-name="ESP_TRAINING_RESP_OBJ" return-type="espTrainingRespObj" />
<int-jdbc:parameter name="v_req_obj" expression="payload.v_req_obj"/>
</int-jdbc:stored-proc-outbound-gateway>
<beans:bean id="espTrainingRespObj" class="com.hsbc.esp.EspTrainingRespObj"/>
更改EspTrainingRespObj实现SQLReturnType,如下:
public class EspTrainingRespObj implements SqlReturnType {
private String param1;
private String param2;
public Object getTypeValue(CallableStatement cs, int paramIndex, int sqlType, String typeName)
throws SQLException {
Object[] attributes = ((STRUCT) cs.getObject(paramIndex)).getAttributes();
this.param1 = (String) attributes[0];
this.param2 = (String) attributes[1];
return this;
}
...
}
是否可以将 Oracle 类型对象作为存储过程的输出,使用 spring 集成调用相同的对象?
例如,我在数据库中有以下内容:
create or replace TYPE ESP_TRAINING_REQ_OBJ AS OBJECT
(
v_param1 varchar2(25),
v_param2 varchar2(25)
);
create or replace TYPE ESP_TRAINING_RESP_OBJ AS OBJECT
(
v_param1 varchar2(25),
v_param2 varchar2(25)
);
create or replace PROCEDURE TEST_PROC (
v_req_obj IN ESP_TRAINING_REQ_OBJ,
v_resp_obj OUT ESP_TRAINING_RESP_OBJ
) AS
BEGIN
v_resp_obj := ESP_TRAINING_RESP_OBJ(v_req_obj.v_param2, v_req_obj.v_param1);
dbms_output.put_line('TEST_PROC');
END;
但是,当我尝试调用它时,出现以下异常:
PLS-00306: wrong number or types of arguments in call to 'TEST_PROC'
请在下面找到 spring 集成配置:
<int-jdbc:stored-proc-outbound-gateway
id="ESP_TRAINING" request-channel="inputChannel"
stored-procedure-name="TEST_PROC" data-source="dataSource"
reply-channel="outputChannel"
skip-undeclared-results="false" ignore-column-meta-data="true">
<int-jdbc:sql-parameter-definition name="v_req_obj" direction="IN" type="STRUCT" />
<int-jdbc:sql-parameter-definition name="v_resp_obj" direction="OUT" type="STRUCT" />
<int-jdbc:parameter name="v_req_obj" expression="payload.v_req_obj"/>
</int-jdbc:stored-proc-outbound-gateway>
请注意,如果我们更改上面的 SP 声明,它工作正常,仅在请求中使用 STRUCT,例如将 ESP_TRAINING_RESP_OBJ 替换为 VARCHAR 或任何其他 Oracle 原始数据类型。
例如:
create or replace PROCEDURE TEST_PROC (
v_req_obj IN ESP_TRAINING_REQ_OBJ,
v_status OUT VARCHAR2
) AS
BEGIN
v_status := v_req_obj.v_param1 || ' and ' || v_req_obj.v_param2;
dbms_output.put_line('TEST_PROC');
END;
return-type
on the <int-jdbc:sql-parameter-definition>
for OUT
param and SqlReturnStruct
一定能帮您解决问题。
框架源代码中的测试用例包含用于 CLOB
处理的示例:
<int-jdbc:stored-proc-outbound-gateway request-channel="getMessageChannel"
data-source="dataSource"
stored-procedure-name="GET_MESSAGE"
ignore-column-meta-data="true"
expect-single-result="true"
reply-channel="output2Channel">
<int-jdbc:sql-parameter-definition name="message_id"/>
<int-jdbc:sql-parameter-definition name="message_json" type="CLOB" direction="OUT" type-name="" return-type="clobSqlReturnType"/>
<int-jdbc:parameter name="message_id" expression="payload"/>
</int-jdbc:stored-proc-outbound-gateway>
<bean id="clobSqlReturnType" class="org.mockito.Mockito" factory-method="spy">
<constructor-arg>
<bean class="org.springframework.integration.jdbc.storedproc.ClobSqlReturnType"/>
</constructor-arg>
</bean>
我已通过以下方式修复它:
已将 spring 集成版本更新为 3.0。0.RELEASE, 在 sql-parameter-definition.
中支持 type-name 和 return-type 属性
更新存储过程声明如下:
<int-jdbc:stored-proc-outbound-gateway id="ESP_TRAINING" request-channel="inputChannel" stored-procedure-name="TEST_PROC" data-source="dataSource" reply-channel="outputChannel" skip-undeclared-results="false" ignore-column-meta-data="true"> <int-jdbc:sql-parameter-definition name="v_req_obj" direction="IN" type="STRUCT" /> <int-jdbc:sql-parameter-definition name="v_resp_obj" direction="OUT" type="STRUCT" type-name="ESP_TRAINING_RESP_OBJ" return-type="espTrainingRespObj" /> <int-jdbc:parameter name="v_req_obj" expression="payload.v_req_obj"/> </int-jdbc:stored-proc-outbound-gateway> <beans:bean id="espTrainingRespObj" class="com.hsbc.esp.EspTrainingRespObj"/>
更改EspTrainingRespObj实现SQLReturnType,如下:
public class EspTrainingRespObj implements SqlReturnType { private String param1; private String param2; public Object getTypeValue(CallableStatement cs, int paramIndex, int sqlType, String typeName) throws SQLException { Object[] attributes = ((STRUCT) cs.getObject(paramIndex)).getAttributes(); this.param1 = (String) attributes[0]; this.param2 = (String) attributes[1]; return this; } ... }