这是我的架构:
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
属性设置为ftOraClob
或ftBlob
而没有运气。
最后,使用TStringList
(实际上TMemo.Lines
将字符串加载到Oracle中)可以解决问题。
我想TBlobField.LoadFromFile/LoadFromStream
或者我没有正确使用它。
TStringList从TStrings继承其LoadFromFile/LoadFromStream
方法,该方法有效。
任何帮助将不胜感激。 问候。
答案 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;