2009-08-23 2 views
2

SQL 데이터베이스의 BLOB 필드에 저장해야하는 이진 데이터가 있습니다. UPDATE (데이터베이스에 저장)의 경우, 2 진 데이터는 문자열 (BDS2006, 유니 코드 없음)로 제공됩니다. BLOB 필드가 READ이면 이진 데이터를 문자열로 반환해야합니다. 코드의 따라서, 내가 사용했던이 두 개 (QRY이 TQuery입니다) :blob에 특정 데이터가 포함되어있는 경우 BLOB 업데이트 문제.

READ :

var s: string; 
begin 
    qry.SQL.Text := 'SELECT BlobField FROM Table WHERE ID=xxx'; 
    qry.Open; 
    if qry.RecordCount > 0 then 
    begin 
     qry.First; 
     s := qry.FieldByName('BlobField').AsString; 
    end; 
end; 

UPDATE : 그 오른쪽인지 잘 모르겠어요

var s: string; 
begin 
    s := ...binary data... 
    qry.SQL.Text := 'UPDATE Table Set BlobField=:blobparam WHERE ID=xxx'; 
    qry.ParamByName('blobparam').AsBlob = s; 
    qry.ExecSQL; 
end; 

/좋은/좋은 방법,하지만 그것을 잘 2 년 동안 일 해왔다.

특정 이진 데이터 집합에 문제가 있습니다. 데이터베이스에 UPDATE 된 후 데이터베이스에서 읽기가 변경/손상된 후 이진 데이터 집합에 문제가 있습니다. ExecSQL 이전의 param 값을 읽은 후 s 값과 비교하면 데이터의 마지막 바이트 (이 경우 총 1519 바이트)가 02h에서 00h로 변경됩니다.

내 코드가 제대로 작동하는지 확실하지 않으므로 TBlobStream을 사용하여 결과가 변경되는지 확인하려고했습니다.

READ :

var s: string; 
    bs: TStream; 
    st: TStringStream; 
begin 
    qry.SQL.Text := 'SELECT BlobField FROM Table WHERE ID=xxx'; 
    qry.Open; 
    if qry.RecordCount > 0 then 
    begin 
     qry.First; 
     st := TStringStream.Create(''); 
     bs := qry.CreateBlobStream(qry.FieldByName('BlobField'), bmRead); 
     bs.Position := 0; 
     st.CopyFrom(bs, bs.Size); 
     st.Position := 0; 
     s := st.ReadString(st.Size); 
    end; 
end; 

UPDATE :

var s: string; 
    bs: TStream; 
    st: TStringStream; 
begin 
    s := ...binary data... 
    st := TStringStream.Create(s); 
    st.Position := 0; 
    qry.SQL.Text := 'UPDATE Table Set BlobField=:blobparam WHERE ID=xxx'; 
    qry.ParamByName('blobparam').LoadFromStream(st, ftBlob); 
    qry.ExecSQL; 
end; 

결과는 동일하므로, 판독 데이터의 마지막 바이트가 손상된다.

내 문제가 될 수있는 것은 무엇입니까?


편집 :

만을 사용하여 스트림 같은 문제를 생성합니다.

데이터가 정확히 1519 바이트 인 경우에만 발생하는 것으로 나타났습니다. 그런 다음, 마지막 바이트는 전에 있던 것과 상관없이 0으로 설정됩니다. 물론이 문제에 대한 다른 사례가있을 수 있지만 그 때마다 재현 할 수있는 문제입니다.

끝까지 하나의 바이트를 추가하여 1520 바이트로 만들면 모든 것이 잘 동작합니다. 나는 그것을 일으킬 수있는 특별한 것을 보지 못했다.

+0

서버 OS 또는 데이터베이스 소프트웨어에 변경/패치가 설치되어 있습니까? –

+0

아니요, 얼마 전부터 실행되고 있던 실행 파일을 가져 와서 특정 바이너리 데이터로 피드하면 데이터베이스에서 변경된 내용이 다시 제공됩니다. 나는 지난 몇 년간 수행 된 여러 버전을 사용해 보았지만 모두 동일하게 작동합니다. 한 세트의 데이터가 손상되면 일반적으로 손상됩니다. 나는 그것이 데이터베이스 자체가 아니고, 내 코드에서 뭔가 있어야하고, 아마도 몇몇 변환이 있어야한다고 확신한다. 나는 그것을 볼 수 없다. – Holgerwa

+0

죄송합니다. 데이터베이스 서버에도 변경 사항이 없습니다. 임베디드 데이터베이스 엔진으로, 의존성이있는 내 실행 파일이됩니다. – Holgerwa

답변

1

저는 Gerry가 후행 NULL이 문자열 문제처럼 보임에 동의합니다.

수정 된 코드는 여전히 TStringStream을 사용하여 데이터를 씁니다. TBlobStream을 사용하여 데이터를 쓰려고 시도했는지, 그리고 차이가 있는지 확인해 보았습니까?

또는 특정 크기/경계 문제와 관련이 있는지 확인하려면 문제 데이터 끝 부분에 몇 가지 패킹 바이트를 추가하십시오. 또는 문제를 좁히기 위해 문제 데이터를 고정 된 테스트 패턴으로 바꾸어보십시오.

FWIW 오랫동안 문제없이 얼룩을 사용했지만 문자열로 취급하지 않았습니다.

문제를 좁히는 행운을 비네.

업데이트 : 내 코드가 괜찮은 것처럼 보이지만 데이터베이스/데이터 액세스 소프트웨어의 어딘가에서 다른 사람의 버그를보고 있습니다. 어떤 데이터베이스/드라이버/액세스 코드를 사용하고 있습니까?

+0

문제의 편집을 참조하십시오. – Holgerwa

+0

문제는 데이터베이스 관련 문제였습니다. 원인에 도달하는 데 도움이되는 모든 제안에 감사드립니다. – Holgerwa

관련 문제