执行查询“删除”时DatabaseIOException

时间:2012-08-10 11:21:32

标签: sqlite blackberry java-me

有人可以帮我告诉我代码有什么问题吗?我正在尝试连接到SQLite数据库,并执行一些查询。在尝试创建和打开数据库时,创建并插入表,不返回任何异常。但是当我尝试执行delete语句时,

  

DatabaseIOException:文件系统错误(12)

总是回来。我完全不知道异常的原因。你能告诉我通常会导致这种例外吗?我甚至不知道何时需要关闭数据库以及何时不需要。 this solution也让我感到困惑。

这是我的代码:

public class DatabaseManager {

    Logger log = new Logger();
    Database db;

    public DatabaseManager() {
        createDatabase();
    }

    private void createDatabase() {

        // Determine if an SDCard is present 
        boolean sdCardPresent = false;
        String root = null;
        Enumeration enum = FileSystemRegistry.listRoots();
        while (enum.hasMoreElements()) {
            root = (String) enum.nextElement();
            if(root.equalsIgnoreCase("sdcard/")) {
                sdCardPresent = true;
            }     
        }
        if(!sdCardPresent) {
            alert("This application requires an SD card to be present. Exiting application...");
        }          
        else {    
            try {
                URI uri = URI.create("/SDCard/databases/MyAdvanceUI/myadvanceui.db");
                db = DatabaseFactory.openOrCreate(uri);
                db.close();
                //alert("Database OK!");
            } catch (Exception e) {
                // TODO Auto-generated catch block
                //alert("Exception in createDatabase(): " + e);
            }
        }
   }

private void alert(final String message) {
    UiApplication.getUiApplication().invokeLater(new Runnable() {
        public void run() {
            Dialog.inform(message);
            System.exit(0);
        }
    });
}

private void createTableTask() {
    try {
        URI uri = URI.create("/SDCard/databases/MyAdvanceUI/myadvanceui.db");
        db = DatabaseFactory.open(uri);
        Statement st = db.createStatement("CREATE TABLE IF NOT EXISTS t_task (id INTEGER PRIMARY KEY AUTOINCREMENT, "
                + "client TEXT, task TEXT)");
        st.prepare();
        st.execute();
        st.close();
        db.close();
        //alert("Table Task created!");
    } catch (Exception e) {
        // TODO: handle exception
        //alert("Exception in createTableTask(): " + e);
    }
}

private void insertTableTask() {

    String[] clients = { "Budi Setiawan", "Dian Kusuma", "Joko Ahmad", "Titi Haryanto", "Wahyu" };
    String[] tasks = { 
        "Penawaran terhadap instalasi server",
        "Follow up untuk keperluan produk terbaru",
        "Pendekatan untuk membina relasi", 
        "Penawaran jasa maintenance",
        "Penawaran terhadap instalasi database" 
    };

    try {
        URI uri = URI.create("/SDCard/databases/MyAdvanceUI/myadvanceui.db");
        db = DatabaseFactory.open(uri);

        for(int i = 0; i < clients.length; i++) {
            Statement st = db.createStatement("INSERT INTO t_task (client, task) VALUES (?, ?)");
            st.prepare();
            st.bind(1, clients[i]);
            st.bind(2, tasks[i]);
            st.execute();
            st.close();

        }
        db.close();
    } catch (Exception e) {
        // TODO: handle exception
        //alert("Exception in insertTableTask(): " + e);
    }

}

public void loadInitialData() {
    createTableTask();
    insertTableTask();
}

public Cursor getTasks() {
    // TODO Auto-generated method stub
    Cursor results = null;
    try {
        URI uri = URI.create("/SDCard/databases/MyAdvanceUI/myadvanceui.db");
        db = DatabaseFactory.open(uri);
        Statement st = db.createStatement("SELECT client, task FROM t_task");
        st.prepare();
        results = st.getCursor();

        return results;
    } catch (Exception e) {
        // TODO: handle exception
        //alert("Exception: " + e);
    }

    return results;
}

public void delete(String string) {
    // TODO Auto-generated method stub

    try {
        URI uri = URI.create("/SDCard/databases/MyAdvanceUI/myadvanceui.db");
        db = DatabaseFactory.open(uri);
        Statement st = db.createStatement("DELETE FROM t_task WHERE client=?");
        st.prepare();
        st.bind(1, string);
        st.execute();
    } catch (Exception e) {
        // TODO: handle exception
        alert("Exception: " + e);
    }
    }

}

谢谢你的帮助。

1 个答案:

答案 0 :(得分:2)

我没有看到您关闭语句并在selectdelete操作后关闭数据库。很可能你无法打开数据库,因为它没有正确关闭。

大警告当用户将设备安装到PC作为外部驱动器时,SD卡不可用。有些设备没有预先安装SD卡。 5个OS设备上的数据库操作非常慢。您的alert方法代码不会关闭db在下一个应用程序启动后打开它可能会出现什么问题。

警告正如@pankar在评论中提到的那样,您应该添加finally {},您肯定会在那里关闭资源。在当前的实现中,如果执行中出现异常,则永远不会关闭数据库。

重大改进您不需要在每个循环中创建和准备语句。就在for之前做。绑定并执行每个循环。并在for之后关闭声明。

改进您可以在应用程序运行周期中保留一个已打开的数据库。它将为您节省一些代码和开始结束的时间。

符号将参数命名为'string'是不好的做法。我会把它重命名为更有意义的东西。