2013-06-21 38 views

回答

2

您可以將sqlite3_create_function創建soundex SQL函數:

#import "ViewController.h" 
#import <sqlite3.h> 

void soundex(sqlite3_context *context, int argc, sqlite3_value **argv); 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    [self test]; 
} 

- (sqlite3 *)openDatabase 
{ 
    NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; 
    NSString *path = [docsPath stringByAppendingPathComponent:@"test.db"]; 
    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    if (![fileManager fileExistsAtPath:path]) 
    { 
     NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"db"]; 
     [fileManager copyItemAtPath:bundlePath toPath:path error:nil]; 
    } 

    sqlite3 *db; 
    int rc; 

    if ((rc = sqlite3_open_v2([path UTF8String], &db, SQLITE_OPEN_READWRITE, NULL)) != SQLITE_OK) 
    { 
     NSLog(@"%s: sqlite3_open_v2 failed: %d", __FUNCTION__, rc); 
    } 

    return db; 
} 

- (BOOL)createFunction:(sqlite3 *)db 
{ 
    int rc; 
    if ((rc = sqlite3_create_function(db, "soundex", 1, SQLITE_ANY, NULL, soundex, NULL, NULL)) != SQLITE_OK) 
    { 
     NSLog(@"%s: sqlite3_create_function error: %s", __FUNCTION__, sqlite3_errmsg(db)); 
    } 

    return rc; 
} 

- (void)test 
{ 
    int rc; 
    sqlite3 *db = [self openDatabase]; 

    [self createFunction:db]; 

    sqlite3_stmt *statement; 

    if (sqlite3_prepare_v2(db, "SELECT name FROM todo WHERE soundex(name) = soundex('Mani')", -1, &statement, NULL) != SQLITE_OK) 
    { 
     NSLog(@"%s: sqlite3_prepare_v2 error: %s", __FUNCTION__, sqlite3_errmsg(db)); 
    } 

    while ((rc = sqlite3_step(statement)) == SQLITE_ROW) 
    { 
     const unsigned char *name = sqlite3_column_text(statement, 0); 
     if (name) 
      NSLog(@"name=%s", name); 
     else 
      NSLog(@"name=NULL"); 
    } 

    if (rc != SQLITE_DONE) 
    { 
     NSLog(@"%s: sqlite3_step error: %s", __FUNCTION__, sqlite3_errmsg(db)); 
    } 

    sqlite3_finalize(statement); 
    sqlite3_close(db); 
} 

@end 

void soundex(sqlite3_context *context, int argc, sqlite3_value **argv) 
{ 
    const char *str = (const char*)sqlite3_value_text(argv[0]); 
    const char *in = str; 

    static int code[] = 
    { 0,1,2,3,0,1,2,0,0,2,2,4,5,5,0,1,2,6,2,3,0,1,0,2,0,2 }; 
    /* a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z */ 

    char ch; 
    int last; 
    int count; 

    char key[5]; 
    /* Set up default key, complete with trailing '0's */ 
    strcpy(key, "Z000"); 

    /* Advance to the first letter. If none present, 
    return default key */ 
    while (*in != '\0' && !isalpha(*in)) 
     ++in; 
    if (*in == '\0') { 
     sqlite3_result_text(context, key, 4, SQLITE_TRANSIENT); 
     return; 
    } 

    /* Pull out the first letter, uppercase it, and 
    set up for main loop */ 
    key[0] = toupper(*in); 
    last = code[key[0] - 'A']; 
    ++in; 

    /* Scan rest of string, stop at end of string or 
    when the key is full */ 
    for (count = 1; count < 4 && *in != '\0'; ++in) { 
     /* If non-alpha, ignore the character altogether */ 
     if (isalpha(*in)) { 
      ch = tolower(*in); 
      /* Fold together adjacent letters sharing the same code */ 
      if (last != code[ch - 'a']) { 
       last = code[ch - 'a']; 
       /* Ignore code==0 letters except as separators */ 
       if (last != 0) 
        key[count++] = '0' + last; 
      } 
     } 
    } 

    sqlite3_result_text(context, key, 4, SQLITE_TRANSIENT); 
} 
+0

將試試這個,讓你知道...感謝您的回答... – Arvind

+1

嘿羅布,這工作正常...很好的幫助!謝謝 – Arvind

0

您需要包括來自sqlite amalgamation本身sqlite.c/sqlite.h在您的項目文件與使用libsqlite dylib。

確保設置SQLITE_SOUNDEX預處理器標誌以及在構建時包含此功能。 1)下載並解壓縮文件sqlite amalgamation。將sqlite.h/sqlite.c文件添加到您的項目中。

2)通過XCode中的Build Settings屏幕,將SQLITE_SOUNDEX = 1添加到項目的預處理器宏中。

3)通過Xcode中的Build Phases屏幕從項目的Link With Libraries列表中刪除libsqlite3XXX.dylib。

+0

你好Tom,你能告訴我詳細的步驟來實現這一目標。感謝您的回答。 – Arvind

+0

嘿湯姆我試過你的步驟,但得到「_sqlite3_bind_int」,引用:錯誤....任何幫助? – Arvind