错误:游标“<unnamed portal =”“5 =”“>”不存在

时间:2018-05-22 10:08:24

标签: java postgresql spring-integration

我正在尝试调用PostgreSQL的函数/存储过程(返回游标)。我正在通过Spring Integration的stored-proc-outbound-gateway调用该函数。它给了我以下错误:

Caused by: org.springframework.messaging.MessageHandlingException: Expression evaluation failed: @sampleProcedureGateway.exchange(#root).payload; nested exception is org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback; uncategorized SQLException for SQL [{? = call erb.getSampleDetails_sp(?, ?, ?, ?, ?)}]; SQL state [34000]; error code [0]; ERROR: cursor "<unnamed portal 5>" does not exist; nested exception is org.postgresql.util.PSQLException: ERROR: cursor "<unnamed portal 5>" does not exist

下面是我的Spring Integration配置:

<int:chain input-channel="inputDataChannel">
    <int-jdbc:stored-proc-outbound-gateway data-source="dataSource" expect-single-result="true" is-function="true" stored-procedure-name="erb.getSampleDetails_sp" ignore-column-meta-data="true">
        <int-jdbc:sql-parameter-definition name="id" direction="IN"/>
        <int-jdbc:sql-parameter-definition name="date" direction="IN"/>
        <int-jdbc:sql-parameter-definition name="name" direction="IN"/>
        <int-jdbc:sql-parameter-definition name="endrow" type="INTEGER" direction="IN"/>
        <int-jdbc:sql-parameter-definition name="startrow" type="INTEGER" direction="IN"/>
        <int-jdbc:sql-parameter-definition name="finalData" direction="OUT"/>
        <int-jdbc:parameter name="id" expression="headers.messageProcessResultHeader.interfaceRequestMetaData.dealerCode"/>
        <int-jdbc:parameter name="date" expression="headers['documentDate']"/>
        <int-jdbc:parameter name="name" expression="headers['IsRTIDealer']"/>
        <int-jdbc:parameter name="endrow" expression="headers['endRow']"/>
        <int-jdbc:parameter name="startrow" expression="headers['startRow']"/> 
        <int-jdbc:returning-resultset name="finalData" row-mapper="sampleRowMapper" />
</int-jdbc:stored-proc-outbound-gateway>                                                        
</int:chain>

以下是存储过程:

CREATE OR REPLACE FUNCTION erb.getSampleDetails_sp(
id text,
date text,
name text,
endrow double precision,
startrow double precision,
OUT finalData refcursor)
    RETURNS refcursor
    LANGUAGE 'plpgsql'

    COST 100
    VOLATILE 
AS $BODY$

BEGIN
    IF name = 'true' THEN
        OPEN finalData FOR
        SELECT
            *
            FROM (SELECT
                row_number() OVER (ORDER BY NULL) AS rnum, vhinv.*
                FROM (SELECT query) AS vhinv
                LIMIT i_endrow) AS var_sbq
            WHERE rnum >= i_startrow;
    ELSE
        OPEN finalData FOR
        SELECT
            *
            FROM (SELECT
                row_number() OVER (ORDER BY NULL) AS rnum, vhinv.*
                FROM (SELECT query) AS vhinv
                LIMIT i_endrow) AS var_sbq_2
            WHERE rnum >= i_startrow;
    END IF;
END;

$BODY$;

有什么方法可以解决这个问题吗?

3 个答案:

答案 0 :(得分:0)

首先,您确实需要确保存储过程确实是函数(is-function="true")并且它返回游标。

很高兴看到您的存储过程以确保正确映射所有参数。

Reference Manual中还有一个描述:

  

指定SQL参数定义的方向。默认为IN。有效值包括:INOUTINOUT。如果您的程序正在返回ResultSets,请使用returning-resultset元素。可选的。

我的意思是您必须从配置中移除sql-parameter-definition name="finalData"并依赖returning-resultset name="finalData"

答案 1 :(得分:0)

在Datasource bean定义中将autoCommit设置为false后,此问题已得到解决。

BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(driverName);
dataSource.setUrl(dbConnectionUrl);
dataSource.setUsername(userName);
dataSource.setDefaultAutoCommit(false);
dataSource.setEnableAutoCommitOnReturn(false);

答案 2 :(得分:0)

正如Abirmi所述,应同时将MappingJacksonHttpMessageConverter设置为false来解决此问题,如果要在现有大型应用程序中解决此问题,则应遵循以下方法,而不是对其进行硬编码。因此,我们可以确保仅更改所需流的AutoCommit属性,而不更改所涉及的连接对象的全部操作。

AutoCommit