【问题标题】:Strange SQLException: Column not found奇怪的 SQLException:找不到列
【发布时间】:2013-10-30 01:46:40
【问题描述】:

我在使用 JDBC 对数据库运行的函数上遇到了一个奇怪的 SQLException。 SQLException: 未找到列“消息”。

我的函数中有这个:

    st = con.prepareStatement("SELECT NotificationID,UserIDFrom,UserIDTo,Message,Timestamp,isNotified FROM notification WHERE UserIDTo=? AND isNotified=?");
    st.setInt(1, _UserID);
    st.setBoolean(2, false);
    System.out.println("st is: " + st);
    rs = st.executeQuery();

我得到了那个错误,所以我在st.executeQuery() 之后添加了这个:

    ResultSetMetaData meta = rs.getMetaData();
    for (int index = 1; index <= meta.getColumnCount(); index++) {
        System.out.println("Column " + index + " is named " + meta.getColumnName(index));
        }

当我再次运行我的代码时,结果如下:

Column 1 is named NotificationID
Column 2 is named UserIDFrom
Column 3 is named UserIDTo
Column 4 is named Message
Column 5 is named TimeStamp
Exception in thread "main" java.sql.SQLException: Column 'Message' not found.
Column 6 is named isNotified

这是我的表格设计的屏幕截图,来自 MySQL Workbench

和表中的数据

我真的不知道这是怎么回事……有人可以帮忙吗?

编辑
我已经替换了SELECT 语句中的*,只是为了对我刚刚注意到的问题添加一些内容。
如果我从选择中删除Message 列,那么TimeStamp 列会出现相同的错误。如果我删除两列,则不会出现错误。

EDIT2
好的,这是我得到错误的部分,我得到消息和时间戳:

while (rs.next()) {
        NotificationID = rs.getInt("NotificationID");
        System.out.println("NotificationID: " + NotificationID);

        SenderID = rs.getInt("UserIDFrom");
        System.out.println("SenderID: " + SenderID);
        From = findUserName(SenderID);

        try {
            body = rs.getString("Message");
            System.out.println("body: " + body);
        } catch (Exception e) {
            System.out.println("Message error: " + e);
            e.printStackTrace();
        }

        try {
            time = rs.getString("Timestamp");
            System.out.println("time: " + time);
        } catch (Exception e) {
            System.out.println("Timestamp error: " + e);
            e.printStackTrace();
        }
    }

我在每列的 getString() 方法上收到错误
TimeStamp 的 StackTrace(Message 相同):

java.sql.SQLException: Column 'TimeStamp' not found.
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1078)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:975)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:920)
    at com.mysql.jdbc.ResultSetImpl.findColumn(ResultSetImpl.java:1167)
    at com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5733)
    at NotifyMe_Server.Database.getUnNotified(Database.java:444)
    at tests.Tests.main(Tests.java:39)

【问题讨论】:

  • 桌上有触发器吗?
  • 在 SQL 语句中手动设置 Int/Boolean 是否会报错?即,尝试“SELECT * FROM notification WHERE UserIDTo=1 AND isNotified=0”并在不设置 PreparedStatement 变量的情况下执行它。
  • 能否在列名中包含一些空格或奇怪的字符?
  • @abmitchell 我已经按照你说的方式尝试过了,但我仍然遇到同样的错误
  • 我建议您调试 jdbc 代码到引发异常的位置,并尝试跟踪您希望成功的比较失败。问题可能出在您的代码/配置中,但调试到 jdbc 将帮助您了解哪些问题没有排好。

标签: java mysql sqlexception


【解决方案1】:

如果你观察你的代码

try {
        time = rs.getString("Timestamp");
        System.out.println("time: " + time);
    } catch (Exception e) {
        System.out.println("Timestamp error: " + e);
        e.printStackTrace();
    }
}

您使用过这种格式的“Timestamp”,但如果您将其更改为数据库中指定的“TimeStamp”,希望它能正常工作。

【讨论】:

    【解决方案2】:

    在数据库中将 isNotified 列的数据类型更改为 TINYINT 并重试插入

    isNotified TINYINT(1)
    

    Bool、Boolean:这些类型是 TINYINT(1) 的同义词。零值被认为是错误的。非零值被认为是真的。

    【讨论】:

    • 我没有在数据类型中看到布尔选项,在 MySQL EDIT 顺便说一句,我在另一个表中有相同类型的字段,我使用'setBoolean( )' 在我的 java 代码中,它工作正常
    • 您使用的是哪个版本的 MSQL?
    • 不知道你为什么建议这个,我到处使用 Bit(1) 并且没有遇到问题。
    • 从 MySQL 命令行:服务器版本:5.6.13-log MySQL Community Server (GPL)
    【解决方案3】:

    你能改吗

    System.out.println("Column " + index + " is named " + meta.getColumnName(index));
    

    System.out.println("Column " + index + " is named '" + meta.getColumnName(index) + "'");
    

    以便我们可以查看“消息”列名称中是否有空格?

    我认为错误消息出现在第 5 列和第 6 列之间这一事实并不重要,因为一个是标准输出,另一个是标准错误,这些不是同步的输出流。

    (另请参阅关于 Timestamp 与 TimeStamp 的先前答案。)

    【讨论】:

      【解决方案4】:

      听起来表元数据已损坏。您应该能够通过删除并重新创建表来纠正此问题,但如果元数据真的很糟糕,您可能无法删除表。如果是这种情况,或者您需要保留数据,那么备份和恢复整个数据库是可行的方法,但在恢复之前检查 SQL 转储文件和/或在删除损坏的数据库之前恢复到另一个数据库名称。根据具体的问题,转储中可能缺少您的问题列。

      如果刷新数据库不是一个选项,那么有一些方法可以执行有针对性的修复,但我不是专家,所以我无法就此向您提供建议。同样,在继续之前备份您的数据库并验证备份是否完整(即它包含所有列)。如果这是一个生产数据库,我会非常谨慎地从互联网上获取有关操纵元数据的建议。版本、存储引擎和环境方面的细微差异可能会影响您使用这些东西的成败,并且鉴于问题的性质,您无法进行试运行。

      【讨论】:

        猜你喜欢
        • 2015-04-25
        • 2011-08-21
        • 2017-12-05
        • 2021-04-10
        • 2011-07-07
        • 2013-03-04
        • 1970-01-01
        • 2010-12-22
        • 1970-01-01
        相关资源
        最近更新 更多