DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: sheik8888
今日帖子: 35
在线用户: 29
导航: 论坛 -> 数据库专区 斑竹:liumazi,waterstone  
作者:
男 aknightchen (.) ★☆☆☆☆ -
盒子活跃会员
2018/5/17 19:44:01
标题:
ClientDataSet的返回数据集中,中文字段名会出错,哪位仁兄知道如何修改这个BUG吗? 浏览:630
加入我的收藏
楼主:
with ClientDataSet1 do
begin
  Close;
  CommandText:='SELECT 1 AS '+''''+'清除该扫描中的所有绑定'+'''';
  Open;
end;

返回的字段名是"清除该扫描中的所有绑",少了一个汉字.

哪位仁兄知道如何修改这个BUG吗?

万分感谢!
----------------------------------------------
...
作者:
男 aknightchen (.) ★☆☆☆☆ -
盒子活跃会员
2018/5/17 19:45:47
1楼: 少了最后一个"定".

以上只是一个例子. 即: 对中文字段名支持有BUG.

XE5
----------------------------------------------
...
作者:
男 wang_80919 (Flying Wang) ▲▲▲▲△ -
普通会员
2018/5/17 19:50:16
2楼: 新版本 Delphi 的确有这个问题。
qc 上提交过解决办法。
已经忘了,具体地址了。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 yugong23 (yugong23) ▲▲△△△ -
注册会员
2018/5/17 21:39:41
3楼: 先多加一个汉字
----------------------------------------------
-
作者:
男 lsh341999 (虫子) ▲▲▲▲△ -
注册会员
2018/5/18 7:58:58
4楼: 长度限制了
----------------------------------------------
就怕想不到,没有做不到的
作者:
男 aknightchen (.) ★☆☆☆☆ -
盒子活跃会员
2018/5/18 10:47:05
5楼: 不是长度限制, 我试了, 字段名如果是全E文, 超过128字节,

才会提示有错, 但是, 中文, 也就几个字,也会出错.

ADOQuery也有这种错误, ClientDataSet也有这种错误.
(两者错误略有不同, ADOQuery字段最后一个汉字,也不显示,但它会显示一个怪怪的字符,  ClientDataSet则直接不显示最后一个汉字)

我想,可能是AdoDB.pas单元中,哪里有BUG,但苦于水平有限,找不到头续.
----------------------------------------------
...
作者:
男 iamdream (银河恒久远,梦想无止境!) ★☆☆☆☆ -
大贡献会员
2018/5/18 11:17:23
6楼: 用英文字段名,然后设置TField.DisplayLabel为中文名称即可。
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河) 偶的生活博客  偶的技术军事博客
作者:
男 sail2000 (小帆工作室) ★☆☆☆☆ -
盒子活跃会员
2018/5/18 18:14:25
7楼: 将写中文字段的人打死即可。
----------------------------------------------
delphi 是兴趣,和工作无关,即使它倒闭。
又不靠它 delphi 吃饭,怕甚?
作者:
男 wang_80919 (Flying Wang) ▲▲▲▲△ -
普通会员
2018/5/18 18:42:15
8楼: 这就是为啥,我明明修改过代码,却懒得找的原因。
打死这样做的,我的Fix代码也就没必要了。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 aknightchen (.) ★☆☆☆☆ -
盒子活跃会员
2018/5/19 10:56:06
9楼: 这样做的意义在于:

比如: 我可以设计一个报表,查询出数据,

数据列,由SQL自动产生. 它的列名,也直接用中文来做.

这样,报表可读性就很高. 整个程序,设计也简单,只要你在SQL中,列名指定一下,

就能很易懂.(这种功能,只限于客户自定义报表时用),

真正数据库,全是采用E文的.

TO: Flying Wang , 有空帮忙找一下吧. 我只会堆砖, 但不擅于深入的技术.
----------------------------------------------
...
作者:
男 aknightchen (.) ★☆☆☆☆ -
盒子活跃会员
2018/5/20 11:57:53
10楼: adodb.pas中.

    //Result := Length(PWideString(@TVarData(Value).VOleStr)^);改为下面这句
    Result:=Length(Value);

===>我测试过了.改后,重编绎中间层和客户端,

问题依旧.没有效果.(XE5)
----------------------------------------------
...
作者:
男 aknightchen (.) ★☆☆☆☆ -
盒子活跃会员
2018/5/20 13:27:58
11楼: 追踪 Datasnap.DBClient.pas

