DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: webb123
今日帖子: 30
在线用户: 17
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 ke8880 (ke8880) ★☆☆☆☆ -
普通会员
2019/2/25 12:33:57
标题:
求助:FireDAC中文字符串储存到数据库时长度变短!! 浏览:3309
加入我的收藏
楼主: Delphi 10.2.3用FireDAC连接Firebird 2.5,中文字符串写入数据库后长度变成原来的一半,比如“中国”存入的只有“中”。请问如何设置解决这个问题??谢谢!!
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2019/2/25 12:40:28
1楼: 不知道啊。
我们的很正常。
反正就是各种参数。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 grjs_2004 (grjsITname) ★☆☆☆☆ -
盒子活跃会员
2019/2/25 13:26:46
2楼: 你数据库的字段长度检查一下,还有客户端界面的数据控件FieldList对应字段的长度也检查一下
----------------------------------------------
Everyone will to do best!
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2019/2/25 13:39:27
3楼: 人家的意思是输入 2N 个 字符,保存和读取的结果是 N 个。这个多半不是长度设置问题。
就是 参数问题。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 grjs_2004 (grjsITname) ★☆☆☆☆ -
盒子活跃会员
2019/2/25 14:01:36
4楼: 客户端的字段长度如果小于数据库对应字段的长度,存储时,会自动截断,而不会报异常的!
----------------------------------------------
Everyone will to do best!
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2019/2/25 14:18:52
5楼: 那么楼上的请问。
我保存
你好中国。结果读取到 你好。
同一个字段,我保存,楼上。读取到 楼。
那么这个字段,长度是多少。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 pp0123 (pp0123) ★☆☆☆☆ -
普通会员
2019/2/25 14:28:20
6楼: 是没了一半,还是没了最尾一个字(那是行尾操作符转换问题). 还有是没了那部分,会不会是繁简通用的保留,单纯简体的缺了(那是数据库编码定义问题).
----------------------------------------------
-
作者:
男 ke8880 (ke8880) ★☆☆☆☆ -
普通会员
2019/2/25 15:54:18
7楼: 谢谢各位的热心解答!是每次保存时只存一半的字符串。待储存的字符串长度小于数据库字段的设定值。
----------------------------------------------
-
作者:
男 earthsbest (全能中间件) ▲▲▲▲△ -
普通会员
2019/2/25 16:01:58
8楼: 建议楼主把demo发上来,估计很快可以找到问题甚至解决了,楼主提供的信息太有限,大伙都只能猜。
----------------------------------------------
Delphi4Linux Delphi三层/FireDAC 技术群:734515869 http://www.cnblogs.com/rtcmw
作者:
男 grjs_2004 (grjsITname) ★☆☆☆☆ -
盒子活跃会员
2019/2/25 16:49:32
9楼: 晕死,字段的长度不一致,就调成一致啊!以数据库字段长度为准!
如果你客户的内容确实有需要超过数据库字段长度,那就先调整数据库字段的长度,客户端的字段长度再调成跟数据库的字段长度一致,就可以了!
(FireDAC组件的字符型字段长度,一般等于数据库字段长度+1)
----------------------------------------------
Everyone will to do best!
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2019/2/25 17:08:29
10楼: 楼上的晕死你吧。
假设本数据库,就 TMD 一个表,表名叫 TMD。
就 TMD 一个字段。类型 NVarChar 长度 20,叫 TEST。
结果 你写一个 你好中文,打开一看,就只有 你好。
你 又写一个 中文,打开一看,就只有 中。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2019/2/25 23:40:13
11楼: 估计是数据库问题。我用Firedac连接sqlserver/sqlanywhere没有问题。
----------------------------------------------
-
作者:
男 pp0123 (pp0123) ★☆☆☆☆ -
普通会员
2019/2/26 4:17:38
12楼: 储存的字符串长度小于数据库字段的设定值...那当然啰!若储存的长于数据库设定,叫数据库如何做好? 容不下当然要删去后面的内容.

