2010-11-18 10 views
5

Tôi cần đọc và ghi dữ liệu BLOB vào cơ sở dữ liệu. Đây là bảng cấu trúc của tôisqlite3 chèn và đọc dữ liệu BLOB trong cơ sở dữ liệu

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

Làm cách nào để chèn nó vào cơ sở dữ liệu và sau đó lấy nó?

Môi trường: iPhone SDK 4.1 Cơ sở dữ liệu SQLite3.

Mã này thất bại:

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

Câu hỏi này yêu cầu điều tương tự như của bạn và câu trả lời sẽ giải quyết nhu cầu của bạn: http://stackoverflow.com/questions/643682/reading-and-writing-images-to-an-sqlite-db- for-iphone-use –

Trả lời

1

Ngoài việc lựa chọn khách hàng của bạn hoặc giao diện lập trình, sử dụng không khác với bất kỳ lĩnh vực chuỗi khác.


[Cập nhật] Tôi không có may mắn để phát triển cho iPhone, nhưng tôi tin nó giống như bất kỳ truy vấn SELECT hoặc INSERT nào khác. Đảm bảo mã hóa BLOB và đính kèm nó với các dấu nháy đơn (') như chuỗi.

+0

Tôi đã thêm một câu hỏi – yozhik

0

tại sao không sử dụng fmdb bởi Gus Mueller et al, của Flying Meat? http://flyingmeat.com/

https://github.com/ccgus/fmdb

Nếu bạn tìm thấy fmdb hữu ích, đi và mua một trong những ứng dụng Excellents of Flying thịt. VoodooPad hoặc Acron.

10

Thanx tất cả !! Với bạn giúp I'v giải quyết vấn đề và muốn chia sẻ kết quả cho người mới bắt đầu tương lai như tôi.)

-(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

cảm ơn bạn đã đăng bài, mã này hoạt động tốt. nhưng khi tôi thay đổi tên của hình ảnh từ "flower.png" thành một số khác như "xyz.png" thì nó sẽ hiển thị hình ảnh trước đó trong imageview để bạn có thể chỉ ra lý do ....... –

+0

maby bạn cần phải đi đến hồ sơ thích hợp trong cơ sở dữ liệu đầu tiên, và chỉ sau đó đọc hình ảnh từ nó, và bây giờ nó luôn luôn có kỷ lục đầu tiên. hãy thử điều đó, tôi thực sự không nhớ đó là một năm trước. – yozhik

+0

trong NSLog (@ "Lỗi khi tạo báo cáo cập nhật:% @", sqlite3_errmsg (cơ sở dữ liệu)); Định dạng% s nên được sử dụng –

0

// ----- chèn IMAGE

- (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;  
} 


    } 

// ---- ---- get ảnh

-(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

mã này thất bại:

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

Bạn đang gọi các hàm SQLite theo đúng thứ tự. Theo các tài liệu SQLite:

an toàn nhất và dễ nhất để nhớ chính sách là để gọi những thói quen theo một trong các cách sau:

  • sqlite3_column_text() tiếp theo là sqlite3_column_bytes()
  • sqlite3_column_blob() theo sau bởi sqlite3_column_bytes()
  • sqlite3_column_text16() theo sau là sqlite3_column_bytes16()

Nói cách khác, bạn nên gọi sqlite3_column_text(), sqlite3_column_blob(), hoặc sqlite3_column_text16() đầu tiên để buộc các kết quả vào định dạng mong muốn, sau đó gọi sqlite3_column_bytes() hoặc sqlite3_column_bytes16() để tìm ra kích thước của kết quả .Không kết hợp các cuộc gọi tới sốtới sqlite3_column_text() hoặc sqlite3_column_blob() với các cuộc gọi tới sqlite3_column_bytes16() và không được kết hợp các cuộc gọi đến sqlite3_column_text16() với các cuộc gọi đến sqlite3_column_bytes().

Tuy nhiên, buff2 là số nguyên chứ không phải con trỏ dữ liệu. sqlite3_column_bytes cho bạn biết số lượng byte trong blob.