发现是这句执行完后,就得到错误的字段名了.

LName := TMarshal.ReadStringAsAnsi(CP_UTF8, TPtrWrapper.Create(@FieldDesc.szName[0]));

TMarshal.ReadStringAsAnsi是来源于System.pas中.

下面就看不懂了...
----------------------------------------------
...
作者:
男 c5soft (大道至简) ▲▲▲△△ -
注册会员
2018/5/20 23:13:59
12楼: 造成这种结果有可能是字符集转换出了问题。上面这句好像是说要将UTF8字符集转换成ANSI。CP=Code Page。不要轻易认定是Bug,有时候可能是咱们不会用。
----------------------------------------------
-
作者:
男 aknightchen (.) ★☆☆☆☆ -
盒子活跃会员
2018/5/21 8:25:27
13楼: 是的.它是System单元下的, 基本上,不可能是BUG.

我怀疑可能是服务端传送到客户端之间出问题.(或许在客户端,或许在服务端)
----------------------------------------------
...
作者:
男 wang_80919 (Flying Wang) ▲▲▲▲△ -
普通会员
2018/5/21 8:32:47
14楼: https://quality.embarcadero.com/browse/RSP-18838
既然打不死你,就算了吧。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 llo2003 (Leo) ★☆☆☆☆ -
盒子活跃会员
2018/5/21 9:03:15
15楼: LName := TMarshal.ReadStringAsAnsi(CP_UTF8, TPtrWrapper.Create(@FieldDesc.szName[0]));
if Lname.length = sizeof(midasname)-1 then

改为

if strlen(fielddesc.szname)=sizeof(midasname)-1 then
----------------------------------------------
-
作者:
男 aknightchen (.) ★☆☆☆☆ -
盒子活跃会员
2018/5/27 9:58:30
16楼: TO wange_80919:
 
 你提供的网页,打不开,需要登录.(好像不允许直接免费注册)

Not a member? To request an account, please contact your JIRA administrators
----------------------------------------------
...
作者:
男 aknightchen (.) ★☆☆☆☆ -
盒子活跃会员
2018/5/27 10:05:46
17楼: TO  llo2003 :

按你提供的,改了, 执行正常,不会报错, 但是, 仍然和原先一样显示字段名(少了一下"定"字)
----------------------------------------------
...
作者:
男 wang_80919 (Flying Wang) ▲▲▲▲△ -
普通会员
2018/5/27 10:37:22
18楼: 楼主连 QC 都上不去,就别搞 DLEPHI 开发了。
注册地址
http://edn.embarcadero.com
----------------------------------------------
(C)(P)Flying Wang
作者:
男 szlbz (szlbz) ★☆☆☆☆ -
盒子活跃会员
2018/5/27 11:04:13
19楼: https://quality.embarcadero.com/browse/RSP-18838
find

Datasnap.DBClient.pas

find

procedure TCustomClientDataSet.AddFieldDesc(FieldDescs: TFieldDescList;

  var DescNo: Integer; var FieldID: Integer; FieldDefs: TFieldDefs);

change code to:

 

procedure TCustomClientDataSet.AddFieldDesc(FieldDescs: TFieldDescList;

  var DescNo: Integer; var FieldID: Integer; FieldDefs: TFieldDefs);

var

  I, LPrecision, LSize: Integer;

  LType: TFieldType;

  LName: string;

  FieldDesc: DSFLDDesc;

  V: Variant;

  LFieldDef: TFieldDef;

//fix by flying wang.

  TempName: string;

begin

  FieldDesc := FieldDescs[DescNo];

  Inc(DescNo);

  if ((fldAttrLINK and FieldDesc.iFldAttr) <> 0) then

  begin

    Inc(FieldID);

    Exit;

  end;

//fix and remove by flying wang.

//  LName := TMarshal.ReadStringAsAnsi(CP_UTF8, TPtrWrapper.Create(@FieldDesc.szName[0]));

//  if LName.Length = SizeOf(MIDASNAME) - 1 then

//  begin

//    V := InternalGetOptionalParam(szFIELDNAME, FieldID);

//    if not VarIsNull(V) and not VarIsClear(V) then

//      LName := VarToStr(V);

//  end;

