如何在iOS应用程序中连接FMDB中两个不同数据库的两个表

时间:2015-06-04 08:28:30

标签: ios sqlite fmdb

我的情况是这样的。 出于安全原因,我决定将应用数据放入捆绑包,将用户数据放入文档目录。 问题是如何从不同的数据库加入表? 如果不可能,我是否必须在文档目录中创建一个数据库表?

1 个答案:

答案 0 :(得分:6)

Sqlite3允许它将外部数据库附加到当前连接。 想象一下,您有两个数据库,每个数据库通过FMDatabase保存自己的连接(出于多线程目的,您应该使用FMDatabaseQueue)。 现在,将另一个数据库附加到第一个数据库的连接。然后,您可以从数据库1加入数据库2中的表。重要说明:所有这些都是通过sqlite per sql语句进行的,与FMDB无关。

我将在github上提供示例代码: https://github.com/itinance/MultiDatabaseJoin

为简单起见,我将数据库文件放在/ tmp-directory下。 使用iOS-Simulator这很好用,我还没有在真正的设备中测试过这段代码,你可以将数据库放在文件夹或类似的东西中(但这还不是重点)。

这里重要的是sqlite3中的以下查询:

[db1 executeStatements:@"ATTACH DATABASE '/tmp/tmp2.db' AS second_db"];

在数据库连接db 1 ,我们从第二个数据库附加数据库文件。

在此附加之后,您可以在类似这样的查询中将Database-Connection 1加入数据库连接2中的表:

SELECT a.id, a.name AS aname, b.name AS bname FROM a INNER JOIN second_db.b ON b.a_id = a.id

这是我尝试的整个代码:

FMDatabase *db1 = [FMDatabase databaseWithPath:@"/tmp/tmp1.db"];
FMDatabase *db2 = [FMDatabase databaseWithPath:@"/tmp/tmp2.db"];

[db1 open];
[db2 open];

[db1 executeStatements:@"CREATE TABLE a (id INTEGER, name TEXT)"];
[db1 executeStatements:@"INSERT INTO a (id, name) VALUES (1, 'foo'), (2, 'bar')"];

[db2 executeStatements:@"CREATE TABLE b (id INTEGER, a_id INTEGER, name TEXT)"];
[db2 executeStatements:@"INSERT INTO b (id, a_id, name) VALUES (1, 1, 'b_foo'), (2, 2, 'b_bar')"];

bool success = [db1 executeStatements:@"ATTACH DATABASE '/tmp/tmp2.db' AS second_db"];
if(!success) {
    NSLog(@"%@", db1.lastErrorMessage);
    return YES;
}

FMResultSet* rs = [db1 executeQuery:@"SELECT a.id, a.name AS aname, b.name AS bname FROM a INNER JOIN second_db.b ON b.a_id = a.id"];
while( [rs next]) {
    NSLog(@"%@, %@", [rs stringForColumn:@"aname"], [rs stringForColumn:@"bname"]);
}
[rs close];