2011-06-16 5 views
5

El comando ATTACH DATABASE es útil para transferir filas entre archivos de base de datos sqlite y le permite unir filas de tablas en bases de datos p.¿Pueden las aplicaciones sqlite de iPhone conectarse a otras bases de datos?

$ sqlite3 BookLoansDB.sqlite 
sqlite> ATTACH DATABASE '/Users/.../Documents/BooksDB.sqlite' AS books_db; 
sqlite> select B.BookName, B.Pages, BL.LentTo from main.tblBookLoan BL inner join books_db.tblBook B on B.BookID = BL.BookID; 
The Client|512|Jenny 
The Pelican Brief|432|Mike 

¿Cómo puedo hacer lo mismo desde objetivo-c en el iPhone. No he tenido éxito con este tipo de código:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentDirectory = [paths objectAtIndex:0]; 
const char *booksDBPath = [[documentDirectory stringByAppendingPathComponent:@"BooksDB.sqlite"] UTF8String]; 
const char *bookLoansDBPath = [[documentDirectory stringByAppendingPathComponent:@"BookLoansDB.sqlite"] UTF8String]; 
sqlite3 *bookLoansDB; 
int result = sqlite3_open(bookLoansDBPath, &bookLoansDB); 
sqlite3_stmt *attachStmt; 
NSString *attachSQL = [NSString stringWithFormat: @"ATTACH DATABASE \'%s\' AS books_db", bookLoansDBPath]; 
result = sqlite3_prepare_v2(bookLoansDB, [attachSQL UTF8String] , -1, &attachStmt, nil); 
char *errorMessage; 
result = sqlite3_exec(bookLoansDB, [attachSQL UTF8String], NULL, NULL, &errorMessage); 
sqlite3_stmt *selectStmt; 
NSString *selectSQL = @"select * from main.tblBookLoan BL inner join books_db.tblBook B on B.BookID = BL.BookID"; 
result = sqlite3_prepare_v2(bookLoansDB, [selectSQL UTF8String] , -1, &selectStmt, nil); 
// result == 1 
result = sqlite3_step(selectStmt) ; 
// result == 21 
if (result == SQLITE_ROW) 
{ 
    //do something 
} 

¿Se puede incluso hacer?

+0

Después de mirar sus comentarios Parece que la sqlite3_prepare_v2 resultado que tienes es 1, que es SQLITE_ERROR, usted debe comprobar el error con sqlite3_errmsg (bookLoansDB). – Joe

Respuesta

0

Puede adjuntar bases de datos en sqlite en el iPhone. Es difícil decir lo que está pasando con su código, pero debería ayudar si se ve un poco más a esto:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentDirectory = [paths objectAtIndex:0]; 
const char *booksDBPath = [[documentDirectory stringByAppendingPathComponent:@"BooksDB.sqlite"] UTF8String]; 
const char *bookLoansDBPath = [[documentDirectory stringByAppendingPathComponent:@"BookLoansDB.sqlite"] UTF8String]; 
sqlite3 *bookLoansDB; 
if (sqlite3_open(bookLoansDBPath, &bookLoansDB) == SQLITE_OK) { 
    NSString *attachSQL = [NSString stringWithFormat: @"ATTACH DATABASE \'%s\' AS books_db", bookLoansDBPath]; 
    char *errorMessage; 
    if (sqlite3_exec(bookLoansDB, [attachSQL UTF8String], NULL, NULL, &errorMessage) == SQLITE_OK && errorMessage == nil) { 
     sqlite3_stmt *selectStmt; 
     NSString *selectSQL = @"select * from main.tblBookLoan BL inner join books_db.tblBook B on B.BookID = BL.BookID"; 
     if (sqlite3_prepare_v2(bookLoansDB, [selectSQL UTF8String] , -1, &selectStmt, nil) == SQLITE_OK) { 
      while (sqlite3_step(selectStmt) == SQLITE_ROW) { 
       //process row 
      } 
     } 
     else { 
      NSLog(@"Error while creating select statement: '%s'", sqlite3_errmsg(bookLoansDB)); 
     } 
    } 
    else { 
     NSLog(@"Error while attaching databases: '%s'", errorMessage); 
    } 
} 
else { 
    NSLog(@"Failed to open database at %@ with error %s", booksDBPath, sqlite3_errmsg(bookLoansDB)); 
    sqlite3_close(bookLoansDB); 
} 

No he probado este código, el suyo acaba de modificar, por lo que podría requerir correcciones.

+0

Gracias. El uso de este código proporciona: Error al crear una instrucción select: 'no such table: books_db.tblBook' Frustrante, el mismo SQL funciona en el ejemplo de la línea de comando sqlite – Nick

6

Tengo el ejemplo funcionando (tenía mis nombres de bases de datos mezclados en el SQL "adjuntar base de datos"). Entonces, sí, se puede hacer. Gracias por apuntarme en la dirección correcta Deepmist

Como tales ejemplos son bastante difíciles de encontrar, he pegado la siguiente versión de trabajo.

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentDirectory = [paths objectAtIndex:0]; 
const char *booksDBPath = [[documentDirectory stringByAppendingPathComponent:@"BooksDB.sqlite"] UTF8String]; 
const char *bookLoansDBPath = [[documentDirectory stringByAppendingPathComponent:@"BookLoansDB.sqlite"] UTF8String]; 
sqlite3 *bookLoansDB; 
if (sqlite3_open(bookLoansDBPath, &bookLoansDB) == SQLITE_OK) { 
    NSString *attachSQL = [NSString stringWithFormat: @"ATTACH DATABASE \'%s\' AS books_db", booksDBPath]; 
    char *errorMessage; 
    if (sqlite3_exec(bookLoansDB, [attachSQL UTF8String], NULL, NULL, &errorMessage) == SQLITE_OK) { 
     sqlite3_stmt *selectStmt; 
     NSString *selectSQL = @"select * from main.tblBookLoan BL inner join books_db.tblBook B on B.BookID = BL.BookID"; 
     if (sqlite3_prepare_v2(bookLoansDB, [selectSQL UTF8String] , -1, &selectStmt, nil) == SQLITE_OK) { 
      int n=0; 
      while (sqlite3_step(selectStmt) == SQLITE_ROW) { 
       //do something 
      } 
     } 
     else { 
      NSLog(@"Error while creating select statement: '%s'", sqlite3_errmsg(bookLoansDB)); 
     } 
    } 
    else { 
     NSLog(@"Error while attaching databases: '%s'", errorMessage); 
    } 
} 
else { 
    NSLog(@"Failed to open database at %@ with error %s", booksDBPath, sqlite3_errmsg(bookLoansDB)); 
    sqlite3_close(bookLoansDB); 
} 
Cuestiones relacionadas