2015-10-15 6 views
1

Оригинал Я хочу сохранить/получить отчет из fastreports, который использует SaveToStream/LoadToStream для этой цели. Я использую RAD Studio XE6 (upd1).Delphi поток в/из базы данных с FireDAC

В базе данных у меня есть таблица Reports с полем индекса 'StVn'type int и поле' Определение 'type ntext. База данных MSSQL и для сохранения отчета я использую:

FDCommand.CommandText.Text:='UPDATE Reports SET Definition= :pDefinition WHERE StVn=1'; 
    FDCommand.Params.ParamByName('pDefinition').LoadFromStream(MyStream, ftWidememo); 
    FDCommand.Execute; 

и для извлечения:

FDQuery.SQL.Text:='SELECT * FROM Reports WHERE StVn=1'; 
    FDQuery.Open(); 
    MyStream:=FDQuery.CreateBlobStream(FDQuery.FieldByName('Definition'),bmRead); 

Это работало в течение нескольких коротких отчетов, но и для любой реальной экономии/восстанавливающие развращает сообщить определение.

Так я делаю тест, по новой форме с как раз Memo и пытался сохранить/восстановить его с такой же установкой Асесс данных (FDConnection, FDCommand, FDQuery) и следующий код:

procedure TForm1.BMemoSaveClick(Sender: TObject); 
var TmpStream:TStream; 
begin 
    TmpStream:=TMemoryStream.Create; 
    Memo1.Lines.SaveToStream(TmpStream); 
    ShowMessage(IntToStr(TmpStream.Size)); 
    FDCommand1.Params.Clear; 
    FDCommand1.CommandText.Text:='UPDATE Reports SET Definition= :pDefinition WHERE StVn=1'; 
    FDCommand1.Params.ParamByName('pDefinition').LoadFromStream(TmpStream,ftWideMemo); 
    FDCommand1.Execute(); 
    TmpStream.Free; 
end; 

procedure TForm1.BMemoLoadClick(Sender: TObject); 
var TmpStream:TStream; 
begin 
    FDQuery.SQL.Text:='SELECT * FROM Reports WHERE StVn=1'; 
    FDQuery.Open(); 
    TmpStream:=FDQuery.CreateBlobStream(FDQuery.FieldByName('Definition'),bmRead); 
    ShowMessage(IntToStr(TmpStream.Size)); 
    Memo1.Lines.LoadFromStream(TmpStream); 
    TmpStream.Free; 
end; 

Как вы можете см. Я добавил ShowMessage, чтобы увидеть размер потока при сохранении и восстановлении, и если я сохраню только текст по умолчанию «Memo1», я получаю длину 7 при сохранении и длину 14 при загрузке заметки (она всегда удваивается).

Любые идеи, что я делаю неправильно?

ответ

0

Заметь, я не проверил базу данных сохранения/загрузки, как я не имею MSSQL, но я уверен, что это является причиной:

По умолчанию TString использует кодировку по умолчанию (TEncoding.Default), что, скорее всего, ANSI (в моем случае Windows-1252), отсюда длина текста заметки, отображаемая как 7 байт: 5 для «Memo1» и две для CRLF.

Однако ваша колонка имеет тип NTEXT, который хранит текст как UTF-16. Когда вы читаете это, вы делаете это как blob, и FireDAC не выполняет преобразования символов 1, а значит, удваивает размер.

Я предлагаю вам рассматривать отчет как двоичные данные и хранить его как таковой с использованием столбца типа «изображение» и использовать ftBlob вместо ftWideMemo.

Смежные вопросы