INT-2865: Stored Procedure SqlReturnType support
JIRA: https://jira.springsource.org/browse/INT-2865
This commit is contained in:
committed by
Gunnar Hillert
parent
3154173d23
commit
7d96dc7969
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -42,6 +42,7 @@ import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* @author Gunnar Hillert
|
||||
* @author Artem Bilan
|
||||
* @since 2.1
|
||||
*/
|
||||
public final class StoredProcParserUtils {
|
||||
@@ -68,6 +69,18 @@ public final class StoredProcParserUtils {
|
||||
String sqlType = childElement.getAttribute("type");
|
||||
String direction = childElement.getAttribute("direction");
|
||||
String scale = childElement.getAttribute("scale");
|
||||
String typeName = childElement.getAttribute("type-name");
|
||||
String returnType = childElement.getAttribute("return-type");
|
||||
|
||||
if (StringUtils.hasText(typeName) && StringUtils.hasText(scale)) {
|
||||
parserContext.getReaderContext().error("'type-name' and 'scale' attributes are mutually exclusive " +
|
||||
"for 'sql-parameter-definition' element.", storedProcComponent);
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(returnType) && StringUtils.hasText(scale)) {
|
||||
parserContext.getReaderContext().error("'returnType' and 'scale' attributes are mutually exclusive " +
|
||||
"for 'sql-parameter-definition' element.", storedProcComponent);
|
||||
}
|
||||
|
||||
final BeanDefinitionBuilder parameterBuilder;
|
||||
|
||||
@@ -79,6 +92,10 @@ public final class StoredProcParserUtils {
|
||||
}
|
||||
else {
|
||||
parameterBuilder = BeanDefinitionBuilder.genericBeanDefinition(SqlParameter.class);
|
||||
if (StringUtils.hasText(returnType)) {
|
||||
parserContext.getReaderContext().error("'return-type' attribute can't be provided " +
|
||||
"for IN 'sql-parameter-definition' element.", storedProcComponent);
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(name)) {
|
||||
@@ -105,9 +122,19 @@ public final class StoredProcParserUtils {
|
||||
parameterBuilder.addConstructorArgValue(Types.VARCHAR);
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(scale)) {
|
||||
if (StringUtils.hasText(typeName)) {
|
||||
parameterBuilder.addConstructorArgValue(typeName);
|
||||
}
|
||||
else if (StringUtils.hasText(scale)) {
|
||||
parameterBuilder.addConstructorArgValue(new TypedStringValue(scale, Integer.class));
|
||||
}
|
||||
else {
|
||||
parameterBuilder.addConstructorArgValue(null);
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(returnType)) {
|
||||
parameterBuilder.addConstructorArgReference(returnType);
|
||||
}
|
||||
|
||||
sqlParameterList.add(parameterBuilder.getBeanDefinition());
|
||||
}
|
||||
@@ -188,16 +215,6 @@ public final class StoredProcParserUtils {
|
||||
String name = childElement.getAttribute("name");
|
||||
String rowMapperAsString = childElement.getAttribute("row-mapper");
|
||||
|
||||
if (!StringUtils.hasText(name)) {
|
||||
parserContext.getReaderContext().error(
|
||||
"The 'name' attribute must be set for the 'returning-resultset' element.", storedProcComponent);
|
||||
}
|
||||
|
||||
if (!StringUtils.hasText(rowMapperAsString)) {
|
||||
parserContext.getReaderContext().error(
|
||||
"The 'row-mapper' attribute must be set for the 'returning-resultset' element.", storedProcComponent);
|
||||
}
|
||||
|
||||
BeanDefinitionBuilder rowMapperBuilder = BeanDefinitionBuilder.genericBeanDefinition(rowMapperAsString);
|
||||
|
||||
returningResultsetMap.put(name, rowMapperBuilder.getBeanDefinition());
|
||||
|
||||
@@ -1296,12 +1296,32 @@
|
||||
<xsd:union memberTypes="sqlType xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="scale" type="xsd:integer" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The scale of the Sql parameter. Only used for numeric and decimal
|
||||
parameters.
|
||||
]]></xsd:documentation>
|
||||
<xsd:attribute name="scale" type="xsd:integer" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The scale of the Sql parameter. Only used for numeric and decimal
|
||||
parameters.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="type-name" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Used for types that are user-named like:
|
||||
STRUCT, DISTINCT, JAVA_OBJECT, named array types.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="return-type" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Reference to a custom value handler for complex type.
|
||||
</xsd:documentation>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.jdbc.core.SqlReturnType" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
@@ -38,8 +38,31 @@
|
||||
<int:channel id="outputChannel"/>
|
||||
|
||||
<int:service-activator id="consumerEndpoint" input-channel="outputChannel" ref="consumer" />
|
||||
|
||||
<bean id="consumer" class="org.springframework.integration.jdbc.StoredProcOutboundGatewayWithSpelIntegrationTests$Consumer"/>
|
||||
|
||||
<int:logging-channel-adapter channel="errorChannel" log-full-message="true"/>
|
||||
|
||||
<int:channel id="output2Channel">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
<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>
|
||||
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
|
||||
package org.springframework.integration.jdbc;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -31,6 +33,7 @@ import org.junit.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
@@ -38,14 +41,23 @@ import org.springframework.integration.Message;
|
||||
import org.springframework.integration.MessageHandlingException;
|
||||
import org.springframework.integration.annotation.ServiceActivator;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.core.PollableChannel;
|
||||
import org.springframework.integration.jdbc.config.JdbcTypesEnum;
|
||||
import org.springframework.integration.jdbc.storedproc.User;
|
||||
import org.springframework.integration.json.JsonInboundMessageMapper;
|
||||
import org.springframework.integration.json.JsonOutboundMessageMapper;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.SqlReturnType;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author Gunnar Hillert
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@@ -61,6 +73,18 @@ public class StoredProcOutboundGatewayWithSpelIntegrationTests {
|
||||
@Qualifier("startChannel")
|
||||
DirectChannel channel;
|
||||
|
||||
@Autowired
|
||||
DirectChannel getMessageChannel;
|
||||
|
||||
@Autowired
|
||||
PollableChannel output2Channel;
|
||||
|
||||
@Autowired
|
||||
JdbcTemplate jdbcTemplate;
|
||||
|
||||
@Autowired
|
||||
SqlReturnType clobSqlReturnType;
|
||||
|
||||
@Test
|
||||
@DirtiesContext
|
||||
public void executeStoredProcedureWithMessageHeader() throws Exception {
|
||||
@@ -121,6 +145,27 @@ public class StoredProcOutboundGatewayWithSpelIntegrationTests {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void testInt2865SqlReturnType() throws Exception {
|
||||
Message<String> testMessage = MessageBuilder.withPayload("TEST").setHeader("FOO", "BAR").build();
|
||||
String messageId = testMessage.getHeaders().getId().toString();
|
||||
String jsonMessage = new JsonOutboundMessageMapper().fromMessage(testMessage);
|
||||
|
||||
this.jdbcTemplate.update("INSERT INTO json_message VALUES (?,?)", messageId, jsonMessage);
|
||||
|
||||
this.getMessageChannel.send(new GenericMessage<String>(messageId));
|
||||
Message<?> resultMessage = this.output2Channel.receive(1000);
|
||||
assertNotNull(resultMessage);
|
||||
Object resultPayload = resultMessage.getPayload();
|
||||
assertTrue(resultPayload instanceof String);
|
||||
Message<?> message = new JsonInboundMessageMapper(String.class).toMessage((String) resultPayload);
|
||||
assertEquals(testMessage.getPayload(), message.getPayload());
|
||||
assertEquals(testMessage.getHeaders().get("FOO"), message.getHeaders().get("FOO"));
|
||||
Mockito.verify(clobSqlReturnType).getTypeValue(Mockito.any(CallableStatement.class),
|
||||
Mockito.eq(2), Mockito.eq(JdbcTypesEnum.CLOB.getCode()), Mockito.eq((String) null));
|
||||
}
|
||||
|
||||
static class Counter {
|
||||
|
||||
private final AtomicInteger count = new AtomicInteger();
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.jdbc.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.sql.Types;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.config.PropertiesFactoryBean;
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.InputStreamResource;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.core.MessageHandler;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
import org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice;
|
||||
import org.springframework.integration.jdbc.storedproc.ProcedureParameter;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.jdbc.core.SqlInOutParameter;
|
||||
import org.springframework.jdbc.core.SqlOutParameter;
|
||||
import org.springframework.jdbc.core.SqlParameter;
|
||||
|
||||
/**
|
||||
* @author Artem Bilan
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StoredProcInvalidConfigsTests {
|
||||
|
||||
@Test
|
||||
public void testProcedureNameAndExpressionExclusivity() throws Exception {
|
||||
try {
|
||||
this.bootStrap("nameAndExpressionExclusivity");
|
||||
fail("Expected a BeanDefinitionParsingException to be thrown.");
|
||||
}
|
||||
catch (BeanDefinitionParsingException e) {
|
||||
assertTrue(e.getMessage().contains("Exactly one of 'stored-procedure-name' or 'stored-procedure-name-expression' is required"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnTypeForInParameter() throws Exception {
|
||||
try {
|
||||
this.bootStrap("returnTypeForInParameter");
|
||||
fail("Expected a BeanDefinitionParsingException to be thrown.");
|
||||
}
|
||||
catch (BeanDefinitionParsingException e) {
|
||||
assertTrue(e.getMessage().contains("'return-type' attribute can't be provided for IN 'sql-parameter-definition' element."));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypeNameAndScaleExclusivity() throws Exception {
|
||||
try {
|
||||
this.bootStrap("typeNameAndScaleExclusivity");
|
||||
fail("Expected a BeanDefinitionParsingException to be thrown.");
|
||||
}
|
||||
catch (BeanDefinitionParsingException e) {
|
||||
assertTrue(e.getMessage().contains("'type-name' and 'scale' attributes are mutually exclusive " +
|
||||
"for 'sql-parameter-definition' element."));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnTypeAndScaleExclusivity() throws Exception {
|
||||
try {
|
||||
this.bootStrap("returnTypeAndScaleExclusivity");
|
||||
fail("Expected a BeanDefinitionParsingException to be thrown.");
|
||||
}
|
||||
catch (BeanDefinitionParsingException e) {
|
||||
assertTrue(e.getMessage().contains("'returnType' and 'scale' attributes are mutually exclusive " +
|
||||
"for 'sql-parameter-definition' element."));
|
||||
}
|
||||
}
|
||||
|
||||
private ApplicationContext bootStrap(String configProperty) throws Exception {
|
||||
PropertiesFactoryBean pfb = new PropertiesFactoryBean();
|
||||
pfb.setLocation(new ClassPathResource("org/springframework/integration/jdbc/config/stored-proc-invalid-configs.properties"));
|
||||
pfb.afterPropertiesSet();
|
||||
Properties prop = pfb.getObject();
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append(prop.getProperty("xmlheaders")).append(prop.getProperty(configProperty)).append(prop.getProperty("xmlfooter"));
|
||||
ByteArrayInputStream stream = new ByteArrayInputStream(buffer.toString().getBytes());
|
||||
GenericApplicationContext ac = new GenericApplicationContext();
|
||||
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(ac);
|
||||
reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_XSD);
|
||||
reader.loadBeanDefinitions(new InputStreamResource(stream));
|
||||
ac.refresh();
|
||||
return ac;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
xmlheaders=\
|
||||
<?xml version="1.0" encoding="UTF-8"?> \
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" \
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" \
|
||||
xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc" \
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd \
|
||||
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd">
|
||||
xmlfooter= </beans>
|
||||
|
||||
nameAndExpressionExclusivity=<int-jdbc:stored-proc-outbound-gateway request-channel="requestChannel" data-source="dataSource" \
|
||||
stored-procedure-name="FOO" stored-procedure-name-expression="'FOO'" />
|
||||
|
||||
returnTypeForInParameter=<int-jdbc:stored-proc-outbound-gateway request-channel="requestChannel" data-source="dataSource" \
|
||||
stored-procedure-name="FOO" >\
|
||||
<int-jdbc:sql-parameter-definition name="foo" return-type="fooReturnType"/>\
|
||||
</int-jdbc:stored-proc-outbound-gateway>
|
||||
|
||||
typeNameAndScaleExclusivity=<int-jdbc:stored-proc-outbound-gateway request-channel="requestChannel" data-source="dataSource" \
|
||||
stored-procedure-name="FOO" >\
|
||||
<int-jdbc:sql-parameter-definition name="foo" type-name="FOO" scale="5"/>\
|
||||
</int-jdbc:stored-proc-outbound-gateway>
|
||||
|
||||
returnTypeAndScaleExclusivity=<int-jdbc:stored-proc-outbound-gateway request-channel="requestChannel" data-source="dataSource" \
|
||||
stored-procedure-name="FOO" >\
|
||||
<int-jdbc:sql-parameter-definition name="foo" scale="5" return-type="fooReturnType" />\
|
||||
</int-jdbc:stored-proc-outbound-gateway>
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.jdbc.storedproc;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.Clob;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.springframework.jdbc.core.SqlReturnType;
|
||||
|
||||
/**
|
||||
* @author Artem Bilan
|
||||
* @since 3.0
|
||||
*/
|
||||
public class ClobSqlReturnType implements SqlReturnType {
|
||||
|
||||
@Override
|
||||
public Object getTypeValue(CallableStatement cs, int paramIndex, int sqlType, String typeName) throws SQLException {
|
||||
Clob clob = cs.getClob(paramIndex);
|
||||
return clob != null ? clob.getSubString(1, (int) clob.length()) : null;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.integration.jdbc.storedproc.derby;
|
||||
|
||||
import java.sql.Clob;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
@@ -26,6 +27,7 @@ import org.springframework.jdbc.support.JdbcUtils;
|
||||
/**
|
||||
*
|
||||
* @author Gunnar Hillert
|
||||
* @author Artem Bilan
|
||||
*
|
||||
*/
|
||||
public final class DerbyStoredProcedures {
|
||||
@@ -74,4 +76,16 @@ public final class DerbyStoredProcedures {
|
||||
|
||||
}
|
||||
|
||||
public static void getMessage(String messageId, Clob[] returnedData) throws SQLException {
|
||||
|
||||
Connection conn = DriverManager.getConnection("jdbc:default:connection");
|
||||
|
||||
PreparedStatement stmt = conn.prepareStatement("select MESSAGE_JSON from JSON_MESSAGE where MESSAGE_ID = ?");
|
||||
stmt.setString( 1, messageId);
|
||||
ResultSet results = stmt.executeQuery();
|
||||
if (results.next()) {
|
||||
returnedData[0] = results.getClob(1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,3 +2,5 @@ DROP FUNCTION CONVERT_STRING_TO_UPPER_CASE;
|
||||
DROP TABLE USERS;
|
||||
DROP PROCEDURE CREATE_USER;
|
||||
DROP PROCEDURE CREATE_USER_RETURN_ALL;
|
||||
DROP TABLE JSON_MESSAGE;
|
||||
DROP PROCEDURE GET_MESSAGE;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
CREATE FUNCTION CONVERT_STRING_TO_UPPER_CASE (invalue VARCHAR(50)) RETURNS VARCHAR(50) PARAMETER STYLE JAVA LANGUAGE JAVA EXTERNAL NAME 'org.springframework.integration.jdbc.storedproc.derby.DerbyFunctions.convertStringToUpperCase';
|
||||
create table USERS(USERNAME varchar(100),PASSWORD varchar(100), EMAIL varchar(100));
|
||||
CREATE PROCEDURE CREATE_USER( IN username VARCHAR(100), IN password VARCHAR(100), IN email VARCHAR(100) ) PARAMETER STYLE JAVA LANGUAGE JAVA EXTERNAL NAME 'org.springframework.integration.jdbc.storedproc.derby.DerbyStoredProcedures.createUser';
|
||||
CREATE PROCEDURE CREATE_USER_RETURN_ALL(IN username VARCHAR(100), IN password VARCHAR(100), IN email VARCHAR(100)) PARAMETER STYLE JAVA LANGUAGE JAVA MODIFIES SQL DATA DYNAMIC RESULT SETS 1 EXTERNAL NAME 'org.springframework.integration.jdbc.storedproc.derby.DerbyStoredProcedures.createUserAndReturnAll';
|
||||
CREATE PROCEDURE CREATE_USER_RETURN_ALL(IN username VARCHAR(100), IN password VARCHAR(100), IN email VARCHAR(100)) PARAMETER STYLE JAVA LANGUAGE JAVA MODIFIES SQL DATA DYNAMIC RESULT SETS 1 EXTERNAL NAME 'org.springframework.integration.jdbc.storedproc.derby.DerbyStoredProcedures.createUserAndReturnAll';
|
||||
create table JSON_MESSAGE(MESSAGE_ID CHAR(36), MESSAGE_JSON CLOB);
|
||||
CREATE PROCEDURE GET_MESSAGE(IN MESSAGE_ID CHAR(36), OUT MESSAGE_JSON CLOB) PARAMETER STYLE JAVA LANGUAGE JAVA EXTERNAL NAME 'org.springframework.integration.jdbc.storedproc.derby.DerbyStoredProcedures.getMessage';
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
DROP FUNCTION CONVERT_STRING_TO_UPPER_CASE;
|
||||
DROP TABLE USERS;
|
||||
DROP PROCEDURE CREATE_USER;
|
||||
DROP PROCEDURE CREATE_USER_RETURN_ALL;
|
||||
@@ -810,10 +810,13 @@
|
||||
attribute.
|
||||
</para>
|
||||
|
||||
<programlisting language="xml"><![CDATA[<int-jdbc:sql-parameter-definition name="" ]]><co id="sp-parameter-definition-xml01-co" linkends="sp-parameter-definition-xml01" /><![CDATA[
|
||||
direction="IN" ]]><co id="sp-parameter-definition-xml02-co" linkends="sp-parameter-definition-xml02" /><![CDATA[
|
||||
type="STRING" ]]><co id="sp-parameter-definition-xml03-co" linkends="sp-parameter-definition-xml03" /><![CDATA[
|
||||
scale=""/> ]]><co id="sp-parameter-definition-xml04-co" linkends="sp-parameter-definition-xml04" /></programlisting>
|
||||
<programlisting language="xml"><![CDATA[<int-jdbc:sql-parameter-definition
|
||||
name="" ]]><co id="sp-parameter-definition-xml01-co" linkends="sp-parameter-definition-xml01" /><![CDATA[
|
||||
direction="IN" ]]><co id="sp-parameter-definition-xml02-co" linkends="sp-parameter-definition-xml02" /><![CDATA[
|
||||
type="STRING" ]]><co id="sp-parameter-definition-xml03-co" linkends="sp-parameter-definition-xml03" /><![CDATA[
|
||||
scale="5" ]]><co id="sp-parameter-definition-xml04-co" linkends="sp-parameter-definition-xml04" /><![CDATA[
|
||||
type-name="FOO_STRUCT" ]]><co id="sp-parameter-definition-xml05-co" linkends="sp-parameter-definition-xml05" /><![CDATA[
|
||||
return-type="fooSqlReturnType"/> ]]><co id="sp-parameter-definition-xml06-co" linkends="sp-parameter-definition-xml06" /></programlisting>
|
||||
<para>
|
||||
<calloutlist>
|
||||
<callout arearefs="sp-parameter-definition-xml01-co" id="sp-parameter-definition-xml01">
|
||||
@@ -850,6 +853,23 @@
|
||||
<emphasis>Optional</emphasis>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-parameter-definition-xml05-co" id="sp-parameter-definition-xml05">
|
||||
<para>
|
||||
The typeName for types that are user-named like: STRUCT, DISTINCT, JAVA_OBJECT, named array types.
|
||||
This attribute is mutually exclusive with the <emphasis>scale</emphasis> attribute.
|
||||
<emphasis>Optional</emphasis>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="sp-parameter-definition-xml06-co" id="sp-parameter-definition-xml06">
|
||||
<para>
|
||||
The reference to a custom value handler for complex types. An implementation of
|
||||
<ulink url="http://static.springsource.org/spring/docs/current/javadoc-api/org/springframework/jdbc/core/SqlReturnType.html"
|
||||
>SqlReturnType</ulink>.
|
||||
This attribute is mutually exclusive with the <emphasis>scale</emphasis> attribute
|
||||
and is applicable for OUT(INOUT)-parameters only.
|
||||
<emphasis>Optional</emphasis>.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</para>
|
||||
|
||||
|
||||
@@ -191,6 +191,21 @@
|
||||
For more information see <xref linkend="chain"/>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="3.0-stored-proc-sql-return-type">
|
||||
<title>SqlReturnType support for Stored Procedure components</title>
|
||||
<para>
|
||||
For more complex database-specific types, not supported by the standard
|
||||
<code>CallableStatement.getObject</code> method, 2 new additional
|
||||
attributes were introduced to the <code><sql-parameter-definition/></code>
|
||||
element with OUT-direction:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem><emphasis>type-name</emphasis></listitem>
|
||||
<listitem><emphasis>return-type</emphasis></listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
For more information see <xref linkend="stored-procedures"/>.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
Reference in New Issue
Block a user