2010-11-18 117 views
5

我需要讀取和寫入BLOB數據到數據庫。這裏是我的結構表sqlite3插入並讀取數據庫中的BLOB數據

#define CREATE_TABLE_USERS_SQL "CREATE TABLE IF NOT EXISTS %@ (\ 
UserID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, \ 
Name VARCHAR(50), \ 
Image BLOB);" 

如何將它插入數據庫,然後從中檢索?

環境:iPhone SDK 4.1 SQLite3數據庫。

此代碼失敗:

 NSData * buf2 = [[NSData alloc] init]; 
     sqlite3_column_blob(statement, 5); 
     buf2 = sqlite3_column_bytes(statement, 5); 
     user.image = [UIImage imageWithData: buf2]; 
+0

此問題與您的要求相同,並且其中的答案應該解決您的需求:http://stackoverflow.com/questions/643682/reading-and-writing-images-to-an-sqlite-db- for iphone- – 2010-11-18 22:06:07

回答

1

除了選擇您的客戶端或編程接口,使用不從任何其他字符串字段不同。


[更新]我還沒有開發iPhone的運氣,但我相信它和任何其他SELECT或INSERT查詢一樣。確保對BLOB進行編碼並用字符串單撇號(')將其括起來。

+0

我添加了一個問題 – yozhik 2010-11-18 14:06:05

10

Thanx all!隨着你的幫助我心中已經解決的問題,並希望像我分享對未來初學者結果。)

-(void) addToDB 
{ 
    NSLog(@"\nCreating db"); 
    NSString *str = @"CREATE TABLE IF NOT EXISTS Images (image1 BLOB);"; 
    int res = SQLITE_ERROR; 


    res = sqlite3_open([@"aa.sql" UTF8String], &database); 
    res = sqlite3_exec(database, [str UTF8String], NULL, NULL, NULL); 

    sqlite3_stmt *updStmt =nil; 

    const char *sql = "INSERT INTO Images (image1) VALUES (?);"; 
    res = sqlite3_prepare_v2(database, sql, -1, &updStmt, NULL); 

    if(res!= SQLITE_OK) 
    { 
     NSLog(@"Error while creating update statement:%s", sqlite3_errmsg(database)); 
    } 

    UIImage *img = [UIImage imageNamed: @"flower.png"]; 
    NSData *imageData = [NSData dataWithData: UIImagePNGRepresentation(img)]; 

    res = sqlite3_bind_blob(updStmt, 1, [imageData bytes], [imageData length] , SQLITE_TRANSIENT); 

    if((res = sqlite3_step(updStmt)) != SQLITE_DONE) 
    { 
     NSLog(@"Error while updating: %@", sqlite3_errmsg(database)); 
     sqlite3_reset(updStmt); 
    } 

    res = sqlite3_reset(updStmt); 
    res = sqlite3_close(database); 
} 

-(void) readFromDB 
{ 
    NSLog(@"\nReading from db"); 

    NSString *query = @"SELECT image1 from Images"; 
    int res = SQLITE_ERROR; 
    int len = 0; 

    res = sqlite3_open([@"aa.sql" UTF8String], &database); 

    sqlite3_stmt *statement; 
    res = sqlite3_prepare_v2 (database, [query UTF8String], -1, &statement, nil); 

    if (res == SQLITE_OK) 
    { 
     if (sqlite3_step(statement) == SQLITE_ROW) 
     { 
      len = sqlite3_column_bytes(statement, 0); 
      NSData *imgData = [[NSData alloc] initWithBytes: sqlite3_column_blob(statement, 0) length: len];   


      UIImage *img = [[UIImage alloc] initWithData:imgData]; 

      self.view1.image = img; 

     } 
    } 
    sqlite3_finalize(statement); 

    res = sqlite3_close(database); 
} 
+0

感謝張貼,這段代碼很好。但是當我從「flower.png」更改圖像的名稱爲「xyz.png」之類的其他圖像時,它會顯示上一張圖像在imageview中,你可以指出原因....... – 2011-09-30 10:58:40

+0

maby你需要先到數據庫中的相應記錄,然後才從它讀取圖像,現在它總是需要第一個記錄。試試看,我真的不記得是在一年前。 NSLog中的 – yozhik 2011-09-30 12:20:40

+0

(@「創建更新語句時出錯:%@」,sqlite3_errmsg(database));應使用%s格式化 – 2013-01-29 19:05:11

0

// -----插入圖片

- (void)setImage:(UIImage *)theImage 
{ 

    if(sqlite3_open([databasePath UTF8String],&myDatabase)==SQLITE_OK) 
    {  
    NSString *insertProgrammeSql = @"INSERT INTO imageTable (imageName) VALUES (?)"; 

sqlite3_stmt *statement; 

    if (sqlite3_prepare_v2(myDatabase, [insertProgrammeSql cStringUsingEncoding:NSUTF8StringEncoding], -1, &statement, NULL) == SQLITE_OK) { 

    NSData *imageData = UIImagePNGRepresentation(theImage); 

     sqlite3_bind_blob(statement, 1, [imageData bytes], [imageData length], SQLITE_TRANSIENT); 

    sqlite3_step(statement); 
} 
    sqlite3_close(myDatabase); 
// return YES;  
} 


    } 

// ---- ----獲取圖像

-(UIImage *)getImage 

    { 

    UIImage *image = nil; 


if(sqlite3_open([databasePath UTF8String],&myDatabase)==SQLITE_OK) 
{ 

NSString *selectSql = @"SELECT image FROM imageTable"; 

sqlite3_stmt *statement; 
if (sqlite3_prepare_v2(myDatabase, [selectSql UTF8String], -1, &statement, NULL) == SQLITE_OK) 
{ 
    int length = sqlite3_column_bytes(statement, 0); 
    NSData *imageData = [NSData dataWithBytes:sqlite3_column_blob(statement, 0) length:length]; 

    image = [UIImage imageWithData:imageData]; 



    sqlite3_finalize(statement); 

    } 
    sqlite3_close(myDatabase); 
    } 
return image; 
} 
0

此代碼失敗:

NSData * buf2 = [[NSData alloc] init]; 
    sqlite3_column_blob(statement, 5); 
    buf2 = sqlite3_column_bytes(statement, 5); 
    user.image = [UIImage imageWithData: buf2]; 

您正在以正確的順序調用SQLite函數。據SQLite的文檔:

最安全,最容易記住的政策是通過以下方式之一來調用這些例程 :),其次是sqlite3_column_bytes()

  • sqlite3_column_text(
  • sqlite3_column_blob (),隨後接着sqlite3_column_bytes16 sqlite3_column_bytes()
  • sqlite3_column_text16()()

換句話說,你應該首先調用sqlite3_column_text(), sqlite3_column_blob(),或sqlite3_column_text16()到 結果迫使所需的格式,然後調用sqlite3_column_bytes()或 sqlite3_column_bytes16()來查找結果的大小。不要將 調用與調用 sqlite3_column_bytes16()的調用混合使用sqlite3_column_text()或sqlite3_column_blob(),並且不要將調用與 sqlite3_column_text16()調用混合並調用sqlite3_column_bytes()。

但是,buff2是一個整數,而不是數據指針。 sqlite3_column_bytes告訴你blob中有多少個字節。