简体   繁体   English

字符串索引超出范围jdbc编程中的异常

[英]String Index out of range Exception in jdbc programming

I have a database table consisting of 6 columns and 6 rows. 我有一个由6列和6行组成的数据库表。 I want to access all 6 column values of the 2nd row, but I'm unable to figure out why I'm getting this exception. 我想访问第二行的所有6列值,但无法弄清楚为什么会出现此异常。

public void send()
{
int row=2;
    try
    {
    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
    Connection cn=DriverManager.getConnection("jdbc:odbc:DSN2");
    Statement st=cn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
    ResultSet rs=st.executeQuery("select *from Table1");
    rs.absolute(row);
    System.out.println(rs.getInt(1)+"\t"+rs.getInt(2)+"\t"+rs.getInt(3)+"\t"+rs.getInt(4)+"\t"+rs.getInt(5)+"\t"+rs.getInt(6));

    }

java.lang.StringIndexOutOfBoundsException: String index out of range: -1 at java.lang.String.substring(String.java:1958) at sun.jdbc.odbc.JdbcOdbcResultSet.reWordAsCountQuery(JdbcOdbcR‌​esultSet. java:6557) at sun.jdbc.odbc.JdbcOdbcResultSet.calculateRowCount(JdbcOdbcRe‌​sultSet.j ava:6350) at sun.jdbc.odbc.JdbcOdbcResultSet.initialize(JdbcOdbcResultSet‌​.java:154) at sun.jdbc.odbc.JdbcOdbcStatement.getResultSet(JdbcOdbcStateme‌​nt.java:4 23) at sun.jdbc.odbc.JdbcOdbcStatement.executeQuery(JdbcOdbcStateme‌​nt.java:2 53)at Router.send(Router1.java:37)at Router1.main(Router1.java:54) java.lang.StringIndexOutOfBoundsException:字符串索引超出范围:在sun.jdbc.odbc.JdbcOdbcResultSet.reWordAsCountQuery(JdbcOdbcR‌esultSet.java:6557)在java.lang.String.substring(String.java:1958)处为-1 .jdbc.odbc.JdbcOdbcResultSet.calculateRowCount(JdbcOdbcRe‌sultSet.j ava:6350)位于sun.jdbc.odbc.JdbcOdbcResultSet.initialize(JdbcOdbcResultSet‌.java:154)位于sun.jdbc.odbc.JdbcStateSet中。 .java:4 23)在sun.jdbc.odbc.JdbcOdbcStatement.executeQuery(JdbcOdbcStateme‌nt.java:2 53)在Router.send(Router1.java:37)在Router1.main(Router1.java:54)

Your SQL statement is not valid, likely causing the issue (assuming what you pasted in your OP is what you are really using) 您的SQL语句无效,可能会引起问题(假设您粘贴到OP中的是您实际使用的内容)

select *from Table1

should be 应该

select * from Table1

The * needs to have a space between it and from . *需要有它之间的空间from

Also, it's worth mentioning that it's best practice with SQL to make your keywords all caps... so your statement re-written as such: 另外,值得一提的是,使用SQL的最佳做法是使关键字全部大写...因此您的语句应这样重写:

SELECT * FROM Table1

Also best practice to have your tables not begin with capital letters, or have caps in them at all... but this would have to be delt with when creating the database. 最好的做法是使表不以大写字母开头或完全没有大写字母...但这在创建数据库时必须消除。

Also, just as a learning note: 另外,作为学习笔记:

Your current method will open a new database connection every time you run this method... which will cause significant performance bottlenecks/problems if this method is called often. 您的当前方法每次运行此方法时都会打开一个新的数据库连接...如果经常调用此方法,将导致严重的性能瓶颈/问题。 Instead, it's much better to open the connection as your program starts up, then you can use that same connection over and over to run statements, then when your program is terminating, have it close the database connection. 相反,最好在程序启动时打开连接,然后可以反复使用同一连接来运行语句,然后在程序终止时关闭数据库连接。 This removes a lot of network activity/overhead in communicating with your database and will yield much better performance and scalability of your code. 这消除了与数据库通信时的大量网络活动/开销,并将产生更好的性能和代码可伸缩性。

Also, it's worth mentioning, look into PreparedStatement . 另外,值得一提的是,查看PreparedStatement These will allow you to create your statement before you need them, and then just re-use the same statement over and over, which will yield even greater performance, as well as provide more security/safety if your queries will use user-input at some point ( PreparedStatement automatically escapes input strings to avoid SQL-Injection attacks). 这些将使您能够在需要它们之前创建语句,然后一次又一次地重复使用同一条语句,这将产生更高的性能,并且如果查询将在以下位置使用用户输入,则将提供更多的安全性/安全性。某些点( PreparedStatement自动转义输入字符串以避免SQL注入攻击)。

UPDATE --

Some code to try: 尝试一些代码:

public void send() {

    try {
        Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        Connection cn=DriverManager.getConnection("jdbc:odbc:DSN2");
        Statement st=cn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
        ResultSet rs=st.executeQuery("SELECT * FROM Table1");

        // debug section
        ResultSetMetaData rsmd = rs.getMetaData();
        System.out.println("DEBUG: Number of columns = " + rsmd.getColumnCount());
        // end debug

        while(rs.next()) {
            System.out.println(rs.getInt(1)+"\t"+rs.getInt(2)+"\t"+rs.getInt(3)+"\t"+rs.getInt(4)+"\t"+rs.getInt(5)+"\t"+rs.getInt(6));
        }

    } catch(Exception e) {
        e.printStackTrace();
    }
}

This will print a line telling us how many columns are in your ResultSet 这将打印一条线,告诉我们您的ResultSet有多少列

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

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