Delphi,TBlobField和UTF8

时间:2012-05-17 21:10:49

标签: delphi utf-8 blob clob

这是我的架构:

Datasnap Client< => Datasnap Server< => Oracle 11 XE

我正在从客户端使用带有TDSProviderConnection的远程提供程序来访问我的数据集。

基本上,我使用TIdHTTP组件来查询网站并将结果存储在Oracle CLOB列中。

将结果保存到文件时,正确显示文本,重音符号和其他异域字符。 使用sqldeveloper插入clob的相同文本也会正确显示。

但是当我通过datasnap架构进行此操作时,会显示错误的字符(如黑色钻石或“upperscore”(顶部的下划线)

我的DB Charset是AL32UTF8,它是Oracle 11 XE上的默认字符集。

为了更好地了解问题所在,我重写了部分客户端以直接访问我的数据库。我可以说问题不在于datasnap客户端和服务器之间的通信。

现在我的架构是:

客户< =>数据库

我通过以下方式访问Oracle XE:

TClientDataSet< => TDataSetProvider< => TSQLDataSet< =>设为TSQLConnection

TIdHTTP的响应是TMemoryStream,存储在TClientDataset中:

    With ClientDataSet do
    begin
      Edit;
      (Fieldbyname('MYCLOBFIELD') as TBlobField).LoadFromStream(MS);
      ApplyUpdates(-1);
    end;

编辑:5月21日

我测试了TBlobField,这个组件似乎是我问题的一部分。让我解释一下:

我带了一个包含扩展字符集中字符的随机字符串,如下所示:'ÐÒÙÜßąûûÆ'

使用我的ClientDataSet,将分配更改为:

    FieldByname('MYCLOB').value := 'ÐÒÙÜßąĀûÆ'; // <-- Inserted correctly into Oracle.

将此字符串放在文件'test.txt'中并尝试显示包含内容的弹出窗口不起作用:

    var
      MyBlobField: TBlobField;
    begin
      MyBlobField.LoadFromFile('test.txt');
      ShowMessage(MyBlobField.AsString); // <-- does not display correctly

但是使用TMemo显示内容就像魅力一样:

    var
      MyMemo: TMemo;
    begin
      MyMemo.Lines.LoadFromFile('test.txt'); // <-- Works perfectly !!

我尝试将TBlobField.BlobType属性设置为ftOraClobftBlob而没有运气。

最后,使用TStringList(实际上TMemo.Lines将字符串加载到Oracle中)可以解决问题。

我想TBlobField.LoadFromFile/LoadFromStream或者我没有正确使用它。

TStringList从TStrings继承其LoadFromFile/LoadFromStream方法,该方法有效。

任何帮助将不胜感激。 问候。

1 个答案:

答案 0 :(得分:1)

如果您想将一些数据放到TBlobField,您可以尝试:

procedure SetParamBlob(Param : TParam; sData : String);
var  
 Str       : TStringStream;
begin
 Str := TStringStream.Create(sData);
 try
   Param.LoadFromStream(Str, ftBlob);
 finally
   Str.Free;
 end;
end;

或者这个:

procedure SetParamBlob(Param : TParam; sData : String);
var List   : TStringList;
   MemStream : TMemoryStream;
begin
  Param.Clear;
  Param.DataType := ftBlob;
  List   := TStringList.Create;
  MemStream := TMemoryStream.Create;
  try
    List.Text := sData;
    List.SaveToStream(MemStream);
    MemStream.Seek(0, soFromBeginning);
    Param.LoadFromStream(MemStream, ftBlob);
   finally
    FreeAndNil(List);
    FreeAndNil(MemStream);
   end;
end;

... ... SetParamBlob(q.ParamByName('FIELD'),MyMemo.Text); ...

您可以通过以下方式从文件加载数据:

   function LoadData(sFileSrc : String) : String;
   var F : TFileStream;
   begin
     F := TFileStream.Create(sFileSrc, fmOpenRead + fmShareDenyNone);
     try
       SetLength(Result, f.Size);
       f.Read(Result[1],f.Size);
      finally
       F.Free;
      end;
    end;