2016-01-20 78 views
1

我已經嘗試了一個準備好的語句和一個常規語句,使用一個長的iPhone模擬器路徑從我的表中檢索記錄。在iPhone上包含路徑失敗的SQLite查詢

我根本無法讓SELECT語句在WHERE語句中使用字段Path。如果我刪除WHERE語句,它將返回記錄。

例如

Last Added[/Users/admin/Library/Developer/CoreSimulator/Devices/1546523B-D9E4-45F6-9ACA-ADA5CF73DFE4/data/Containers/Data/Application/9187662E-16F3-4573-B486-256BDA00CBD1/Documents/wf_mages-3.lha] 

SQL[SELECT ID FROM Tune WHERE Path="/Users/admin/Library/Developer/CoreSimulator/Devices/1546523B-D9E4-45F6-9ACA-ADA5CF73DFE4/data/Containers/Data/Application/9187662E-16F3-4573-B486-256BDA00CBD1/Documents/wf_mages-3.lha"] 

我在查詢中試過雙引號和單引號。我甚至在SQLiteBrowser中嘗試了相同的查詢,它工作正常。

SELECT ID FROM Tune WHERE Path LIKE'%mages%'works fine。

正斜槓或路徑值的大小有問題嗎?是否需要以某種方式逃避正斜槓?

我能找到關於正斜槓的唯一其他帖子推薦使用準備好的語句,但這是我最初開始的,他們不會工作。查找在我的表格中的其他字段上工作正常 - 只是沒有路徑。

int GetTuneIDWithPath(char *pszPath) 
{ 
    // TEST 
    char txTmp [ 1024 ]; 

    sprintf(g_txSQL, "SELECT %s", fldTune_ID); 

    sprintf(txTmp, " FROM %s ", tbTune); 
    strcat(g_txSQL, txTmp); 

    //sprintf(txTmp, " WHERE %s=\"%s\"", fldTune_Path, pszPath); 
    //strcat(g_txSQL, txTmp); 

// sprintf(txTmp, " WHERE %s='%s'", fldTune_Path, pszPath); 
    //strcat(g_txSQL, txTmp); 

    //sprintf(txTmp, " WHERE %s LIKE '%%mages%%'", fldTune_Path); 
    //strcat(g_txSQL, txTmp); 

    LogDebugf("SQL[%s]", g_txSQL); 

    char *zErrMsg = 0; 
    char **pszResult; 
    int nRows; 
    int nCols; 
    int rc; 

    rc = sqlite3_get_table_wrapper(g_MainDB, 
           g_txSQL, 
           &pszResult, 
           &nRows, 
           &nCols, 
           &zErrMsg); 

    if(nRows != 1) 
    { 
    LogDebugf("FAILED nRows: %d", nRows); 
    return FALSE; 
    } 

    // First row is field names, so start at 1 
    int nCol = 0; 
    int nID = Safe_atoi( pszResult[ nCols + nCol ]); nCol ++; 

    LogDebugf("PDS> nID: %d Find[%s]", nID, pszPath); 
    return nID; 
} 

在此之前,我曾嘗試使用預處理語句就像我的其他查詢做到:

char txTmp [ 1024 ]; 

    sprintf(g_txSQL, "SELECT %s", fldTune_ID);  
    sprintf(txTmp, " FROM %s WHERE %s=?", tbTune, fldTune_Path); 
    strcat(g_txSQL, txTmp); 

    sqlite3_stmt *stmt = NULL; 
    sqlite3_prepare(g_MainDB, g_txSQL, -1, &stmt, NULL); 
    sqlite3_reset(stmt); 
    sqlite3_bind_text(stmt, 1, pszPath, strlen(pszPath), SQLITE_STATIC); 

    rc = sqlite3_step(stmt); 

    if(rc != SQLITE_ROW) 
    { 
    LogDebugf("PDS> Lookup failed [%s] rc: %d", pszPath, rc); 
    return FALSE; 
    } 

    int nID = sqlite3_column_int(stmt, 0); 

    LogDebugf("PDS> nID: %d Find[%s]", nID, pszPath); 
+0

顯示您的代碼。 –

+0

@CL - 添加了一些代碼。 – SparkyNZ

回答

2

您需要忽略該文件,並只記錄的實際位置和內搜索文件應用程序文檔目錄,因此您需要存儲/搜索'wf_mages-3.lha'而不是'/Users/admin/Library/Developer/CoreSimulator/Devices/1546523B-D9E4-45F6-9ACA-ADA5CF73DFE4/data/Containers/Data/Application/9187662E-16F3-4573-B486-256BDA00CBD1/Documents/wf_mages-3.lha'

只有在實際讀取/寫入文件時,您需要預先安裝文件路徑,您可以通過NSSearchPathForDirectoriesInDomains()獲取文件路徑。

原因是在應用程序更新期間位置會發生變化,文檔目錄內容將被遷移,但數據庫行不會,並且您將失去兩者之間的連接。

在語句中使用'/'不應該存在任何問題,因爲就SQL而言它不是特別的,所以應該可以在文檔文件夾中創建層次結構而沒有問題。

要在你的代碼註釋,我以前從來沒見過使用的方法,我會主張更傳統的sqlite3_prepare()sqlite3_step()sqlite3_finalize()功能。另外,最重要的是,您需要使用sqlite3_errmsg()報告任何錯誤,否則您將無法取得進展。

+0

謝謝 - 使用文檔目錄的好處。我意識到我不需要存儲所有的東西,但爲了測試這個功能,它仍然不能解釋爲什麼我可以存儲一個很長的路徑,但不能在長路徑名稱上做SELECT。我還應該指出,我正在寫入表格,然後立即選擇 - 在這兩個操作之間不重新啓動應用程序或模擬器。這只是增加了一個查詢到我的應用程序 - 它總共有大約50個查詢,比這更復雜的方式,他們都工作。這裏錯過了一些愚蠢的東西。 – SparkyNZ

+0

@SparkyNZ我會從更傳統的功能開始,並從那裏開始。 – trojanfoe