我正在开发一个应用程序商店中的应用程序,FMDB用于与其sqlite数据库进行交互.我们收到了一些崩溃报告,堆栈跟踪如下:
Thread : Crashed: NSOperationQueue 0x170239c20 :: NSOperation 0x17024d7d0 (QOS: LEGACY)
0 libobjc.A.dylib 0x000000019701c0b4 objc_retain + 20
1 MyApp 0x00000001002bdff4 FMDBBlockSQLiteCallBackFunction
2 MyApp 0x00000001002bdb1c FMDBBlockSQLiteCallBackFunction
3 MyApp 0x00000001002b66b4 FMDBBlockSQLiteCallBackFunction
4 MyApp 0x00000001002980fc FMDBBlockSQLiteCallBackFunction
5 MyApp 0x000000010029f20c FMDBBlockSQLiteCallBackFunction
6 CFNetwork 0x00000001851475a4 __49-[__NSCFLocalSessionTask _task_onqueue_didFinish]_block_invoke + 300
7 Foundation 0x00000001866bf1c4 __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 16
8 Foundation 0x0000000186610604 -[NSBlockOperation main] + 96
9 Foundation 0x00000001866001cc -[__NSOperationInternal _start:] + 636
10 Foundation 0x00000001866c1f28 __NSOQSchedule_f + 228
11 libdispatch.dylib 0x0000000197655954 _dispatch_client_callout + 16
12 libdispatch.dylib …Run Code Online (Sandbox Code Playgroud) 现在这可能看起来像一个重复的线程,但我的问题是我已经阅读了很多问题,如核心数据与SQLite 3和其他人,但这些都是2 - 3年.我还读到FMDB是由于iOS上不支持核心数据而开发的,因此不应再使用它了.而另一方面,我已经读过,不应该将核心数据用作数据库.
所以我很困惑,我是否应该使用核心数据进行对象存储.我的意思是在什么基础上我应该决定使用哪个?是否有苹果或其他人提供的指导方针......或者是时间会来找我的东西.
在iPhone上,使用FMDB获取SQLite数据库上最后插入行的ID的最佳方法是什么?
有没有更好的方式而不是做:
SELECT MAX(ID)
Run Code Online (Sandbox Code Playgroud) 有没有人知道如何在使用FMDB时返回查询计数?如果我执行Query @"selecttable(*)from sometable是......"我得到一个空的FMResultSet.如何获取查询的行数?我是否需要执行诸如"select*from sometable where .."之类的查询并迭代结果集?或者我可以使用useCount或最好的方式(在性能方面)做到这一点?
谢谢!
是否可以通过FMDB将数组传递给SELECT ... WHERE ... IN语句?我试图像这样内爆数组:
NSArray *mergeIds; // An array with NSNumber Objects
NSString *mergeIdString = [mergeIds componentsJoinedByString:@","];
NSString *query = @"SELECT * FROM items WHERE last_merge_id IN (?)";
FMResultSet *result = [database executeQuery:query, mergeIdString];
Run Code Online (Sandbox Code Playgroud)
这只适用于数组中只有一个对象,这使我相信FMDB在整个内爆字符串周围添加了引号.
所以我尝试将数组传递给FMDB的方法:
NSArray *mergeIds; // An array with NSNumber Objects
NSString *query = @"SELECT * FROM items WHERE last_merge_id IN (?)";
FMResultSet *result = [database executeQuery:query, mergeIds];
Run Code Online (Sandbox Code Playgroud)
这根本不起作用.
我没有在README或FMDB的github页面上的示例中找到任何关于它的内容.
谢谢,斯特凡
有人能解释一下使用FMDB在iPhone上插入大量数据的最佳方法是什么?我看到使用beginTransaction命令之类的东西.老实说,我不确定这个或setShouldCacheStatements是做什么的.我按照我的同事到目前为止所做的代码,这就是它的样子:
BOOL oldshouldcachestatements = _db.shouldCacheStatements;
[_db setShouldCacheStatements:YES];
[_db beginTransaction];
NSString *insertQuery = [[NSString alloc] initWithFormat:@"INSERT INTO %@ values(null, ?, ?, ?, ?, ?, ?, ?);", tableName];
[tableName release];
BOOL success;
bPtr += 2;
int *iPtr = (int *)bPtr;
int numRecords = *iPtr++;
for (NSInteger record = 0; record < numRecords; record++) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Some business logic to read the binary stream
NSNumber *freq = aFreq > 0 ? [NSNumber numberWithDouble:100 * aFreq / 32768]: …Run Code Online (Sandbox Code Playgroud) 我在我的应用程序中使用两种不同类型的fmdb连接:
所有READ查询的FMDatabase和所有UPDATE查询的FMDatabaseQueue.
两者都由一个单例处理,这使得两种类型在应用程序运行时保持打开状态.
读取和更新查询都在不同的线程中使用,因为我的应用程序中的某些任务是在后台进行的; 比如从服务器获取数据并通过FMDatabaseQueue在自己的后台线程中将其插入数据库 - 同时通过FMDatabase从db读取一些信息并在主线程上用它更新ViewController.
我的问题是,通过FMDatabaseQueue将数据插入数据库后,第二个连接(FMDatabase)不会返回更新的信息,因为它找不到它们.但我知道插入的数据是因为我使用db浏览器工具检查了数据库+插入时没有发生错误.为避免这种情况,我必须关闭FMDatabase数据库连接并重新打开它以查看其他连接所做的更改.不幸的是,当我的应用程序启动时,有许多插入,更新+读取,因为从服务器加载了许多需要处理的新数据 - 因此每次更新时关闭并打开数据库会发生在许多"数据库忙"消息.
我已经为所有线程使用了一个FMDatabaseQueue并执行(读取,更新)之前但是当使用__block变量的读取查询从回调中获取结果集而另一个线程执行一些插入(在50-100之间)时它非常慢单笔交易).
最重要的是,数据库是通过sqlcipher加密的 - 不确定它是否重要但是想要提及它.所以每次我必须关闭并打开数据库时,我正在做一个setKey.
我的问题:是否可以在多个线程上使用具有两种不同连接类型的设置,如果是,是否必须关闭并打开FMDatabase连接?或者这个用例有更好的解决方案吗?
我执行插入/更新的代码看起来像
-(void) create:(NSArray *)transactions
{
NSMutableString *sqlQuery = [[NSMutableString alloc] initWithString:STANDARD_INSERT_QUERY];
[sqlQuery appendString:@"(transaction_id, name, date) VALUES (?,?,?)"];
FMDBDataSource *ds = [FMDBDataSource sharedManager];
FMDatabaseQueue *queue = [ds getFMDBQ];
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
[db setKey:[ds getKey]]; // returns the key to decrypt the database
for (Transaction *transaction in transactions)
{
[db executeUpdate:sqlQuery, transaction.transactionId, transaction.name, transaction.date];
}
}];
}
Run Code Online (Sandbox Code Playgroud)
和一个读取查询
-(Transaction *)read:(NSString *)transactionId
{
NSString …Run Code Online (Sandbox Code Playgroud) 我正在使用FMDB,它是SQLite的包装器.http://github.com/ccgus/fmdb
这是我的查询行:
FMResultSet *athlete = [db executeQuery:@"SELECT * FROM athletes WHERE athlete_name LIKE ?", search_text];
Run Code Online (Sandbox Code Playgroud)
如果我输入运动员的确切名字,我可以用这个来得到结果.但是,我正在尝试使用LIKE,所以我可以搜索名称.但是,当我添加%?%而不是仅仅?......没有回报.而且没有错误.
有没有人遇到过这个,知道我做错了什么?
感谢大家!
我使用FMDB在Swift中创建了一个SQLite数据库.但现在我想加密它.那么有谁能帮助我使用'FMDB/SQLCipher'加密和解密SQLite数据库的Swift版本?我无法找到一个很好的教程来理解这一点.
有没有一种简单的方法可以轻松地将FMDB结果executeQuery:SELECT * ...放入字典中?
FMResultSet *appointmentResults = [[DataClass getDB] executeQuery:@"SELECT * FROM Appointments WHERE date = ?",currDateString];
while ([appointmentResults next]) {
//Create dictionary
//Add dictionary to array for later use
}
Run Code Online (Sandbox Code Playgroud)
我想知道是否有一种方法可以使字典键为列名,值为列值.优选地,不必在一段时间内遍历每一行.