还有,中文字要用上2个 char, 别当作一字一 char 去存.
----------------------------------------------
-
作者:
男 hdcopy (hdcopy) ★☆☆☆☆ -
普通会员
2019/2/26 9:08:02
13楼: 不是firedac的锅,中间件那里检查下吧,肯定是代码出了问题。

应该是哪个函数/过程(也可能是数据库里的)有个长度参数,
然后玩砸了呗
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2019/2/26 9:54:55
14楼: 9、12、13 楼 请认真阅读 楼主的内容。
同时也请认真阅读 5 楼 10 楼的 内容。
我觉得,大家应该都小学毕业了吧。
语文不至于是火星版的吧!

小学语文和小学数学 都没学好,搞个屁的软件开发。\

连问题描述都理解不了。怎么去理解客户需求。
怎么去和你的领导沟通。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2019/2/26 11:25:41
15楼: 我琢磨着,楼主既然会玩firebird,应该不至于不晓得字段长度这个问题。大家既然对这个这么关注,也是担心这种小众数据库是不是可靠的。
----------------------------------------------
-
作者:
男 mochizuki (mochizuki) ★☆☆☆☆ -
普通会员
2019/2/26 12:22:45
16楼: 字符集问题?我有个小项目用的是也是firebird+firedac,字符集是utf8,一点问题也没有
----------------------------------------------
-
作者:
男 iamdream (银河恒久远,梦想无止境!) ★☆☆☆☆ -
大贡献会员
2019/2/26 14:59:35
17楼: 楼主贴一下表字段的定义呗!有可能是数据库字段定义的是Ansi,存的是Unicode?瞎猜……
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河) 博客挂了……
作者:
男 pp0123 (pp0123) ★☆☆☆☆ -
普通会员
2019/2/26 15:07:41
18楼: iamdream 说过了,楼主没回应,而且喷子在喷是文盲啊。
我看到重点是楼主在7楼的最后一句,相当有趣。
”待储存的字符串长度小于数据库字段的设定值”--那不是当然吗?
储存的长度怎可能长于数据库设定值?
----------------------------------------------
-
作者:
男 ke8880 (ke8880) ★☆☆☆☆ -
普通会员
2019/2/26 16:54:04
19楼: 十分感谢大家的相助!!!!

按以下代码执行,出现字符串问题:
DC.RS.Params.Clear;
DC.RS.SQL.Text := 'update fmclip set labelcaption=:labelcaption,' +
'labelparent=:labelparent where q_id=:q_id and paper_id=:paper_id';
DC.RS.ParamByName('q_id').AsInteger := ID;
DC.RS.ParamByName('paper_id').AsInteger := FPaperID;
DC.RS.ParamByName('labelcaption').AsString := pData.ItemCaption;
DC.RS.ParamByName('labelparent').AsInteger := LabelParent;
DC.RS.ExecSQL;

改为以下代码后正常:
DC.RS.SQL.Text := Format('update fmclip set labelcaption=''%0:s'',' +
'labelparent=%1:d where q_id=%2:d and paper_id=%3:d',[pData.ItemCaption,LabelParent,ID,FPaperID]);
DC.RS.ExecSQL;

以上代码均在事务(Transaction)中。
此帖子包含附件:
PNG 图像
大小:28.5K
----------------------------------------------
-
作者:
男 ke8880 (ke8880) ★☆☆☆☆ -
普通会员
2019/2/26 16:58:29
21楼: 数库库字段设置
此帖子包含附件:
PNG 图像
大小:16.4K
----------------------------------------------
-
作者:
男 ke8880 (ke8880) ★☆☆☆☆ -
普通会员
2019/2/26 17:01:29
22楼: To mochizuki:
我改为字符集为UTF8或GB_2312,仍有问题
----------------------------------------------
-
作者:
男 ke8880 (ke8880) ★☆☆☆☆ -
普通会员
2019/2/26 17:03:27
23楼: 另外,我把数据库组件FireDAC换成UniDAC或Zeoslib,同样的代码,没有这个问题
----------------------------------------------
-
作者:
男 earthsbest (全能中间件) ▲▲▲▲△ -
普通会员
2019/2/26 17:11:32
24楼: 将AsString 改为 AsWideString 
DC.RS.ParamByName('labelcaption').AsWideString := pData.ItemCaption;
----------------------------------------------
Delphi4Linux Delphi三层/FireDAC 技术群:734515869 http://www.cnblogs.com/rtcmw
作者:
男 ke8880 (ke8880) ★☆☆☆☆ -
普通会员
2019/2/26 19:53:47
25楼: To earthsbest (全能中间件):

