DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: sprblck
今日帖子: 11
在线用户: 21
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 gengyonghui (gyh) ★☆☆☆☆ -
普通会员
2017/9/20 17:08:53
标题:
Delphi(英文操作系统下)查询SQL server(中文Chinese_PRC_CI_AS编码), TEXT内容乱码 浏览:1080
加入我的收藏
楼主: 大家好,
问题描述:
Delphi在Win7英文环境(或者语言和区域的non-Unicode程序语言选项为"English")时,从SQLServer 2008中文字符集数据库下,查询出来的
CREATE TABLE T_CLOB(id int NULL, name text COLLATE Chinese_PRC_CI_AS NULL);
<
id, name
9 中国
>
为乱码,分析半天仍旧找不出解决办法。除非把操作系统的非unocode程序语言改为中文,这个依赖操作系统环境设置的方法法肯定没办法用。

分析1:分别用FireDAC的query和Unidac的query组件测试,均为乱码。
分析2:发现传送到客户端的原始字节为"中国"的GBK编码。
分析3:Navicat Premium查询出来的中文都是正确的。它肯定用了某种数据库字符转unicode的方法,目前未知。

大家有没有好的办法?
----------------------------------------------
-
作者:
男 hujiacheng ( 旺财) ★☆☆☆☆ -
普通会员
2017/9/20 19:54:20
1楼: 程序运行会以 当前系统ansi版本 。。剩下的。呵呵。
----------------------------------------------
免费的FTPhttps://download-installer.cdn.mozilla.net/pub/firefox/releases/43.0/win64/zh-CN/https://cc.embarcadero.com/Author/575019>http://delphi-z.ruhttps://download-installer.cdn.mozilla.net/pub/firefox/releases/43.0/win64/zh-CN/https://cc.embarcadero.com/Author/575019>http://delphi.icm.edu.pl/ftp/https://download-installer.cdn.mozilla.net/pub/firefox/releases/43.0/win64/zh-CN/https://cc.embarcadero.com/Author/575019>http://delphi-z.ruhttps://download-installer.cdn.mozilla.net/pub/firefox/releases/43.0/win64/zh-CN/https://cc.embarcadero.com/Author/575019
作者:
男 gengyonghui (gyh) ★☆☆☆☆ -
普通会员
2017/9/20 21:43:35
2楼: 问题是Navicat也是用delphi写的,它居然显示TEXT类型列的中文正常,估计有一种方法做处理。
另外,sql server官方客户端(.net写的),以及其它.net写的sql server开发工具,中文也显示正常。估计.net把所有字符串直接全转成unicode了。

如果dlephi现成的数据库组件都是这个德性的话,就无话可说了。为了用你一个delphi写的程序,让别人改客户端机器的non-unicode语言,基本上不现实。
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2017/9/20 21:46:40
3楼: 请问是 10.2.1 吗
----------------------------------------------
(C)(P)Flying Wang
作者:
男 gengyonghui (gyh) ★☆☆☆☆ -
普通会员
2017/9/20 21:47:27
4楼: 10.1.2的c++ builder测试的,delphi也是相同的问题。
----------------------------------------------
-
作者:
男 wr960204 (武稀松) ★☆☆☆☆ -
盒子活跃会员
2017/9/21 0:05:01
5楼: 如果数据库返回的确实是GBK编码的内码,应该是你的CodePage设置问题吧。
setCodePage(936)试试
----------------------------------------------
武稀松http://www.raysoftware.cn
作者:
男 gengyonghui (gyh) ★☆☆☆☆ -
普通会员
2017/9/21 0:30:19
6楼: setCodePage()没办法通用,我觉得应该有类似直接转为unicode的方法,否则Navicat不会一切正常。

