1

誰かが私のコードの何が問題なのか教えてもらえますか?SQLiteデータベースに接続しようとしていますが、いくつかのクエリを実行しています。データベースを作成して開き、テーブルを作成して挿入しようとしても、例外は返されません。しかし、deleteステートメントを実行しようとすると、

DatabaseIOException:ファイルシステムエラー(12)

常に返されます。例外の原因は正確にはわかりません。この種の例外の通常の原因を教えてください。いつデータベースを閉じる必要があるのか​​、いつ閉じる必要がないのかさえわかりません。この解決策も私を混乱させます。

これが私のコードです:

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

}

ご協力ありがとうございました。

4

1 に答える 1

2

アクションの後selectにステートメントを閉じてデータベースを閉じているようには見えません。deleteデータベースが正しく閉じられていないため、おそらくデータベースを開くことができません。

ユーザーが外部ドライブとして PC にデバイスをマウントした場合、SD カードは利用できません一部のデバイスは、SD カードがプリインストールされていません。5 OS デバイスでの DB 操作は非常に遅いです。あなたのalertメソッドコードは、次のアプリケーションの起動後にそれを開くために問題になる可能性があるdbを閉じません。

警告@pankar がコメントで述べたようにfinally {}、確実にリソースを閉じる場所を追加する必要があります。現在の実装では、実行中に例外が発生した場合、データベースを閉じることはありません。

大きな改善ループごとにステートメントを作成して準備する必要はありません。の前にそれをしてくださいfor。すべてのループをバインドして実行します。の後にステートメントを閉じforます。

改善点 アプリケーションの実行サイクル中に 1 つのデータベースを開いておくことができます。これにより、コードを数行節約し、オープニング クロージングの時間を節約できます。

記法'string' のような名前のパラメーターを持つことは悪い習慣です。より意味のある名前に変更します。

于 2012-08-10T11:59:57.007 に答える