2016-03-23 14 views
0

Bir görüntüyü sqlite'e kaydetmeye çalıştığımda, bu görüntüyü NSData'ya dönüştürdüm ve 2.000.000 bayttan fazla var. imageData.Bir görüntüyü sqlite'e depolamaya çalıştım ve onu almaya çalıştığımda 2 milyon bayt yerine bir baytlık

Bunu sqlite veritabanından almayı denediğimde, BIR bayt oldu. sqlite içine

Görsel ekle:

İşte benim kod

-(void)INSERTCLAIMATTACHMENT:(NSString *)tablename 
        PARENTID:(long long)parentid 
      ATTACHMENTCONTENT:(UIImage *)attachmentimage 
       ATTACHMENTNAME:(NSString *)attachmentname 
{ 
    sqlite3_stmt *statement; 
    const char *dbPath = [_databasePath UTF8String]; 

    Global * g = [[Global alloc]init]; 
    NSData *imageData = [[NSData alloc]init]; 
    imageData = UIImagePNGRepresentation(attachmentimage); 

    if(sqlite3_open(dbPath, &_DB) == SQLITE_OK) 
    { 
     NSString *insertSQL = [NSString stringWithFormat:@"INSERT INTO CLAIM_ATTACHMENT_ITEM ('PARENT_ID', 'CLAIM_ATTACHMENT_CONTENT', 'CLAIM_ATTACHMENT_NAME', 'CLAIM_ATTACHMENT_SIZE') VALUES ('%lld', '?', '%@', '%lu')", parentid,attachmentname, [imageData length]]; 
     const char *insert_statement = [insertSQL UTF8String]; 

     if(sqlite3_prepare_v2(_DB,insert_statement, -1, &statement, NULL) == SQLITE_OK) 
      { 
       sqlite3_bind_blob(statement, 2, [imageData bytes], [imageData length], SQLITE_TRANSIENT); 
       if(sqlite3_step(statement) == SQLITE_DONE) 
       { 
        [g showCustomAlertView:@"Successfull" message:@"Attachment has been added into database."]; 
       } 
       else{ 
        [g showCustomAlertView:@"Failure" message:[NSString stringWithFormat:@"%s", sqlite3_errmsg(_DB)]]; 
       } 

      } 
     else{ 
      [g showCustomAlertView:@"Failure" message:[NSString stringWithFormat:@"%s", sqlite3_errmsg(_DB)]]; 
     } 

    } 
    else{ 
     [g showCustomAlertView:@"Failure" message:[NSString stringWithFormat:@"%s", sqlite3_errmsg(_DB)]]; 
    } 
    sqlite3_close(_DB); 
} 

olur ne sqlite

-(NSMutableArray *)SELECTATTACHMENTFROMCLAIMATTACHMENTITEM:(long long)rowID 
{ 
    sqlite3_stmt *statement; 
    const char *dbPath = [_databasePath UTF8String]; 

    Global * g = [[Global alloc]init]; 

    NSMutableArray *attachmentArray = [[NSMutableArray alloc]init]; 

    if(sqlite3_open(dbPath, &_DB) == SQLITE_OK) 
    { 
     NSString *querySQL = [NSString stringWithFormat:@"SELECT * FROM CLAIM_ATTACHMENT_ITEM WHERE PARENT_ID = '%lld'", rowID]; 
     const char *query_Statement = [querySQL UTF8String]; 

     if(sqlite3_prepare_v2(_DB, query_Statement, -1, &statement, NULL) == SQLITE_OK) 
     { 
      while(sqlite3_step(statement) == SQLITE_ROW) 
      { 
       AttachmentItem * attachment = [[AttachmentItem alloc]init]; 
       NSData *attachmentImageData = [[NSData alloc]initWithBytes:sqlite3_column_blob(statement, 2) length:sqlite3_column_bytes(statement, 2)]; 

       UIImage *attachmentImage = [UIImage imageWithData:attachmentImageData]; 

       NSString *attachmentName = [[NSString alloc]initWithUTF8String:sqlite3_column_text(statement, 3)]; 
       attachment.attachmentImage = attachmentImage; 
       attachment.attachmentName = attachmentName; 
       [attachmentArray addObject:attachment]; 
      } 
     } 
     else 
     { 
      [g showCustomAlertView:@"Failure" message:[NSString stringWithFormat:@"%s", sqlite3_errmsg(_DB)]]; 
     } 
    } 
    else 
    { 
     [g showCustomAlertView:@"Failure" message:[NSString stringWithFormat: @"%s",sqlite3_errmsg(_DB)]]; 
    } 


    sqlite3_close(_DB); 

    return attachmentArray; 

} 