谢谢。这个我改过,不起作用。
----------------------------------------------
-
作者:
男 bluestorm8 (bluestorm) ▲▲△△△ -
普通会员
2019/2/26 21:15:55
26楼: FDConnection -> Params -> CharLenMode改为clmBytes试试看
----------------------------------------------
-
作者:
男 devilman (devilman) ★☆☆☆☆ -
普通会员
2019/2/27 8:35:57
27楼: 如果英文可以正常写入,中文不行的话,很可能是数据库或数据库表字段的字符集定义是英文单字节,两者都要确认。不是Firedac的连接设定,而是创建数据库时定义的字符集。
如果数据库的Charset是None的话,恐怕表的数据集指定成中文也不管用
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2019/2/27 9:59:12
28楼: 有些人,你只有骂他,
他才会把脑子转起来。眼神也会提高。
因为,他想证明,你骂错了。
这些人外号 不挨骂不舒服斯基

关于楼主
VarChar 是 单字节数据,只能存放 ANSI 编码的数据(当然,我完全可以把他当成流,那么就什么都能存,但是当成 string 就不可能 多国语言 一起保存了。比如 简体中文加韩文加俄语一起保存,ANSI 是不支持的)。
NVarChar 是 多字节数据,可能是 UTF8 或者 Unicode 的,看数据库开发者的想法。

如果你非要用 VarChar 那么,出现各种错误,在所难免。
但是 FDConnection 肯定是需要修改参数的。
具体改那个参数,改成什么值。
我们都不知道。因为我们水平低,都是用 N开头的。

另外 24 楼 的 答案 可能(注意是可能)是正解。
因为你的 字段是 ANSI 的。
那么 AsString 也对应是 只支持 ANSI 的。虽然是 Unicode 的类型。但是 保存读取,都只支持 Ansi 的。
AsWideString 才是真正支持 Unicode 的。保存和读取采用什么编码,就不清楚了。

如果你 字段的类型是 N 开头的。那么 AsString 和 ASWideString 效果是一样的。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 bluestorm8 (bluestorm) ▲▲△△△ -
普通会员
2019/2/27 12:02:44
29楼:     刚才我用Win10(64bit) + FireBird 3.04(64Bit) + FireDac(10.3)试了一下,完全没有楼主说的问题, 一切正常.Firedac的Connction只设置过Server、port、username、password和database
  另外FireBird没有nvarchar这种数据类型。
  测试用的建表语句:create table test (id integer, name varchar(32))

测试代码
procedure TForm1.Button1Click(Sender: TObject);
begin
  FDConnection1.Connected := True;
  FDQuery1.Open('select * from test');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  FDQuery1.ExecSQL('insert into test(id, name) values (1, ''aaaa'')');
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  FDQuery1.SQL.Text := 'update test set name = :name where id = :id';
  FDQuery1.ParamByName('id').AsInteger := 1;
  FDQuery1.ParamByName('Name').AsString := '中文字符串';
  FDQuery1.ExecSQL;
end;
----------------------------------------------
-
作者:
男 bluestorm8 (bluestorm) ▲▲△△△ -
普通会员
2019/2/27 12:10:40
30楼: 另外,如果用firebird是为了免费,那还不如用mysql或mongodb这类比较通用、功能也比较强的数据库
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2019/2/27 12:37:58
31楼: FireBird 一点问题都没有。比你们的 mysql 好多了。

