简体   繁体   English

奇怪的SQLException:找不到列

[英]Strange SQLException: Column not found

I'm getting a weird SQLException on a function I run against a database using JDBC. 我在使用JDBC对数据库运行的函数上得到了一个奇怪的SQLException。 SQLException: Column 'Message' not found. SQLException:找不到列'消息'。

I have this in my function: 我的功能有这个:

    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();

And I got that error, so I added this after the 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));
        }

And when I run my code again this is what I get as a result: 当我再次运行我的代码时,这就是我得到的结果:

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

And here is a screenshot of my table's design, from MySQL Workbench 这是MySQL Workbench的表格设计截图 在此输入图像描述

And the data in the table 和表中的数据 在此输入图像描述

I really can't figure out what's going one here.... Anyone can help out? 我真的无法弄清楚这里有什么......有人可以帮忙吗?

EDIT 编辑
I've replaced the * in the SELECT statement just to add something to the question that I just noticed. 我已经在SELECT语句中替换了*只是为了添加一些我刚注意到的问题。
If I remove the Message column from the select then I get the same error for the TimeStamp column. 如果我从select中删除Message列,那么TimeStamp列会出现相同的错误。 And if I remove both columns I get no errors then. 如果我删除两列,那么我没有错误。

EDIT2 EDIT2
OK,this is the part i get the errors, i get both on Message and Timestamp: 好的,这是我得到错误的部分,我得到消息和时间戳:

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();
        }
    }

I get the error on the getString() methods for each column 我在每列的getString()方法上得到错误
StackTrace for TimeStamp (the same for Message ): 栈跟踪用于TimeStamp (同样为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)

If you observe your code 如果你观察你的代码

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

you have used "Timestamp" in this format but if you changed it to "TimeStamp" as specified in your database, hopefully it will work. 您已使用此格式的“Timestamp”,但如果您将其更改为数据库中指定的“TimeStamp”,则希望它能够正常工作。

Change datatype of your isNotified column as TINYINT in database and retry to insert 将isNotified列的数据类型更改为数据库中的TINYINT,然后重试插入

isNotified TINYINT(1)

Bool, Boolean: These types are synonyms for TINYINT(1). Bool,Boolean:这些类型是TINYINT(1)的同义词。 A value of zero is considered false. 值为零被视为false。 Non-zero values are considered true. 非零值被认为是真实的。

Can you change 你能改变吗?

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

to

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

so that we can see if there is whitespace in the "Message" column name? 这样我们就可以看到“消息”列名中是否有空格?

The fact that the error message comes between column 5 and 6 is not important I think, because one is Standard Output and the other one Standard Error, these are not synchronized output streams. 我认为错误消息在第5列和第6列之间的事实并不重要,因为一个是标准输出而另一个是标准错误,这些不是同步的输出流。

(Also see the previous answer about Timestamp vs TimeStamp.) (另请参阅上一个关于Timestamp vs TimeStamp的答案。)

It sounds like the table metadata is corrupt. 听起来表元数据已损坏。 You should be able to correct this by dropping and recreating the table, although if the metadata is really borked you may not be able to drop the table. 你应该能够通过删除和重新创建表来纠正这个问题,尽管如果元数据确实很糟糕,你可能无法删除表格。 If that's the case or you need to keep the data, backing up and restoring the whole database is the way to go, but check the SQL dump file before restoring and/or restore to another database name before dropping the broken database. 如果是这种情况,或者您需要保留数据,则备份和还原整个数据库是可行的方法,但在删除损坏的数据库之前,请在还原和/或还原到其他数据库名称之前检查SQL转储文件。 Depending on exactly what's wrong, your problem columns may be missing from the dump. 根据确切的错误,转储中可能缺少您的问题列。

If refreshing the database is not an option there are ways to perform targetted repairs, but I'm no expert so I can't advise you on that. 如果刷新数据库不是一个选项,有办法进行目标修复,但我不是专家,所以我无法就此提出建议。 Again, back up your database AND verify that the backup is complete (ie it has all your columns) before proceeding. 再次,备份数据库并在继续之前验证备份是否完整(即它包含所有列)。 If this is a production database, I would be very wary about taking advice from the internet on manipulating metadata. 如果这是一个生产数据库,我会非常谨慎地从互联网上获取有关操纵元数据的建议。 Minor differences in version, storage engine and environment can make or break you with this stuff, and given the nature of the problem you can't do a dry run. 版本,存储引擎和环境方面的细微差别会使这些东西产生或破坏,并且鉴于问题的本质,您无法进行干运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM