我有一个经常访问sqlite数据库的应用程序。它大部分时间都很好用,但偶尔会在我的一个数据库函数中失败并返回:
文件已加密或不是数据库
我没有启用任何加密,但我无法确定这是怎么回事。它不是一贯可重复的,并且从崩溃日志中,它发生在主线程上。
提前致谢。
@synchronized(self) {
sqlite3 *database = mydb;
int result = 0;
static sqlite3_stmt *stmt = nil;
if (stmt == nil) {
const char *sql = "select sum(not isAvailable) from table1 e inner join table2 f on e.key=f.pk where f.pk=? AND e.isDeleting=0;";
if (sqlite3_prepare_v2(database, sql, -1, &stmt, NULL) != SQLITE_OK) {
NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}
}
sqlite3_bind_int(stmt, 1, obj.primaryKey);
if (sqlite3_step(stmt) == SQLITE_ROW) {
int val = sqlite3_column_int(stmt, 0);
result = val;
} else {
[NSException raise:@"SQL Fail" format:@"SQL Failed: %s", sqlite3_errmsg(database)];
}
// Reset the statement for future reuse.
sqlite3_reset(stmt);
return result;
}
答案 0 :(得分:1)
要创建新的加密SQLite数据库或打开现有的加密SQLite数据库,您必须在执行任何其他数据库操作之前立即调用函数sqlite3_key或在打开数据库后立即执行“pragma key =”命令。 我怀疑您尝试打开现有数据库,但未尝试加密SQLite数据库,并希望使用上述方法之一对其进行加密。这不起作用,但会导致您遇到错误消息。 要加密现有的未加密SQLite数据库,必须使用函数sqlite3_rekey或“pragma rekey =”命令。 要更改现有加密SQLite数据库的加密密钥,您必须打开数据库,然后使用sqlite3_key(或“pragma key =”),然后应用sqlite3_rekey(或“pragma rekey =”)。
答案 1 :(得分:0)
当DB文件以某种方式变得乱码时,会发生错误。究竟为什么会出现这种情况,这有点难题。
如果您在应用中编写其他文件,则可能意外覆盖了DB文件。如果您要在DB上打开相同的DB文件两次或在DB上执行两个“同时”操作,那么可能能够创建此场景(但我认为大多数版本的SQLite都是使用代码编译的检测到这一点并在出现冲突时输出错误)。 (问题:你有没有得到“数据库被锁定”的错误?)
答案 2 :(得分:0)
由于“版本不匹配”建议通常没有帮助,我遇到了相同的症状,发现问题是通过将数据库从版本2更新到3来解决的。可能出现此问题的原因之一是文件数据库的扩展名不一定正确反映实际版本号。
我可能会弄错,但是当我使用SQLite管理员版本0.8.3.2创建我的第一个SQLite数据库并接受SQLite3 DB的默认“另存为类型”时,它创建的文件显然是版本2数据库,尽管有一个。 s3db名称。在Databases菜单下,启用了“Migrate to SQLite3”项,但我认为这是GUI中的一个错误。然而,在使用该功能后,我的问题就消失了。
随后在SQLite Administrator中使用Database | New选项会创建我选择的版本的DB,并且文件扩展名与该版本的约定相匹配。 SQL管理员的错误行为仅在我第一次使用“数据库”|“新建”选项时发生。
答案 3 :(得分:0)
我今天遇到同样的问题。
原来,我在我的数据库中创建了一个名为Time的列。将其更改为TimeStamp并且它有效。我以为我的文件已被损坏所以我正在查看sql代码来生成表格(在新文件上重做它)当我注意到“时间”突出显示为蓝色表示它是一个保留字。