的确没有 N开头的。
所以,我们后面就设置了 Charset 为 UTF8。这样就安全了。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 bluestorm8 (bluestorm) ▲▲△△△ -
普通会员
2019/2/27 13:17:25
32楼: 首先,我从来不用mysql和mongodb,其次,我也不相信FirdBird比mysql好。
----------------------------------------------
-
作者:
男 lzhg_kn (lzhg_kn) ★☆☆☆☆ -
盒子活跃会员
2019/2/27 15:01:15
33楼: DC.RS.ParamByName('labelcaption').AsMemo := pData.ItemCaption;
百分百解决问题
----------------------------------------------
-
作者:
男 ke8880 (ke8880) ★☆☆☆☆ -
普通会员
2019/2/27 18:09:46
34楼: To bluestorm8:

谢谢!!我也是这样的代码,但我两台机式测试过都有问题。Windows 10 64bit,Delphi 10.2.3
Firebird 2.5.7 32bit。
----------------------------------------------
-
作者:
男 ke8880 (ke8880) ★☆☆☆☆ -
普通会员
2019/2/27 18:12:51
35楼: To lzhg_kn (lzhg_kn):

如你所言,这个真可以,但换成AsString问题依然,另外,如果写入的字符串是全英文或数字,没问题;
代码、数据库、Firebird版本都不变,仅换成UniDAC、或Zeoslib组件,则没问题,太奇怪了!难道是FireDAC有Bug,但你们的却都是正常的。
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2019/2/27 18:56:22
36楼: 屁的  BUG .
说了多少遍了。要设置参数。
我们的配置是默认不需要参数的。
你的配置,不是我们那些标准的 全球兼容 的。你的不兼容 所以,需要特殊配置。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 ke8880 (ke8880) ★☆☆☆☆ -
普通会员
2019/2/27 19:12:26
37楼: 你看我贴的图,没有特殊参数
----------------------------------------------
-
作者:
男 iamdream (银河恒久远,梦想无止境!) ★☆☆☆☆ -
大贡献会员
2019/2/27 19:20:32
38楼: 字段字符集改成unicode,连接时也改成unicode.
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河) 博客挂了……
作者:
男 he_19_79 (he) ▲▲▲▲▲ -
普通会员
2019/2/27 21:07:36
39楼: 是不是你所用的Windows系统的字符集导致的?(我觉得是FireDAC数据驱动的错)。 RO DA也出现过这种错,保存Stream时会漏字符。

在控制面板-时钟、语言、区域中选择“区域”,选择“管理” , 把“非Unicodet程序的语言”-“更改区域语言设置”改变一下(如改成英语,不行时再改成简体等),试试。(服务器同本机都改变试试)
----------------------------------------------
-
作者:
男 bluestorm8 (bluestorm) ▲▲△△△ -
普通会员
2019/2/28 8:12:58
40楼: 估计直接写成DC.RS.ParamByName('labelcaption').Value := pData.ItemCaption;就可以了。
我的例子里面是可以的,估计你的情况应该也是可以的吧。
----------------------------------------------
-
作者:
男 ke8880 (ke8880) ★☆☆☆☆ -
普通会员
2019/2/28 13:34:52
41楼: 回楼上,我这边测试不行。
----------------------------------------------
-
作者:
男 ke8880 (ke8880) ★☆☆☆☆ -
普通会员
2019/2/28 13:37:43
42楼: 这是我做一个最简单的Demo,我在两台机上测试都有问题,请大家帮我看看问题到底出在哪里,谢谢!!
此帖子包含附件:ke8880_2019228133742.rar 大小:2.49M
----------------------------------------------
-
作者:
男 earthsbest (全能中间件) ▲▲▲▲△ -
普通会员
2019/2/28 13:42:56
43楼: 测试楼上的代码 D10.3.1+win10 没问题
----------------------------------------------
Delphi4Linux Delphi三层/FireDAC 技术群:734515869 http://www.cnblogs.com/rtcmw
作者:
男 ke8880 (ke8880) ★☆☆☆☆ -
普通会员
2019/2/28 13:49:23
44楼: 我要抓狂!!!!
----------------------------------------------
-
作者:
男 ke8880 (ke8880) ★☆☆☆☆ -
普通会员
2019/2/28 13:52:03
45楼: 我的测试环境是10.2.3 + win10(64bit),也按39楼 he_19_79的建议更改过区域语言设置,不起效
----------------------------------------------
-
作者:
男 earthsbest (全能中间件) ▲▲▲▲△ -
普通会员
2019/2/28 14:04:39
46楼: D10.2.3 ,D10.1 都存在楼主的问题。
用10.3吧,这就是升级新版的意义。
----------------------------------------------
Delphi4Linux Delphi三层/FireDAC 技术群:734515869 http://www.cnblogs.com/rtcmw
作者:
男 he_19_79 (he) ▲▲▲▲▲ -
普通会员
2019/2/28 14:40:10
47楼:   NewValue := '电影喜剧之王';
  FDQuery1.SQL.Clear;
  FDQuery1.SQL.Text := 'update fmclip set caption=:caption where id=:id';

  FDQuery1.Params.Clear;
  FDQuery1.Params.CreateParam(ftString,'caption',ptInput);
  FDQuery1.Params.CreateParam(ftInteger,'id',ptInput);

  FDQuery1.ParamByName('caption').Value := NewValue;
  FDQuery1.ParamByName('id').AsInteger := 1;
  FDQuery1.ExecSQL;

  ShowMessageFmt('已向字段caption中写入字符串“%s”。', [NewValue]);
