简体   繁体   中英

Can't insert data more than 254 in sqlite database by java

I am using a java class which allow me to insert data into SQLite database from string. I am inserting the data by a loop. My string have 260 data. When I try to insert those data from string to sqlite database it works fine but stops at the position of 254 every time! Why ?!

for(i = 0; i < 260; i++)
    {
        try {
            Class.forName("org.sqlite.JDBC");
            connection = DriverManager.getConnection("jdbc:sqlite:D:\\new.db");
            java.sql.Statement statement = connection.createStatement();
            statement .executeUpdate("INSERT INTO suggestion (suggesting) VALUES('"+words[i]+"')");
             System.out.println(i + " - " + words[i]);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Word.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

Here is the error log from netbeans!

Exception in thread "main" java.lang.NullPointerException
    at org.sqlite.NestedDB$CausedSQLException.fillInStackTrace(NestedDB.java:442)
    at java.lang.Throwable.<init>(Throwable.java:250)
    at java.lang.Exception.<init>(Exception.java:54)
    at java.sql.SQLException.<init>(SQLException.java:140)
    at org.sqlite.NestedDB$CausedSQLException.<init>(NestedDB.java:435)
    at org.sqlite.NestedDB._open(NestedDB.java:63)
    at org.sqlite.DB.open(DB.java:77)
    at org.sqlite.Conn.<init>(Conn.java:88)
    at org.sqlite.JDBC.connect(JDBC.java:64)
    at java.sql.DriverManager.getConnection(DriverManager.java:571)
    at java.sql.DriverManager.getConnection(DriverManager.java:233)
    at test.Word.main(Word.java:106)
Java Result: 1

You are probably running out of connections, because you are not closing them as required before opening a new one. Running out of connections shouldn't throw a NullPointerException ; this seems to be a bug in sqlite.

A better and faster approach is: don't close the connection, but don't open a new connection every time.

You can do that like this:

try {
    Class.forName("org.sqlite.JDBC");
} catch (ClassNotFoundException ex) {
    Logger.getLogger(Word.class.getName()).log(Level.SEVERE, null, ex);
}
connection = DriverManager.getConnection("jdbc:sqlite:D:\\new.db");

for(i = 0; i < 260; i++)
{
    java.sql.Statement statement = connection.createStatement();
    try {
        statement.executeUpdate("INSERT INTO suggestion (suggesting) VALUES('"+words[i]+"')");
    } finally {
        // Statements, like connections, also need to be closed after use
        statement.close();
    }
    System.out.println(i + " - " + words[i]);
}

Here's a re-factoring and update that might help.

I am assuming that the SQLite driver does not like the fact that you do not close your connections after using them (the actual NullPointer is probably a bug in the library you are using).

I also added the use of a PreparedStatement (which would be more efficient and less risky to SQL Injection attacks) as well as correct closing of resources (prior to Java 7 try-with-resources of course).

    Connection connection = null;
    PreparedStatement insert = null;
    try {
        Class.forName("org.sqlite.JDBC");
        connection = DriverManager.getConnection("jdbc:sqlite:D:\\new.db");
        insert = connection.prepareStatement("INSERT INTO suggestion (suggesting) VALUES(?)");
        for (String word : words) {                
            insert.setString(1, word);
            System.out.println("Word "+word+" inserted");
        }
    } catch (ClassNotFoundException ex) {
        Logger.getLogger(Word.class.getName()).log(Level.SEVERE, "Driver not found", ex);
    } catch (SQLException sqle) {
        Logger.getLogger(Word.class.getName()).log(Level.SEVERE, "Could not execute SQL", sqle);
    } finally {
        if (insert != null) {
            try {
                insert.close();
            } catch (SQLException sqle) {
                Logger.getLogger(Word.class.getName()).log(Level.SEVERE, "Could not close prepared statement", sqle);
            }
            insert = null;
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException sqle) {
                Logger.getLogger(Word.class.getName()).log(Level.SEVERE, "Could not close connection", sqle);
            }
            connection = null;
        }
    }

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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