ResultSet字段索引关闭一个

时间:2013-12-13 18:22:42

标签: java mysql sql jdbc resultset

我的SQL:

    String mainSql =
            " SELECT `subject`, `message_id`, `sender`, `date`, `type`, `order`, `body` "
            + " FROM `scan_result` sr LEFT OUTER JOIN `scan_result_body` srb ON `sr`.id = `srb`.scan_result_id "
            + " WHERE `user_id` = ? AND `message_id` = ? "
            + " ORDER BY `type`, `order` ASC ";

我的代码:

    try (PreparedStatement ps = connection.prepareStatement(mainSql)) {
        int idx = 1;
        ps.setInt(idx++, userId);
        ps.setString(idx++, messageId);

        try (ResultSet rs = ps.executeQuery()) {
            boolean firstRow = false;
            while (rs.next()) {
                if (!firstRow) {
                    firstRow = true;
                    builder.setSubject(rs.getString(1));
                    builder.setMessageId(rs.getString(2));
                    builder.setFrom(rs.getString(3));
                    builder.setDate(rs.getDate(4));

我的错误:

...whole 'body' field
</body>
</html>

' can not be represented as java.sql.Date
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:988)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:974)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:919)
    at com.mysql.jdbc.ResultSetRow.getDateFast(ResultSetRow.java:141)
    at com.mysql.jdbc.BufferRow.getDateFast(BufferRow.java:707)
    at com.mysql.jdbc.ResultSetImpl.getDate(ResultSetImpl.java:2210)
    at com.mysql.jdbc.ResultSetImpl.getDate(ResultSetImpl.java:2172)
    at com.mchange.v2.c3p0.impl.NewProxyResultSet.getDate(NewProxyResultSet.java:3466)
    at me.unroll.bilbo.SQLRunner.getMime(SQLRunner.java:307)

当我在MySQLWorkbench中运行SQL时,结果行是预期的。 date是第4列。

获取subjectmessageIdfrom(或sender)的前三行按预期工作。第四行以某种方式跳到body。这很奇怪。

我正在检查ResultSet。特别是这里有以下领域:

  

领域originalTableName = SR,COLUMNNAME =受试者,mysqlType = 253(FIELD_TYPE_VAR_STRING)]   领域originalTableName = SR,COLUMNNAME = MESSAGE_ID,mysqlType = 253(FIELD_TYPE_VAR_STRING)]   领域originalTableName = SR,COLUMNNAME =发件人,mysqlType = 253(FIELD_TYPE_VAR_STRING)]   领域originalTableName = SR,COLUMNNAME =日期,mysqlType = 7(FIELD_TYPE_TIMESTAMP)]   领域originalTableName = SRB,COLUMNNAME =类型,mysqlType = 1(FIELD_TYPE_TINY)]   领域originalTableName = SRB,COLUMNNAME =顺序,mysqlType = 1(FIELD_TYPE_TINY)]   领域originalTableName = SRB,COLUMNNAME =体,mysqlType = 253(FIELD_TYPE_VAR_STRING)]

我缩写为我可以确定的相关内容(字段上的命名空间,内存地址和Field中的不相关字段)。你可以清楚地看到所有7个,顺序是第4个是FIELD_TYPE_TIMESTAMP的日期,就像我期望的那样。

ResultSet.get方法是从1编制索引的。无论如何这都是事实,并且我正在通过检查builder准确检索主题和messageId这一事实进一步验证了这一点:

<1234567890.JavaMail.app@12345.abcde>
Voted Top 10 Best Magazines By Whoever

(字段省略,但可以清楚地看到正如预期的那样)。

然而,召唤rs.getDate(4)会让一切都失败。为什么?我的下一个调试步骤是逐步完成实现,看看发生了什么,但这对我来说是正确的设置,所以在这里发布SO。

1 个答案:

答案 0 :(得分:3)

这是我们之前遇到的MySQL错误0000-00-00打破了所有内容。一个补丁是在阅读之前将日期0000-00-00转换为NULL。这是众所周知的,可以通过驱动程序或连接属性进行修复。我很肯定有一个更标准的方法可以做到这一点,但无论如何这都是诀窍:

String url = env.database().url;
char separator = url.contains("?") ? '&' : '?';
url += separator + "zeroDateTimeBehavior=convertToNull";

cpds.setJdbcUrl(url);

请参阅:

https://stackoverflow.com/a/1180131/1339987

https://stackoverflow.com/a/2524493/1339987