有人可以帮我告诉我代码有什么问题吗?我正在尝试连接到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);
}
}
}
谢谢你的帮助。
答案 0 :(得分:2)
我没有看到您关闭语句并在select
和delete
操作后关闭数据库。很可能你无法打开数据库,因为它没有正确关闭。
大警告当用户将设备安装到PC作为外部驱动器时,SD卡不可用。有些设备没有预先安装SD卡。 5个OS设备上的数据库操作非常慢。您的alert
方法代码不会关闭db在下一个应用程序启动后打开它可能会出现什么问题。
警告正如@pankar在评论中提到的那样,您应该添加finally {}
,您肯定会在那里关闭资源。在当前的实现中,如果执行中出现异常,则永远不会关闭数据库。
重大改进您不需要在每个循环中创建和准备语句。就在for
之前做。绑定并执行每个循环。并在for
之后关闭声明。
改进您可以在应用程序运行周期中保留一个已打开的数据库。它将为您节省一些代码和开始结束的时间。
符号将参数命名为'string'是不好的做法。我会把它重命名为更有意义的东西。