ExecuteStoredProcedure抛出错误代码17004

时间:2015-03-04 08:37:57

标签: java oracle jdbc

我正在使用这些库

import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;

和这个班级

CallableStatementCreatorFactory  

详细例外

Root Cause: [org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback; uncategorized SQLException for SQL [{? = call xxxxxxxxxxxx()}]; SQL state [99999]; error code [17004]; Invalid coloumn: 16; nested exception is java.sql.SQLException: Invalid coloumn: 16]</faultstring>

Map<String, Object> result = QueryExecutor.getInstance().executeStoredProcedure("XXX", null);

我不明白为什么会收到这个错误的主要原因?

2 个答案:

答案 0 :(得分:1)

您的函数似乎返回BOOLEAN值。 Oracle JDBC driver does not support BOOLEAN values

以下类再现了类似的错误:

import java.sql.*;
import oracle.jdbc.OracleTypes;

public class Error17004Test {
    public static void main(String[] args) throws Exception {
        try (Connection c = DriverManager.getConnection(
                    "jdbc:oracle:thin:@localhost:1521:XE", "user", "password")) {

            try (Statement stmt = c.createStatement()) {
                stmt.execute(
                    "CREATE OR REPLACE FUNCTION bool_test RETURN BOOLEAN " +
                    "AS BEGIN RETURN TRUE; END;");
            }

            try (CallableStatement cstmt = c.prepareCall("{ ? = call bool_test }")) {
                cstmt.registerOutParameter(1, OracleTypes.BOOLEAN);
                cstmt.execute();
                System.out.println("Got result of " + cstmt.getObject(1));
            }
        }
        catch (SQLException e) {
            System.out.println("Got a SQLException with message '" + e.getMessage() +
                    "' and error code " + e.getErrorCode());
        }
    }
}

当我运行时,我得到以下输出:

Got a SQLException with message 'Invalid column type: 16' and error code 17004

幸运的是,这是一个简单的解决方法:将您的函数包装到sys.diutil.bool_to_int的调用中。 sys.diutil.bool_to_intBOOLEANTRUEFALSENULL分别转换为10NULL。然后你只需要从存储过程调用而不是布尔值中读取一个整数值。当然,您必须在返回的整数值和您可能想要的布尔值之间进行转换,但这应该是直截了当的。

如果我上课并更换两行

            try (CallableStatement cstmt = c.prepareCall("{ ? = call bool_test }")) {
                cstmt.registerOutParameter(1, OracleTypes.BOOLEAN);

            try (CallableStatement cstmt = c.prepareCall(
                    "{ ? = call sys.diutil.bool_to_int(bool_test) }")) {
                cstmt.registerOutParameter(1, Types.INTEGER);

再次运行我的课程,我得到以下输出:

Got result of 1

代替。

答案 1 :(得分:0)

检查数据类型之间是否存在不匹配,并确保没有空值或约束。