导航:
论坛 -> DELPHI技术
斑竹:liumazi,sephil
作者:
2019/2/25 12:33:57
标题:
求助:FireDAC中文字符串储存到数据库时长度变短!!
浏览:3404
加入我的收藏
楼主:
Delphi 10.2.3用FireDAC连接Firebird 2.5,中文字符串写入数据库后长度变成原来的一半,比如“中国”存入的只有“中”。请问如何设置解决这个问题??谢谢!!
----------------------------------------------
-
作者:
2019/2/25 12:40:28
1楼:
不知道啊。 我们的很正常。 反正就是各种参数。
----------------------------------------------
(C)(P)Flying Wang
作者:
2019/2/25 13:26:46
2楼:
你数据库的字段长度检查一下,还有客户端界面的数据控件FieldList对应字段的长度也检查一下
----------------------------------------------
Everyone will to do best!
作者:
2019/2/25 13:39:27
3楼:
人家的意思是输入 2N 个 字符,保存和读取的结果是 N 个。这个多半不是长度设置问题。 就是 参数问题。
----------------------------------------------
(C)(P)Flying Wang
作者:
2019/2/25 14:01:36
4楼:
客户端的字段长度如果小于数据库对应字段的长度,存储时,会自动截断,而不会报异常的!
----------------------------------------------
Everyone will to do best!
作者:
2019/2/25 14:18:52
5楼:
那么楼上的请问。 我保存 你好中国。结果读取到 你好。 同一个字段,我保存,楼上。读取到 楼。 那么这个字段,长度是多少。
----------------------------------------------
(C)(P)Flying Wang
作者:
2019/2/25 14:28:20
6楼:
是没了一半,还是没了最尾一个字(那是行尾操作符转换问题). 还有是没了那部分,会不会是繁简通用的保留,单纯简体的缺了(那是数据库编码定义问题).
----------------------------------------------
-
作者:
2019/2/25 15:54:18
7楼:
谢谢各位的热心解答!是每次保存时只存一半的字符串。待储存的字符串长度小于数据库字段的设定值。
----------------------------------------------
-
作者:
2019/2/25 16:01:58
8楼:
建议楼主把demo发上来,估计很快可以找到问题甚至解决了,楼主提供的信息太有限,大伙都只能猜。
----------------------------------------------
Delphi4Linux Delphi三层/FireDAC 技术群:734515869 http://www.cnblogs.com/rtcmw
作者:
2019/2/25 16:49:32
9楼:
晕死,字段的长度不一致,就调成一致啊!以数据库字段长度为准! 如果你客户的内容确实有需要超过数据库字段长度,那就先调整数据库字段的长度,客户端的字段长度再调成跟数据库的字段长度一致,就可以了! (FireDAC组件的字符型字段长度,一般等于数据库字段长度+1)
----------------------------------------------
Everyone will to do best!
作者:
2019/2/25 17:08:29
10楼:
楼上的晕死你吧。 假设本数据库,就 TMD 一个表,表名叫 TMD。 就 TMD 一个字段。类型 NVarChar 长度 20,叫 TEST。 结果 你写一个 你好中文,打开一看,就只有 你好。 你 又写一个 中文,打开一看,就只有 中。
----------------------------------------------
(C)(P)Flying Wang
作者:
2019/2/25 23:40:13
11楼:
估计是数据库问题。我用Firedac连接sqlserver/sqlanywhere没有问题。
----------------------------------------------
-
作者:
2019/2/26 4:17:38
12楼:
储存的字符串长度小于数据库字段的设定值...那当然啰!若储存的长于数据库设定,叫数据库如何做好? 容不下当然要删去后面的内容. 还有,中文字要用上2个 char, 别当作一字一 char 去存.
----------------------------------------------
-
作者:
2019/2/26 9:08:02
13楼:
不是firedac的锅,中间件那里检查下吧,肯定是代码出了问题。 应该是哪个函数/过程(也可能是数据库里的)有个长度参数, 然后玩砸了呗
----------------------------------------------
-
作者:
2019/2/26 9:54:55
14楼:
9、12、13 楼 请认真阅读 楼主的内容。 同时也请认真阅读 5 楼 10 楼的 内容。 我觉得,大家应该都小学毕业了吧。 语文不至于是火星版的吧! 小学语文和小学数学 都没学好,搞个屁的软件开发。\ 连问题描述都理解不了。怎么去理解客户需求。 怎么去和你的领导沟通。
----------------------------------------------
(C)(P)Flying Wang
作者:
2019/2/26 11:25:41
15楼:
我琢磨着,楼主既然会玩firebird,应该不至于不晓得字段长度这个问题。大家既然对这个这么关注,也是担心这种小众数据库是不是可靠的。
----------------------------------------------
-
作者:
2019/2/26 12:22:45
16楼:
字符集问题?我有个小项目用的是也是firebird+firedac,字符集是utf8,一点问题也没有
----------------------------------------------
-
作者:
2019/2/26 14:59:35
17楼:
楼主贴一下表字段的定义呗!有可能是数据库字段定义的是Ansi,存的是Unicode?瞎猜……
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河) 博客挂了……
作者:
2019/2/26 15:07:41
18楼:
iamdream 说过了,楼主没回应,而且喷子在喷是文盲啊。 我看到重点是楼主在7楼的最后一句,相当有趣。 ”待储存的字符串长度小于数据库字段的设定值”--那不是当然吗? 储存的长度怎可能长于数据库设定值?
----------------------------------------------
-
作者:
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)中。
此帖子包含附件: 大小: 28.5K
----------------------------------------------
-
作者:
2019/2/26 16:58:29
21楼:
数库库字段设置
此帖子包含附件: 大小: 16.4K
----------------------------------------------
-
作者:
2019/2/26 17:01:29
22楼:
To mochizuki: 我改为字符集为UTF8或GB_2312,仍有问题
----------------------------------------------
-
作者:
2019/2/26 17:03:27
23楼:
另外,我把数据库组件FireDAC换成UniDAC或Zeoslib,同样的代码,没有这个问题
----------------------------------------------
-
作者:
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
作者:
2019/2/26 19:53:47
25楼:
To earthsbest (全能中间件): 谢谢。这个我改过,不起作用。
----------------------------------------------
-
作者:
2019/2/26 21:15:55
26楼:
FDConnection -> Params -> CharLenMode改为clmBytes试试看
----------------------------------------------
-
作者:
2019/2/27 8:35:57
27楼:
如果英文可以正常写入,中文不行的话,很可能是数据库或数据库表字段的字符集定义是英文单字节,两者都要确认。不是Firedac的连接设定,而是创建数据库时定义的字符集。 如果数据库的Charset是None的话,恐怕表的数据集指定成中文也不管用
----------------------------------------------
-
作者:
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
作者:
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;
----------------------------------------------
-
作者:
2019/2/27 12:10:40
30楼:
另外,如果用firebird是为了免费,那还不如用mysql或mongodb这类比较通用、功能也比较强的数据库
----------------------------------------------
-
作者:
2019/2/27 12:37:58
31楼:
FireBird 一点问题都没有。比你们的 mysql 好多了。 的确没有 N开头的。 所以,我们后面就设置了 Charset 为 UTF8。这样就安全了。
----------------------------------------------
(C)(P)Flying Wang
作者:
2019/2/27 13:17:25
32楼:
首先,我从来不用mysql和mongodb,其次,我也不相信FirdBird比mysql好。
----------------------------------------------
-
作者:
2019/2/27 15:01:15
33楼:
DC.RS.ParamByName('labelcaption').AsMemo := pData.ItemCaption; 百分百解决问题
----------------------------------------------
-
作者:
2019/2/27 18:09:46
34楼:
To bluestorm8: 谢谢!!我也是这样的代码,但我两台机式测试过都有问题。Windows 10 64bit,Delphi 10.2.3 Firebird 2.5.7 32bit。
----------------------------------------------
-
作者:
2019/2/27 18:12:51
35楼:
To lzhg_kn (lzhg_kn): 如你所言,这个真可以,但换成AsString问题依然,另外,如果写入的字符串是全英文或数字,没问题; 代码、数据库、Firebird版本都不变,仅换成UniDAC、或Zeoslib组件,则没问题,太奇怪了!难道是FireDAC有Bug,但你们的却都是正常的。
----------------------------------------------
-
作者:
2019/2/27 18:56:22
36楼:
屁的 BUG . 说了多少遍了。要设置参数。 我们的配置是默认不需要参数的。 你的配置,不是我们那些标准的 全球兼容 的。你的不兼容 所以,需要特殊配置。
----------------------------------------------
(C)(P)Flying Wang
作者:
2019/2/27 19:12:26
37楼:
你看我贴的图,没有特殊参数
----------------------------------------------
-
作者:
2019/2/27 19:20:32
38楼:
字段字符集改成unicode,连接时也改成unicode.
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河) 博客挂了……
作者:
2019/2/27 21:07:36
39楼:
是不是你所用的Windows系统的字符集导致的?(我觉得是FireDAC数据驱动的错)。 RO DA也出现过这种错,保存Stream时会漏字符。 在控制面板-时钟、语言、区域中选择“区域”,选择“管理” , 把“非Unicodet程序的语言”-“更改区域语言设置”改变一下(如改成英语,不行时再改成简体等),试试。(服务器同本机都改变试试)
----------------------------------------------
-
作者:
2019/2/28 8:12:58
40楼:
估计直接写成DC.RS.ParamByName('labelcaption').Value := pData.ItemCaption;就可以了。 我的例子里面是可以的,估计你的情况应该也是可以的吧。
----------------------------------------------
-
作者:
2019/2/28 13:34:52
41楼:
回楼上,我这边测试不行。
----------------------------------------------
-
作者:
2019/2/28 13:37:43
42楼:
这是我做一个最简单的Demo,我在两台机上测试都有问题,请大家帮我看看问题到底出在哪里,谢谢!!
----------------------------------------------
-
作者:
2019/2/28 13:42:56
43楼:
测试楼上的代码 D10.3.1+win10 没问题
----------------------------------------------
Delphi4Linux Delphi三层/FireDAC 技术群:734515869 http://www.cnblogs.com/rtcmw
作者:
2019/2/28 13:49:23
44楼:
我要抓狂!!!!
----------------------------------------------
-
作者:
2019/2/28 13:52:03
45楼:
我的测试环境是10.2.3 + win10(64bit),也按39楼 he_19_79的建议更改过区域语言设置,不起效
----------------------------------------------
-
作者:
2019/2/28 14:04:39
46楼:
D10.2.3 ,D10.1 都存在楼主的问题。 用10.3吧,这就是升级新版的意义。
----------------------------------------------
Delphi4Linux Delphi三层/FireDAC 技术群:734515869 http://www.cnblogs.com/rtcmw
作者:
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]);
----------------------------------------------
-
作者:
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); 但我的疑惑时为什么原来的代码会出错,一定要通过变通的方法来解决吗? 对了,原代码在你那边执行时有这个问题吗?
----------------------------------------------
-
作者:
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
作者:
2019/2/28 15:16:35
50楼:
原代码在我这边执行同你的错误一样,汉字减少一半。 我在“电影喜剧之王”改为“电影喜剧之王1234567890”,第二个显示为“电影喜剧之王1234” 我做DELPHI程序,已经10多年没在客户端写过任何SQL语句了,你的代码让我有些陌生。
----------------------------------------------
-
作者:
2019/2/28 15:20:45
51楼:
算了,说过多少次了,你不相信,你继续活该吧。 试了下,你的 DMEO,改连接参数,是解决不了的。 但是,改代码可以。
此帖子包含附件: 大小: 107.9K
----------------------------------------------
(C)(P)Flying Wang
作者:
2019/2/28 15:27:28
52楼:
可能是FB太小众了,以致于这bug存活了几个版本之久,直到10.3才修复了。
----------------------------------------------
Delphi4Linux Delphi三层/FireDAC 技术群:734515869 http://www.cnblogs.com/rtcmw
作者:
2019/2/28 15:37:30
53楼:
不改代码就升级吧。 10.3.2 不错。
----------------------------------------------
(C)(P)Flying Wang