----------------------------------------------
-
作者:
男 ke8880 (ke8880) ★☆☆☆☆ -
普通会员
2019/2/28 14:59:25
48楼: 谢谢he_19_79的回复!!

加入以下三行后,用.AsString,不用.Value也没问题了。
  FDQuery1.Params.Clear;
  FDQuery1.Params.CreateParam(ftString,'caption',ptInput);
  FDQuery1.Params.CreateParam(ftInteger,'id',ptInput);

但我的疑惑时为什么原来的代码会出错,一定要通过变通的方法来解决吗?

对了,原代码在你那边执行时有这个问题吗?
----------------------------------------------
-
作者:
男 earthsbest (全能中间件) ▲▲▲▲△ -
普通会员
2019/2/28 15:02:41
49楼:   NewValue := '电影喜剧之王1';
  FDQuery1.SQL.Text := 'update fmclip set caption=:caption where id=:id';
  FDQuery1.Prepare;
  FDQuery1.ParamByName('caption').Value := NewValue;
  FDQuery1.ParamByName('id').AsInteger := 1;
  FDQuery1.ExecSQL;
这样也是可以。
----------------------------------------------
Delphi4Linux Delphi三层/FireDAC 技术群:734515869 http://www.cnblogs.com/rtcmw
作者:
男 he_19_79 (he) ▲▲▲▲▲ -
普通会员
2019/2/28 15:16:35
50楼: 原代码在我这边执行同你的错误一样,汉字减少一半。 我在“电影喜剧之王”改为“电影喜剧之王1234567890”,第二个显示为“电影喜剧之王1234”

我做DELPHI程序,已经10多年没在客户端写过任何SQL语句了,你的代码让我有些陌生。
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2019/2/28 15:20:45
51楼: 算了,说过多少次了,你不相信,你继续活该吧。
试了下,你的 DMEO,改连接参数,是解决不了的。
但是,改代码可以。
此帖子包含附件:
PNG 图像
大小:107.9K
----------------------------------------------
(C)(P)Flying Wang
作者:
男 earthsbest (全能中间件) ▲▲▲▲△ -
普通会员
2019/2/28 15:27:28
52楼: 可能是FB太小众了,以致于这bug存活了几个版本之久,直到10.3才修复了。
----------------------------------------------
Delphi4Linux Delphi三层/FireDAC 技术群:734515869 http://www.cnblogs.com/rtcmw
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2019/2/28 15:37:30
53楼: 不改代码就升级吧。
10.3.2 不错。
----------------------------------------------
(C)(P)Flying Wang
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行171.875毫秒 RSS