【问题标题】:How to execute multiple select statement in one query in sqlite in iOS?如何在 iOS 的 sqlite 的一个查询中执行多个 select 语句?
【发布时间】:2016-06-08 13:55:02
【问题描述】:

是否可以在 SQLite 的一个查询中执行两个或多个 select 语句?例如,

我们可以执行创建或插入查询,

NSString *create_query = @"create table if not exists Employee (id integer primary key, firstName text, lastName text);create table if not exists Department (id integer primary key, department text, devision text)";

通过使用,

sqlite3_exec(self.contactDB,[create_query UTF8String], NULL, NULL, &errorMessage) == SQLITE_OK)

我们可以执行它。

但如果查询类似于,

NSString *select_query = @"select * from Employee;select * from Department";

那么可以执行吗?如果是,那么如何区分数据和sqlite3_step

通常我们会获取类似的数据,

if (sqlite3_prepare_v2(self.contactDB, [select_query UTF8String], -1, &statement, NULL) == SQLITE_OK) {
    NSLog(@"prepared from data get");

    while (sqlite3_step(statement) == SQLITE_ROW) {
        NSString *department = [[NSString alloc]initWithUTF8String:(const char*)sqlite3_column_text(statement, 1)];
        NSString *devision = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statement, 2)];

        NSLog(@"Department : %@, Devision : %@",department,devision);
    }
    NSLog(@"errror1 is %s",sqlite3_errmsg(self.contactDB));
}

但是如果有两个select语句那么如何识别sqlite3_step中的列和行呢?

我们可以在终端中同时执行两个 select 语句(即 select * from Employee;select * from Department ),所以我认为它应该在 iOS 中以某种方式。

【问题讨论】:

  • 每个语句都应该用双引号括起来 For ex; const char *sql_stmt = "选择 1 .....;" “选择 2……;” ;
  • 您可以使用sqlite3_exec 并使用回调函数。或者,如果两个查询中的列计数/类型相同,您可以执行单个 UNION 查询。但为什么呢?
  • 1) 永远不要使用select * from ...。始终明确列出您希望选择的列。 2) 为什么要像这样组合两个select 语句?它们各自返回完全不同的值。
  • @rob :是的,回调有效。谢谢...... :) 我刚刚要求知识。我没有要求这样做。
  • @rmaddy :我刚刚询问了知识,因为我很困惑,如果在终端中可以,那么在 ios 中也应该可以。!

标签: ios objective-c sqlite


【解决方案1】:

是的,您可以使用sqlite3_exec() 在一次调用中执行两个 SELECT 语句。您只需提供一个回调函数来处理结果行。我从未使用过该功能,以及我如何理解您自己的文档来区分每个语句的行;也许可以使用列数。

我建议不要那样使用sqlite3_exec();这似乎相当乏味且容易出错。 sqlite3_prepare_*() 应该是要走的路,它只能处理一个结果集(SELECT 查询),但您可以一次打开多个语句,由 ppStmt 句柄表示。如果您对此有任何疑问,您应该描述它们,而不是发布XY Problem 问题。

【讨论】:

  • 是的,sqlite3_exec()callback 已经解决了。您可以查看我的答案以了解如何实现它。并且在答案中提供了有用的链接......谢谢。
【解决方案2】:

我们可以通过使用 C 风格的 callback 函数和 sqlite3_exec 来执行此操作。

互联网上没有合适的代码(我还没有找到!)所以我想用代码示例来回答。

我们可以像这样实现C - style callback方法

int myCallback(void *parameter, int numberOfColumn, char **resultArr, char **column)
{

NSLog(@"number of column %d",numberOfColumn); // numberOfColumn is return total number of column for correspond table

NSString *columnName = [[NSString alloc]initWithUTF8String:column[0]];  // This will return column name column[0] is for first, column[1] for second column etc
NSLog(@"column name is %@",columnName);

NSString *result = [[NSString alloc]initWithUTF8String:resultArr[2]]; // resultArr returns value for row with respactive column for correspond table. resultArr[2] considered as third column.

NSLog(@"result is %@",result);

return 0;
}

我们可以在 sqlite3_exec 函数中调用这个回调函数,例如,

NSString *getData = @"select * from Department;select * from Employee";


if (sqlite3_exec(self.contactDB, [getData UTF8String], myCallback, (__bridge void *)(self), &err) == SQLITE_OK ) {


    if (err) {

        NSLog(@"error : %s",err);
    }

    else {

        NSLog(@"executed sucessfully");
    }

}

我们已经制作了新娘:(__bridge void *)(self) 作为sqlite3_exec 的参数。在这种情况下,我们可以传递NULL,因为我们已经实现了 c 风格的函数。但是如果我们实现 Objective - c 风格的函数或方法,那么我们必须传递(__bridge void *)(self) 作为参数。

所以,通过回调函数,我们可以在一个语句中执行多个queries,无论是select类型查询还是其他。

参考:One-Step Query Execution Interface

【讨论】:

  • 没有理由这样做超过执行两个单独的查询,每个查询都有自己的明确列列表。与“正常”方式相比,以这种方式执行这两个查询有什么好处?
  • 是的,这种方法有许多明显的缺点,但在某些极端情况下它可能有用。
  • Lion,顺便说一句,你说“但是如果我们实现 Objective - c 风格的函数或方法,那么我们必须传递 (__bridge void *)(self) 作为参数。”我不相信这是真的。回调必须是 C 风格的函数。但是通过传递self,C 风格的函数至少现在可以引用您的self 对象并调用其方法和/或访问其属性。
  • @rmaddy :正如我之前所说,我只是想检查一下这是不是这样。就是这样。我不建议任何人使用这种方法。
猜你喜欢
  • 1970-01-01
  • 2012-08-15
  • 1970-01-01
  • 2014-07-24
  • 2013-10-15
  • 1970-01-01
  • 1970-01-01
  • 2014-03-03
  • 2022-11-21
相关资源
最近更新 更多