尝试从 Java 调用简单的 Oracle PROCEDURE 的索引无效

Invalid Index trying to call a simple Oracle PROCEDURE from Java

以下 SQL 块在根据过程是否 运行 针对生产数据库调用时成功显示“Y”或“N”。

DECLARE
  v_is_prod VARCHAR2(1);
BEGIN

  FDS_APPS.FDS_USR_SEC_PKG2.IS_RUNNING_IN_PRODUCTION2(v_is_prod);
  dbms_output.put_line('v_is_prod=' || v_is_prod);
END;

我正在尝试从 Java 调用此过程(这是我第一次调用)。对于这个问题,请忽略这可能应该是 returns 一个 char 而不是单输出 varchar2(1) 参数的函数。我正在迈出第一步。

这是我的 Java 代码:

public String isRunningInProduction() throws DaoException {
        
        LoggerUtil.info("Start calling [" + IS_RUNNING_IN_PRODUCTION + "]::", LOGGER);
        String inProduction = "";
        
        try {

            SqlOutParameter isProd = new SqlOutParameter("v_is_prod", OracleTypes.VARCHAR);

            List<SqlParameter> paramList = new ArrayList<SqlParameter>();
            paramList.add(isProd); 
            
            Map<String, Object> resultMap = jdbcTemplate.call(new CallableStatementCreator() {

                public OracleCallableStatement createCallableStatement(Connection connection) throws SQLException {

                    OracleCallableStatement callableStatement = (OracleCallableStatement) connection
                            .prepareCall(IS_RUNNING_IN_PRODUCTION);
                                        
                    callableStatement.registerOutParameter(1, Types.VARCHAR);
                    return callableStatement;
                }
            }, paramList);

            inProduction = (String)resultMap.get("v_is_prod");
                                    
        } catch (Exception e) {
            LOGGER.error("Error while determining if running in prod or not, PROC_NAME::[" + IS_RUNNING_IN_PRODUCTION + "]," + e);
            throw new DaoException("Error while retreiving " + IS_RUNNING_IN_PRODUCTION + e);
        }
        LoggerUtil.info("Finished calling [" + IS_RUNNING_IN_PRODUCTION + "]::", LOGGER);
        
        return inProduction;    
        
    }

我收到这个错误:

org.springframework.jdbc.InvalidResultSetAccessException: CallableStatementCallback; invalid ResultSet access for SQL []; nested exception is java.sql.SQLException: Invalid column index

显然,r​​egisterOutParameter 是基于 1 的,因此 callableStatement 似乎不是问题所在,第一个参数的索引为 1。

以下const在别处定义:

public static final String IS_RUNNING_IN_PRODUCTION = "FDS_APPS.FDS_USR_SEC_PKG2.is_running_in_production2";

对我的问题有什么建议吗?

问题是你需要在你的声明中指出需要一个参数,像这样:

public static final String IS_RUNNING_IN_PRODUCTION = "FDS_APPS.FDS_USR_SEC_PKG2.is_running_in_production2(?);";

通常语句包含在 call 调用中:

public static final String IS_RUNNING_IN_PRODUCTION = "{call FDS_APPS.FDS_USR_SEC_PKG2.is_running_in_production2(?)}";

请注意括号和 ? 字符。

在 Java 和 JDBC 中,您需要使用 ? 字符为 SQL 语句中所需的每个参数提供一个占位符,无论是否如果是 IN 或 OUT。

因为你没有在你的例子中提供这样的占位符,Spring 抱怨是因为你试图用索引 1 注册一个输出参数 - 你是对的,第一列索引是1 -,但在您的 SQL 语句中没有该参数的占位符。

请查看更多示例,例如查看 this article,这可能会有所帮助。