2010-03-16 4 views
3

NSPropertyListSerialization 또는 NSKeyedArchiver를 통해 먼저 NSData로 변환하여 NSMutableDictionaries를 sqlite에 blob로 저장하려고합니다.NSData가 sqlite 데이터베이스에 저장 될 때 잘리고 있습니다

BLOB를 저장할 때 NSData 객체의 길이는 수천 (KB 범위)입니다. 다시 가져올 때 10 바이트로 잘 렸습니다. SQLite Browser를 통해 DB를 검사하면 대부분의 데이터가 사라집니다 (사전을 NSPropertyListSerialization로 저장하면 사전의 값이 사라짐). 이것은 NSPropertyListSerialization 또는 NSKeyedArchiver를 사용하여 내 데이터를 직렬화하는지 여부에 관계없이 발생합니다.

NSMutableDictionary* item = [items objectAtIndex:i]; 
NSData *dictionary = [NSKeyedArchiver archivedDataWithRootObject:item]; 
sqlite3_bind_blob( compiledStatement, 5, [dictionary bytes], [dictionary length], SQLITE_TRANSIENT); 

이것은 실제로 내 코드에서 발췌 한 것으로 전체 섹션은 다른 관련 질문에 게시했습니다.

Bulk inserts into sqlite db on the iphone

값을 점검 [사전 길이] GDB를 사용하거나 NSLog이 동일한 결과를 산출 : 데이터 길이가 KB의 범위이다. 내가 나중에 데이터를 검색 확인할 때

는 :

NSData* raw = [[NSData alloc] initWithBytes:sqlite3_column_blob(compiledStatement, 1) length:sqlite3_column_bytes(compiledStatement, 1)]; 
[raw release]; 

확인 [원시 길이] 나에게 단순한 10 바이트를 제공합니다. 이것은이 열에 저장하려고 시도한 모든 데이터 인스턴스에 해당합니다. 시작 크기에 관계없이 결국 10 바이트가됩니다. 검색 쿼리에 문제가 없습니다. 커맨드 라인과 SQL Browser에서 실행했고 정확한 레코드와 컬럼을 얻었지만,이 특정 컬럼에 대한 레코드에 저장된 데이터는 정확하지 않습니다.

나머지 데이터는 어떻게됩니까? 내가 sqlite3_bind_blob을 사용하는 방식에 문제가 있습니까? 문자 또는 최대 크기 제한을 종료하는 sqlite 설명서를 확인했습니다. 내 데이터는 BLOB 항목의 최대 크기 내에 잘 들어 있고, 데이터를 크기에 맞게 잘라낼 수있는 터미널에 대한 정보는 찾을 수 없습니다.

+1

BLOB의 기본 최대 크기와 조정 방법을 확인합니다. 그 또는 당신은 어딘가에 데이터를 버퍼링하고 첫 번째 청크 만 만들 수 있습니다. –

+0

문서의 '기본'최대 크기, AFAICT ... 최대 크기가 없습니다. 거대합니다. 내가 저장하려고하는 것보다 훨씬 더 큽니다. 바인드 호출 바로 전에 값을 확인 중이며 NSData의 인스턴스는 그 시점까지 유효하며 유효합니다. 바인드 호출 중에 매개 변수로 SQLITE_TRANSIENT를 전달하면 데이터를 복사하여 ... 나중에 손실되는 데이터가 문제가되지 않도록해야합니다. – akaii

+0

10 바이트 란 무엇입니까? 사실 그것은 사전 데이터의 절사입니까? – Chuck

답변

0

나는이 좋은 일에 자주 범인을 찾았습니다. 제 데이터가 들어있는 실제 열이었던 열 0 대신 열 1의 값을 사용하고있었습니다. 쿼리의 바인딩 값은 1 열에서 시작하기 때문에 쿼리 결과에서 열을 가져 오는 것이 1부터 시작될 것이라고 생각했습니다. 실수였습니다.

행당 10 바이트는 실제로 사전 데이터가 아니지만 결과를 정렬하는 데 사용한 타임 스탬프입니다.

2

해당 바인딩의 반환 유형을 확인 했습니까? 오류 코드를 반환 할 수도 있습니다 (명령문은이 이벤트에서 여전히 잘못 실행될 수 있음).

해결 방법으로 ZEROBLOB을 작성한 다음 SQLite documentation에 설명 된 BLOB I/O 루틴을 사용하여 쓰기를 시도 했습니까? 그것은 오류 코드를보고 나서 시도 할 다음 일 것입니다.

+0

SQLITE_OK를 반환합니다. 나는 blob I/O를 줄 것이다. 그러나 점진적으로 저장하지 않을 때, blob을 데이터베이스에 제출하는 것은 매우 믿을 수 없을 정도로 원형이다. – akaii

+0

또한이 방법을보다 철저하게 검사 한 후에 오버 헤드가 걱정됩니다. 먼저 레코드를 삽입 한 다음 나중에 blob 핸들을 가져 와서 업데이트해야합니까? 나는 그것이 존재하기도 전에 zeroblob에 쓸 수있는 것은 이치에 맞지 않는다고 생각하지만, 이것은 트랜잭션에 더 많은 시간이 걸릴 것이고, 나는 성능에 대해 심각하게 염려한다. – akaii

+0

제로 블록은 단지 자리 표시 자일뿐입니다. 실제 BLOB 데이터를 작성할 때까지는 공간 (또는 성능)을 차지하지 않습니다. 문제가되지 않는 한 성능에 대해 걱정하지 마십시오. –