görüntüyü alınsın mı? görüntü verileri benim için tek bayt içine oturtma Neden :( ben damla belki verilerin bu boyutu depolamak olamayacağını tahmin ediyorum?

+0

1 olmalıdır böylece bu açıklama, sadece tek bir SQL parametresi vardır - Muhtemelen kötü bir fikir görüntüleri veritabanında saklamak için. Onları dosya sistemine yazmalı ve dosya adını veritabanına kaydetmelisiniz. Bkz. Http://stackoverflow.com/questions/12346879/store-images-in-sqlite-or-just-a-reference-to-it – rmaddy

+0

Diğer bir şey. SELECT * FROM ... kullanımından kaçının. '*' Yerine sütun adlarını açık bir şekilde listeleyin. Kodunuzu daha kolay okunur hale getirir ve daha sonra şemayı değiştirirseniz ve sütun düzeni beklediğiniz gibi değilse, garip hatalardan kaçınır. – rmaddy

+0

Tamam, ipuçları için teşekkürler! –

cevap

2

sqlite_bind_blob için Çağrı yanlış alan indeksi geçiyor. Sadece bir tane ? var endeks böylece INSERT açıklamada, 1 olmalıdır değil 2

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

Ayrıca, INSERT açıklamada ? tırnak kaldırmak gerekir.

NSString *insertSQL = [NSString stringWithFormat:@"INSERT INTO CLAIM_ATTACHMENT_ITEM ('PARENT_ID', 'CLAIM_ATTACHMENT_CONTENT', 'CLAIM_ATTACHMENT_NAME', 'CLAIM_ATTACHMENT_SIZE') VALUES ('%lld', ?, '%@', '%lu')", parentid,attachmentname, [imageData length]]; 

stringWithFormat: kullanarak bir sorgu oluşturmak yerine ? uygun sqlite3_bind_xxx deyimiyle birlikte kullanılmasının temel nedeni, değerlerin düzgün bir şekilde alıntılanması ve sizin için kaçmasıdır.

+0

Anladım ... böylece parametre '?' string formatı belirteci yerine? –

+0

'sqlite3_bind_xxx' işlevleri, Objective-C'den hiçbir şey bilmez ve kesinlikle NSString formatı belirleyicilerinden hiçbir şey bilmez. – rmaddy

+0

Pekala efendim, sizden ve kabul etmeyi hakediyorsunuz, teşekkürler –

1
VALUES ('%lld', '?', '%@', '%lu') 

% değiştirmeler metinsel fakat ? SQL motoru tarafından işlenen ve bu bir deyim olduğu parametre işaretleyici göründüğünde yalnızca çalışır.

Alıntılar ile '?' yalnızca ? tek karakterini içeren bir dizedir.

tırnak işareti olmaksızın parametreyi yazmak zorunda:

[NSString stringWithFormat:@"INSERT ... VALUES ('%lld', ?, '%@', '%lu')", ...]; 

Ve endeksi değil, Bilginize 2.

+0

Oh tanrım, tam olarak neyin yanlış olduğunu gördüm. Çok teşekkür ederim! –

İlgili konular