//fix by flying wang.

  LName := '';

  V := InternalGetOptionalParam(szFIELDNAME, FieldID);

  if not VarIsNull(V) and not VarIsClear(V) then

    LName := VarToStr(V);

  if LName.IsEmpty then

    LName := TMarshal.ReadStringAsAnsi(CP_UTF8, TPtrWrapper.Create(@FieldDesc.szName[0]));

  TempName := LName;

//fix by flying wang end.

  I := 0;

  while FieldDefs.IndexOf(LName) >= 0 do

  begin

    Inc(I);

//    LName := string.Format('%s_%d', [TMarshal.ReadStringAsAnsi(CP_UTF8, TPtrWrapper.Create(@FieldDesc.szName[0])), I]);

//fix by flying wang.

    LName := string.Format('%s_%d', [TempName, I]);

  end;

...

how long added a comment - 16/Aug/17 2:03 AM

Bug.
David Yip added a comment - 14/Sep/17 3:24 AM

Fixing 2 Bugs in Datasnap.DBClient.pas and Datasnap.Provider.pas

These bugs prevent normal display of long chinese field name

 

// (1) Datasnap.DBClient.pas:

 

procedure TCustomClientDataSet.AddFieldDesc(FieldDescs: TFieldDescList;

  var DescNo: Integer; var FieldID: Integer; FieldDefs: TFieldDefs);

var

  I, LPrecision, LSize: Integer;

  LType: TFieldType;

  LName: string;

  FieldDesc: DSFLDDesc;

  V: Variant;

  LFieldDef: TFieldDef;

begin

  FieldDesc := FieldDescs[DescNo];

  Inc(DescNo);

  if ((fldAttrLINK and FieldDesc.iFldAttr) <> 0) then

  begin

    Inc(FieldID);

    Exit;

  end;

  LName := TMarshal.ReadStringAsAnsi(CP_UTF8, TPtrWrapper.Create(@FieldDesc.szName[0]));

  //----------

  //if LName.Length = SizeOf(MIDASNAME) - 1 then  //"LName.Length" changed to "StrLen(FieldDesc.szName)"

  if StrLen(FieldDesc.szName) = SizeOf(MIDASNAME) - 1 then

  //----------

  begin

    V := InternalGetOptionalParam(szFIELDNAME, FieldID);

    if not VarIsNull(V) and not VarIsClear(V) then

      LName := VarToStr(V);

  end;

......

 

 

//(2) Datasnap.Provider.pas:

 

procedure TCustomPacketWriter.AddAttribute(Area: TPcktAttrArea; const ParamName: string;

  const Value: OleVariant; IncludeInDelta: Boolean);

.......

    begin

      ParamType := (dsfldZSTRING shl dsSizeBitsLen) or dsVaryingFldType or SizeOf(Word);

      Count := Length(TEncoding.UTF8.GetBytes(string(Value)));

      ParamLen := Count + 1;

      PWord(FBuffer)^ := ParamLen;

      Inc(ParamLen, SizeOf(Word));

      if Count > (Length(FBuffer) - SizeOf(Word)) then

        Count := Length(FBuffer) - SizeOf(Word);

      //----------

      //LValuePtr := M.AsAnsi(string(Value)).ToPointer;  // "M.AsAnsi" changed to "M.AsUTF8"

      LValuePtr := M.AsUTF8(string(Value)).ToPointer;

      //----------

      Move(LValuePtr^, FBuffer[SizeOf(Word)], Count);

      FBuffer[ParamLen-1] := 0; //Ensure null termination

    end

......
----------------------------------------------
-
作者:
男 aknightchen (.) ★☆☆☆☆ -
盒子活跃会员
2018/6/4 0:29:19
20楼: 无比地感谢"Flying Wang",无比地感谢 szlbz.

我的是XE5,
我按楼上提供的代码,

我修改了Datasnap.DBClient.pas中.

  //----------
  //if LName.Length = SizeOf(MIDASNAME) - 1 then  //"LName.Length" changed to "StrLen(FieldDesc.szName)"
  if StrLen(FieldDesc.szName) = SizeOf(MIDASNAME) - 1 then
  //----------


还修改了Datasnap.Provider.pas中的

      //----------
      //LValuePtr := M.AsAnsi(string(Value)).ToPointer;  // "M.AsAnsi" changed to "M.AsUTF8"
      LValuePtr := M.AsUTF8(string(Value)).ToPointer;
      //----------


完美地支持长中文的字段了.再次感谢两位的指点.也感谢其它朋友的参与.
----------------------------------------------
...
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v2.1 版权所有 页面执行46.875毫秒 RSS