iphone
  • objective-c
  • ios
  • 2013-01-02 64 views -2 likes 
    -2

    我想實現一個查詢和一個動態查詢。 有4個表格,通過它我使用group by子句過濾表格。 但現在我想結合這四個表,並進行動態查詢。 關於選擇值T將是如下面例如 例如:如何在iphone中實現動態查詢sdk

    NSString *strQuery = @"Select * from TableName where " 
    

    步驟:1:

    使用實體的查詢將是:

    Select * from TableName where entity1 = 'S' 
    

    步驟:2

    實體2的查詢將是:

    Select * from TableName where entity1 = 'S' AND entity 2 = '100S' 
    

    步:3

    實體3的查詢將是:

    Select * from TableName where entity1 = 'S' AND entity 2 = '100S' AND entity3 = 'Fly' 
    
    +0

    什麼是實體1,2和3的含義? –

    +0

    當我選擇表中的值並執行動態查詢時,我必須追加字符串。你記得概率嗎? – Roma

    +1

    你可以給我你的郵件ID – Roma

    回答

    0

    你可以用的NSString像 「stringWithFormat」 的方法試試,

    NSString *strQuery = [NSString stringWithFormat:@"Select * from TableName where entity1 = '%@' AND entity 2 = '%@'",@"S",@"100S"]; 
    

    希望它會對你有所幫助。

    乾杯!

    0

    對於靜態值,你可以嘗試

    NSString *strQuery [email protected]"Select * from TableName where entity1 = 'S' AND entity 2 = '100S'"; 
    

    動態值,你可以嘗試

    NSString *strQuery = [NSString stringWithFormat:@"Select * from TableName where entity1 = '%@' AND entity 2 = '%@'",entity1_obj,entity2_obj]; 
    
    1

    一對夫婦的想法:

    1. 這是最好的,如果列名沒有有他們的空間。如果您有空格,則需要將列名稱放在引號中,例如

      Select * from TableName where entity1 = 'S' AND 'entity 2' = '100S' 
      

      最好通過確保列名中沒有空格來完全繞過此問題,例如, entity2而不是entity 2

    2. 與其使用stringWithFormat構建SQL,在SQL中使用?佔位符並使用sqlite3_bind_text()來設置值更安全。這樣,如果變量具有可能會混淆手動創建的SQL語句的任何字符(例如該字段具有單引號字符'),則它會繞過該問題。所以,你可能有:

      sqlite3 *database; 
      if (sqlite3_open([databasePath UTF8String], &database) != SQLITE_OK) 
          NSLog(@"%s open error '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(database), sqlite3_errcode(database)); 
      
      NSString *sql = @"Select * from TableName where entity1 = ? AND entity2 = ?"; 
      NSString *entity1 = @"S"; 
      NSString *entity2 = @"100S"; 
      
      sqlite3_stmt *statement; 
      
      if (sqlite3_prepare_v2(database, [sql UTF8String], -1, &statement, NULL) != SQLITE_OK) 
          NSLog(@"%s prepare SQL error '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(database), sqlite3_errcode(database)); 
      
      if (sqlite3_bind_text(statement, 1, [entity1 UTF8String], -1, NULL) != SQLITE_OK) 
          NSLog(@"%s bind entity 1 error '%s'", __FUNCTION__, sqlite3_errmsg(database)); 
      
      if (sqlite3_bind_text(statement, 2, [entity2 UTF8String], -1, NULL) != SQLITE_OK) 
          NSLog(@"%s bind entity 2 error '%s'", __FUNCTION__, sqlite3_errmsg(database)); 
      
      int rc; 
      
      while ((rc = sqlite3_step(statement)) == SQLITE_ROW) 
      { 
          // do whatever you want with the results 
      
          const unsigned char *entity1 = sqlite3_column_text(statement, 0); 
          const unsigned char *entity2 = sqlite3_column_text(statement, 1); 
          const unsigned char *entity3 = sqlite3_column_text(statement, 2); 
      
          NSLog(@"%s %s %s", entity1, entity2, entity3); 
      } 
      
      if (rc != SQLITE_DONE) 
          NSLog(@"%s step SQL error '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(database), sqlite3_errcode(database)); 
      
      sqlite3_finalize(statement); 
      sqlite3_close(database); 
      

      誠然,這使用的是sqlite_bind_text多一點麻煩,但它更健壯。如果您不能完全確定您要查找的字段是否具有單引號字符,則使用此約定很重要。如果您正在根據用戶提供的某些搜索條件構建SQL(例如,找到「喬的酒吧和燒烤」,如果你不使用sqlite3_bind_text或其他代碼圍繞這個問題,「喬的」撇號可能會導致你有點心痛。雖然這不是一個應用程序比網站的問題,但你根本不想讓你的應用程序易受SQL injection影響。

    3. 如果使用FMDB,一個美妙的小的Objective-C包裝SQLite的上述sqlite_bind_text語法大大簡化:

      FMDatabase *database = [FMDatabase databaseWithPath:databasePath]; 
      NSAssert(database, @"unable to open database"); 
      
      if (![database open]) 
          NSLog(@"%@", [self.database lastErrorMessage]); 
      
      FMResultSet *rs = [database executeQuery:@"Select * from TableName where entity1 = ? AND entity2 = ?", @"S", @"100S"]; 
      NSAssert(rs, [self.database lastErrorMessage]); 
      
      while ([rs next]) 
      { 
          NSLog(@"%@ %@ %@", rs[0], rs[1], rs[2]); 
      } 
      
      [rs close]; 
      [database close]; 
      

      該享有的sqlite_bind_text好處,而拖你通過sqlite的雜草函數調用。


    如果你想有,你可以使用的可變參數數目調用一個函數,你能做到這一點一堆不同的方式,動態建立你的SQL。我將在下面提供一個免責聲明的例子,我真的不喜歡手動構建SQL,因爲代碼最終會遇到可讀性問題。我寧願犧牲更簡潔的代碼,但我從你的問題推斷出你想知道如何動態構建你的SQL,所以我會提供一個示例,並提供上述警告。我也會說有很多方法可以解決這個問題,這只是一個例子。

    無論如何,我們假設您想使用字典作爲哪些列具有哪些值的參數,您可以按如下方式調用它。如果你只有實體1,你會打電話,像這樣:

    [self selectTableWithDictionary:@{@"entity1":@"S"}]; 
    

    或者,如果你有兩個實體1和實體2,你會叫它像這樣:

    [self selectTableWithDictionary:@{@"entity1":@"S", @"entity2":@"100S"}]; 
    

    的方法以然後解析該字典,手動構建SQL,然後綁定各個列可能類似於:

    - (void)selectWithDictionary:(NSDictionary *)dictionary 
    { 
        NSArray *fieldNames = [dictionary allKeys]; 
        NSArray *values = [dictionary allValues]; 
    
        // build the sql 
    
        NSMutableString *sql = [NSMutableString stringWithString:@"Select * from TableName"]; 
        if ([fieldNames count]){ 
         [sql appendString:@" where "]; 
         [sql appendString:[fieldNames componentsJoinedByString:@" = ? AND "]]; 
         [sql appendString:@" = ?"]; 
        } 
    
        sqlite3_stmt *statement; 
    
        // prepare the sql 
    
        if (sqlite3_prepare_v2(database, [sql UTF8String], -1, &statement, NULL) != SQLITE_OK) 
         NSLog(@"%s prepare SQL error '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(database), sqlite3_errcode(database)); 
    
        // bind the values 
    
        for (NSInteger i = 0; i < [fieldNames count]; i++) 
         if (sqlite3_bind_text(statement, i+1, [values[i] UTF8String], -1, NULL) != SQLITE_OK) 
          NSLog(@"%s bind column # %d error '%s'", __FUNCTION__, i+1, sqlite3_errmsg(database)); 
    
        int rc; 
    
        // iterate through the results 
    
        while ((rc = sqlite3_step(statement)) == SQLITE_ROW) 
        { 
         const unsigned char *entity1 = sqlite3_column_text(statement, 0); 
         const unsigned char *entity2 = sqlite3_column_text(statement, 1); 
         const unsigned char *entity3 = sqlite3_column_text(statement, 2); 
    
         NSLog(@"%s %s %s", entity1, entity2, entity3); 
        } 
    
        if (rc != SQLITE_DONE) 
         NSLog(@"%s step SQL error '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(database), sqlite3_errcode(database)); 
    
        sqlite3_finalize(statement); 
    } 
    

    的FMDB實現可能看起來像:

    - (void)selectTableWithDictionary:(NSDictionary *)dictionary 
    { 
        NSArray *fieldNames = [dictionary allKeys]; 
        NSArray *values = [dictionary allValues]; 
    
        // build the sql 
    
        NSMutableString *sql = [NSMutableString stringWithString:@"Select * from TableName"]; 
        if ([fieldNames count]){ 
         [sql appendString:@" where "]; 
         [sql appendString:[fieldNames componentsJoinedByString:@" = ? AND "]]; 
         [sql appendString:@" = ?"]; 
        } 
    
        // execute the sql 
    
        FMResultSet *rs = [self.database executeQuery:sql 
              withArgumentsInArray:values]; 
        NSAssert(rs, [self.database lastErrorMessage]); 
    
        // iterate through the results 
    
        while ([rs next]) 
        { 
         NSLog(@"%@ %@ %@", rs[0], rs[1], rs[2]); 
        } 
    
        [rs close]; 
    } 
    
    相關問題