|
Тема
|
Качване на голям файл в база данни ?
|
|
Автор | Daniel (Нерегистриран) |
Публикувано | 19.12.06 15:07 |
|
Здравейте на всички.
Нуждая се от помощ за следния проблем - в база данни (MS Access, MS SQL Server 2000) се опитвам да вкарам голям (над 100 МВ) файл в съответно BLOB поле, но не успявам. За файлове с размер под 90-100 МВ нещата се получават, но иначе връща грешка E_FAIL.
Ползва се ADO за връзка с базата данни.
Пример от ползвания код е даден по-долу:
var
LSFile : _Stream; //interface _Stream from ADODB_TLB.pas
ADORs : TRecordset; //class from ADODB_TLB.pas
intRealSize, intChunkSize, intAllSize : integer;
.....
.....
LSFile.LoadFromFile(SourceFile);
while LSFile.State <> adStateOpen do
sleep(5);
intRealSize := 0;
intChunkSize := 500000;
intAllSize := LSFile.Size;
while intRealSize <= intAllSize do
begin
ADORs.Fields.Item['FieldBLOB'].AppendChunk(LSFile.Read(intChunkSize));
intRealSize := intRealSize + intChunkSize;
end;
ADORs.Update;
result:=true;
Кода е подобен на този в сайта на delphi.about.com за качване на изображение в база данни.
При изеикване на ADORs.Update се появява грешка и промените не се получават.
Платформата е:
Windows XP + SP2
Delphi 6 Professional
База данни: MS Access, MS SQL Server 2000, Oracle
Търсих на доста места в мрежата, но досега решение не съм открил. В повечето случаи ставаше въпрос за обекти с размери до 1 МВ и ползване на BDE, което е различно от моя случай.
Моля, ако някой има идея как може да се реши проблема, нека каже.
Благодаря предварително и весело изкарване на празниците
| |
Тема
|
Re: Качване на голям файл в база данни ?
[re: Daniel]
|
|
Автор | Йopдaн (Нерегистриран) |
Публикувано | 20.12.06 14:38 |
|
http://support.microsoft.com/kb/258038
| |
Тема
|
Re: Качване на голям файл в база данни ?
[re: Йopдaн]
|
|
Автор | Daniel (Нерегистриран) |
Публикувано | 21.12.06 12:50 |
|
Йордане, видях примера който си ми пратил.
Направих един подобен пример с почти същите настройки (само CommandTimeout-a на обекта е зададен със стойност 1000000).
По-интересното е, че при просто тестово приложение този пример сработва, докато в по-голяма система, със същите настройки се издънва, което все още не мога да си обясня защо се случва.
И в двата случая го тествам под Аксес, но не мисля че това е проблема.
По-скоро е нещо друго, което ми убягва засега.
Мерси все пак за оказаната помощ.
| |
Тема
|
Re: Качване на голям файл в база данни ?
[re: Daniel]
|
|
Автор | Ивaнчo (Нерегистриран) |
Публикувано | 21.12.06 22:23 |
|
Какво ти каза Акцеса?!?
Че записа е променен, докато го пълниш ли?
| |
Тема
|
Re: Качване на голям файл в база данни ?
[re: Ивaнчo]
|
|
Автор | Daniel (Нерегистриран) |
Публикувано | 22.12.06 10:37 |
|
Не е това съобщемието. По-скоро проблема ще се окаже в настройките за CursorLocation и CommandTimeout на ADORecordset.
Особено второто ще е малко сложно за изчисление, понеже си зависи и от мрежата.
| |
Тема
|
Re: Качване на голям файл в база данни ?
[re: Daniel]
|
|
Автор | Ивaнчo (Нерегистриран) |
Публикувано | 22.12.06 11:28 |
|
Предполагам, че CommandTimeout:=0 не е желателно да го използваш, макар че върши работа...
аз използва следния код, може да е модификация на нещо което си срещал, но върши работа, поне при мен...
procedure TForm1.Button4Click(Sender: TObject);
var
MemStream: TMemoryStream;
StrSQL, ConnectionString: string;
RecordSet: _RecordSet;
RecordsAffected: olevariant;
ImgActualSize: integer;
lngOffset, iSize: integer;
Data: olevariant;
P: PByteArray;
begin
MemStream := TMemoryStream.Create;
ImageTarget.Picture.Bitmap.SaveToStream(MemStream);
MemStream.Seek(0, 0);
StrSQL := 'SELECT ENTRYID, IMAGE_DATA FROM MAIL_USERS WHERE ENTRYID={00000001-0000-0000-0000-000000000000}';
ConnectionString :=
'Provider=Microsoft.Jet.OLEDB.4.0;Password="";Data Source=C:\IMIADOAB.mdb';
Recordset := CoRecordset.Create;
Recordset.Open(StrSQL, ConnectionString, adOpenKeyset,
adLockOptimistic, adCmdText);
Data := VarArrayCreate([0, 4095], varByte);
iSize := 4096;
repeat
P := VarArrayLock(Data);
FillChar(P^, iSize, 0);
iSize := MemStream.Read(PByte(P)^, 4096);
VarArrayUnlock(Data);
if iSize > 0 then
begin
if iSize < 4096 then
VarArrayReDim(Data, iSize - 1); // must trim to the exact size
Recordset.Fields.Item['IMAGE_DATA'].AppendChunk(Data);
// append chunk to parameter object
end; // if
until iSize < 4096;
Data := Unassigned;
Recordset.Update(EmptyParam, EmptyParam);
Recordset := nil;
MemStream.Free;
end;
| |
|
|
|
|