我能想到的一个笨方法是,一旦碰到Text类型列,query里写成
select id, cast(name as NTEXT) as name
from t_clob;
select里强制转一下,就正常了。
----------------------------------------------
-
作者:
男 hujiacheng ( 旺财) ★☆☆☆☆ -
普通会员
2017/9/21 10:37:31
7楼: 你不告诉控件我的编码那么。  他只能用 英文系统的ansi来读取 当然乱码。
load(txt,国家编码)
----------------------------------------------
免费的FTPhttps://download-installer.cdn.mozilla.net/pub/firefox/releases/43.0/win64/zh-CN/https://cc.embarcadero.com/Author/575019>http://delphi-z.ruhttps://download-installer.cdn.mozilla.net/pub/firefox/releases/43.0/win64/zh-CN/https://cc.embarcadero.com/Author/575019>http://delphi.icm.edu.pl/ftp/https://download-installer.cdn.mozilla.net/pub/firefox/releases/43.0/win64/zh-CN/https://cc.embarcadero.com/Author/575019>http://delphi-z.ruhttps://download-installer.cdn.mozilla.net/pub/firefox/releases/43.0/win64/zh-CN/https://cc.embarcadero.com/Author/575019
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2017/9/21 10:55:07
8楼: 你居然没用 N 开头的 类型?
面对这种问题,建议问问微软,如何设置非 N 开头类型的字符串的默认输出编码。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 gengyonghui (gyh) ★☆☆☆☆ -
普通会员
2017/9/21 11:19:45
9楼: 谢谢大家关注,不继续跟了,我直接select cast(name as NTEXT)处理得了。
----------------------------------------------
-
作者:
男 wr960204 (武稀松) ★☆☆☆☆ -
盒子活跃会员
2017/9/21 11:41:08
10楼: 别人可以做是因为他根据字段类型知道CodePage是GBK也就是936了.
转Unicode的时候可以直接用这个转.
所以根源上还是要setCodePage.
你现在首要的是怎么获取文本字段CodePage也就是name text COLLATE Chinese_PRC_CI_AS NULL设置的CodePage是多少.
可以看下SQL语法COLLATIONPROPERTY,可以查询一个字段的内置CodePage是什么.
然后SetCodePage,如果不愿意COLLATIONPROPERTY,因为你知道是GBK也可以直接SetCodePage(936)

给你段的数据库引擎的部分代码,获取MSSQLserver的CodePage部分
function DetermineMSServerCodePage(const Collation: String): Word;
var
  Tmp: RawByteString;
begin
  Result := High(Word);
  Tmp := 'SELECT COLLATIONPROPERTY('+
    {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}AnsiQuotedStr(
      {$IFDEF UNICODE}UnicodeStringToASCII7{$ENDIF}(Collation), #39)+
    ', ''Codepage'') as Codepage';
  if (GetPlainDriver.dbcmd(FHandle, Pointer(Tmp)) <> DBSUCCEED) or
     (GetPlainDriver.dbsqlexec(FHandle) <> DBSUCCEED) or
     (GetPlainDriver.dbresults(FHandle) <> DBSUCCEED) or
     (GetPlainDriver.dbcmdrow(FHandle) <> DBSUCCEED) or
     (GetPlainDriver.dbnextrow(FHandle) <> REG_ROW) then
    CheckDBLibError(lcOther, Tmp)
  else
  begin
    ZSetString(PAnsiChar(GetPlainDriver.dbdata(FHandle, 1)), GetPlainDriver.dbDatLen(FHandle, 1), Tmp);
    Result := RawToInt(Tmp);
  end;
  GetPlainDriver.dbCancel(FHandle);
end;
----------------------------------------------
武稀松http://www.raysoftware.cn
作者:
男 gengyonghui (gyh) ★☆☆☆☆ -
普通会员
2017/9/21 11:48:56
11楼: 嗯,已经通过Query的类型映射发现了:
1. FireDAC里把映射规则从dtMemo->dtWideMemo, 一切正常了。
2. UniDAC里映射规则从Text->dtWideMemo有问题,估计是它自己的bug。
由于想利用unidac里的loader组件,所以没用FireDAC。
能自动处理的就让它自动处理,自己不折腾了。
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行78.125毫秒 RSS