2016-06-08 17 views
0

Возможно ли выполнить два или более оператора select в одном запросе в SQLite? Например,Как выполнить несколько операторов select в одном запросе в sqlite в iOS?

Мы можем выполнить создать или вставить запрос,

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?

Обычно мы Fetching данные, такие как,

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)); 
} 

Но если есть два оператор выбора, то как определить столбец и строку в sqlite3_step?

Мы можем выполнить два оператора select вместе (например, выбрать * из Employee, выбрать * из отдела) в терминале, так что это должно быть каким-то образом в iOS, я думаю.

+0

Каждое заявление должно быть в двойных кавычках Для экс; const char * sql_stmt = "select 1 .....;" "выбрать 2 .....;" ; –

+1

Вы можете использовать 'sqlite3_exec' и использовать функции обратного вызова. Или, если количество столбцов/тип было одинаковым в двух запросах, вы можете сделать один запрос UNION. Но почему? – Rob

+1

1) Никогда не используйте 'select * from ...'. Всегда явно указывайте столбцы, которые вы хотите выбрать. 2) Почему вы хотите объединить два оператора 'select' вроде этого? Каждый из них возвращает совершенно разные значения. – rmaddy

ответ

0

Мы можем выполнить это, используя функцию 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

+1

Нет причин для этого, выполняя два отдельных запроса, каждый со своим явным списком столбцов. Какова ощущаемая выгода от этих двух запросов таким образом над «нормальным» способом? – rmaddy

+1

Да, существует множество значительных недостатков этого подхода, но есть краевые случаи, когда это может быть полезно. – Rob

+0

Лев, между прочим, вы говорите: «Но если мы реализуем функцию или метод стиля Objective-c, тогда мы должны передать' (__bridge void *) (self) 'как параметр." Я не верю, что это правда. Обратный вызов всегда должен быть функцией C-стиля. Но, передавая «self», эта функция C-стиля может по крайней мере теперь ссылаться на ваш объект «self» и вызывать его методы и/или получать доступ к своим свойствам. – Rob

2

Да, вы можете использовать sqlite3_exec() для выполнения двух операторов SELECT за один вызов. Вам просто нужно предоставить функцию обратного вызова, где вы обрабатываете строки результатов. Я никогда не использовал эту функцию, и как я понимаю документ, который вы сами используете, чтобы различать строки каждого утверждения; возможно, для этого можно использовать количество столбцов.

Я советую использовать sqlite3_exec() таким образом; это кажется довольно утомительным и подверженным ошибкам. sqlite3_prepare_*() должен быть способ, и он может обрабатывать только один набор результатов (запрос SELECT), но вы можете иметь открытые несколько операторов за раз, представленные дескриптором ppStmt. Если у вас есть проблемы с этим, вы должны описать их, а не размещать вопрос XY Problem.

+0

Да, 'sqlite3_exec()' и 'callback' сделали решение. Вы можете проверить мой ответ, чтобы узнать, как его реализовать. И ссылка была полезна в ответе ... спасибо за это. – Lion