#delphi
Вопрос:
Мне нужно взять значения из списка Tstring, сжать его с помощью системы.Библиотеки ZLIb и сохраните его в базе данных SQL Server в виде столбца VARBINARY(MAX).
До сих пор мне удавалось считывать сжатые данные из таблицы SQL, распаковывать их и загружать в список TSTRING. Однако моя проблема заключается в сохранении данных обратно в базу данных, и я не могу заставить их работать. Согласно документам Embarcadero, это должен быть очень простой процесс: http://docwiki.embarcadero.com/CodeExamples/Sydney/en/ZLibCompressDecompress_(Дельфи)
Вот код для обновления моей таблицы SQL. Когда я добираюсь до строки «CompressedStrm.copyFrom(InputStream, InputStream.Size);», я получаю сообщение об ошибке «Ошибка чтения потока».
procedure TdmMain.SaveSystemSetting(SettingName: string; Settings: TStringList);
var
InputStream, OutputStream: TMemoryStream;
CompressedStrm: TCompressionStream;
begin
InputStream:= TMemoryStream.Create;
OutputStream:= TMemoryStream.Create;
try
Settings.SaveToStream(InputStream, TEncoding.Default);
CompressedStrm := TCompressionStream.Create(clDefault, OutputStream);
try
CompressedStrm.CopyFrom(InputStream, InputStream.Size);
OutputStream.SaveToFile('c:output.zip');
finally
FreeAndNil(CompressedStrm);
end;
{save settings to the database}
qryWork.Close;
qryWork.SQL.Clear;
qryWork.SQL.Add('UPDATE SystemSettings');
qryWork.SQL.Add(' SET Setting = :data');
qryWork.SQL.Add(' WHERE SettingName = ''' SettingName '''');
qryWork.Parameters.ParamByName('data').LoadFromStream(OutputStream, ftBlob);
qryWork.ExecSQL;
finally
FreeAndNil(InputStream);
FreeAndNil(OutputStream);
end;
end;
Следующий код считывается из базы данных, распаковывает данные и загружает список TStringList — он работает на 100%:
procedure TdmMain.GetSystemSetting(SettingName: string; var Settings: TStringList);
var
SettingBlob: TBlobField;
DecompStream: TDecompressionStream;
InputStream, OutputStream: TMemoryStream;
begin
qryWork.Close;
qryWork.SQL.Clear;
qryWork.SQL.Add('SELECT Setting');
qryWork.SQL.Add(' FROM SystemSettings');
qryWork.SQL.Add(' WHERE SettingName = ''' SettingName '''');
qryWork.Open;
if not qryWork.EOF then
begin
SettingBlob := qryWork.FieldByName('Setting') as TBlobField;
InputStream := TMemoryStream.Create;
OutputStream := TMemoryStream.Create;
try
SettingBlob.SaveToStream(InputStream);
InputStream.Position := 0;
DecompStream := TDecompressionStream.Create(InputStream);
try
OutputStream.CopyFrom(DecompStream, 0);
OutputStream.Position := 0;
Settings.LoadFromStream(OutputStream, TEncoding.Default);
finally
FreeAndNil(DecompStream);
end;
finally
FreeAndNil(InputStream);
FreeAndNil(OutputStream);
end;
end;
qryWork.Close;
end;
Комментарии:
1. Зачем вам нужно это делать? Почему бы вам просто не сохранить строки в таблице?
2. О, Оливье, мы с тобой думаем об одном и том же… К сожалению, именно так система была написана 15 лет назад. Я понятия не имею, почему он был разработан таким образом, потому что таблица содержит только 15 записей, а строка, которую она хранит, имеет длину всего несколько сотен символов.
3. Ну, я думаю, ты забыл
InputStream.Position := 0;
.4. Собираюсь пнуть себя! Со всеми тестами я, должно быть, удалил «Входной поток. Позиция := 0;» заявление… Положи его обратно и вуаля!
5. Вам не нужны
FreeAndNil
локальные вары,.Free
этого достаточно.
Ответ №1:
Забыл изменить положение входного потока…
try
Settings.SaveToStream(InputStream, TEncoding.Default);
InputStream.Position := 0;
...