2013-10-29 70 views
1

我正在寫一個簡單的導航視圖iPhone程序使用SQLite的學習目的。我以前在數據庫中有一個表,但現在已經將它更新爲兩個,並且我的INNER JOIN語句崩潰了。 SQL語句似乎很好地直接運行它。在下面的代碼中,未註釋的語句工作得很好,但是如果我將它們切換出來,則註釋掉的語句將會出錯。JOIN不工作在SQLite查詢編譯

static sqlite3_stmt *init_statement = nil; 
static sqlite3_stmt *dehydrate_statment = nil; 

@implementation ICD9 
@synthesize primaryKey,text,priority,status,match; 

- (id)initWithPrimaryKey:(NSInteger)pk database:(sqlite3 *)db { 

    if (self = [super init]) { 
     primaryKey = pk; 
     database = db; 
     if (init_statement == nil) { 
      const char *sql = "SELECT text,priority,complete FROM todo WHERE pk=?"; 
     //const char *sql = "SELECT todo.*, match.code10 FROM todo INNER JOIN match ON match.text = todo.text WHERE pk=1;"; 
     if (sqlite3_prepare_v2(database, sql, -1, &init_statement, NULL) != SQLITE_OK) { 
       NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database)); 
     } 
    } 
    return self; 
} 

的表是在同一個數據庫:

CREATE TABLE todo(pk INTEGER PRIMARY KEY, text VARCHAR(25), priority INTEGER, complete BOOLEAN); 
CREATE TABLE match(matchid INTEGER PRIMARY KEY, text VARCHAR(25), name VARCHAR(25)); 

我很新的這所以任何幫助,將不勝感激。

+0

請格式化問題。 –

+0

'SELECT todo。,'無效! –

+0

我認爲'SELECT todo。*'是正確的,問題出現在'pk =?'中,沒有傳遞參數值。 –

回答

0

關鍵是要檢查由sqlite3_errmsg返回的錯誤消息。您報告您的NSAssert行報告消息:

failed to prepare statement with message 'no such table: match'

這意味着,你已經打開的數據庫沒有一個match表。如果你已經在模擬器上運行了這個工具,最簡單的方法就是在你選擇的MacOS SQLite工具中打開數據庫(我使用Base,你可以使用sqlite3命令行工具;使用你想要的任何東西)。該數據庫可以在您的~/Library/Application Support/iPhone Simulator文件夾中找到。爲了更容易找到這個數據庫,您可能需要啓動Terminal應用程序,然後運行命令chflags nohidden ~/Library/來取消隱藏您的~/Library文件夾。

無論如何,我認爲你會發現match表不存在(也許整個數據庫將是空白的)。一個常見的原因是在不存在的數據庫上調用sqlite_open,在這種情況下,它會爲您創建一個空白數據庫。

如果是這樣的話,你要

  • 刪除你可能在你的文檔文件夾中(這樣做是從你的設備/模擬器刪除的應用程序最簡單的方式)的任何空白數據庫和再次運行;和

  • 檢查數據庫開放的邏輯,這可能應該是這個樣子:

    NSString *filename = @"yourdb.sqlite"; 
    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    NSString *bundlePath = [[NSBundle mainBundle] pathForResource:[filename stringByDeletingPathExtension] ofType:[filename pathExtension]]; 
    NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; 
    NSString *path = [documentsPath stringByAppendingPathComponent:filename]; 
    
    if (![fileManager fileExistsAtPath:path isDirectory:NO]) 
    { 
        NSError *error = nil; 
        [fileManager copyItemAtPath:bundlePath toPath:path error:&error]; 
        NSAssert(error == nil, @"Unable to copy %@ to %@", bundlePath, path); 
    } 
    

    顯然,這種假設你有一個數據庫,準備好你的包使用。如果你是以編程方式創建它,那麼只需在if塊中執行該操作,並確定它不是fileExistsAtPath

+0

這就是發生了什麼事。謝謝你,羅伯! – AaronB