DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: tkzcol
今日帖子: 4
在线用户: 1
导航: 论坛 -> 数据库专区 斑竹:liumazi,waterstone  
作者:
男 lsqtony (小白) ★☆☆☆☆ -
普通会员
2005/5/10 2:39:04
标题:
[奇??]汉字问题 浏览:1573
加入我的收藏
楼主: 我用delphi6写一个数据库管理软件,数据库用SQL server 2000,操作系统是XP sp2,出现一个很奇怪的问题,当我使用存储过程向数据库写数据时,若字符串中带有中文汉字字符,那么写到数据库中的时候SQL会将后面的N个字符截断(字符串长度并未越界),不管是纯中文字符串还是中英文混合,后面无论全是英文还是中英混合,都发生这种情况。

请教高手指点迷津,谢谢!

我有点怀疑是xp 与 sql 在全角汉字的处理上有不兼容的情况
我以前写的一个程序,在win2000写好了,拿到xp上用,中文的显示有时会出乱码,不过那个问题是控件自身的Bug
----------------------------------------------
-
作者:
男 ptgfr (ptgfr) ★☆☆☆☆ -
盒子活跃会员
2005/5/10 10:02:03
1楼: select unicode word
----------------------------------------------
to be ,not to be, is life!
until now, I still study life....
作者:
男 lsqtony (小白) ★☆☆☆☆ -
普通会员
2005/5/10 14:31:23
2楼: 具体怎么用呢?
是在SQL中调还是在XP中设置?还是在delphi中???
谢谢赐教!
----------------------------------------------
-
作者:
男 lsqtony (小白) ★☆☆☆☆ -
普通会员
2005/5/10 19:52:26
3楼: 在SQL中没有select unicode word这条语句啊?
我把原来的varchar换成了nvarchar也还是出现同样的问题
----------------------------------------------
-
作者:
男 ptgfr (ptgfr) ★☆☆☆☆ -
盒子活跃会员
2005/5/11 8:28:50
4楼: 我的意思是说将资料库内的语系改成UNICODE,
并不是指SQL语法。
还有你的资料栏位长度是否正确,
例如栏位长度20,结果你给资料23,那麽超过20的部份会自动被CUT掉。
至於为什麽要选UNICODE,
是把字串无论大小写或汉英文字都会自动把它当做2BYTE....

不过,小弟在想你的问题,应该是在栏位长度!!
----------------------------------------------
to be ,not to be, is life!
until now, I still study life....
作者:
男 ptgfr (ptgfr) ★☆☆☆☆ -
盒子活跃会员
2005/5/11 11:03:44
5楼: 表中存放中文的字段的數據類型全部換成unicode
也就是說全部換成nchar,nvarchar,ntext的.
然後存儲時將要存的字符前面加上N
如:

insert into yourTable (a1) values(N'內容');
----------------------------------------------
to be ,not to be, is life!
until now, I still study life....
作者:
男 lsqtony (小白) ★☆☆☆☆ -
普通会员
2005/5/12 17:25:53
6楼: 我的栏位长度没有问题
比如:我定义了nvarchar(32)的字段
在存储delphi6传过来的'abcdefg'没有任何问题
在存储delphi6传过来的'一二三'就在数据库中只写'一 '
我怀疑是xp与sql之间在unicode字符集的使用上存在差异
我在网上找到一些资料,说sql用的是unicode格式 的 ucs-2 标准
delphi用的是ansi 格式,xp用的是unicode格式 的 utf-8 (or utf-16 ??)

我发现的问题尽在xp sp2 + delphi6 + sql2000 这种情况下发生
在win2000中就没有此问题出现
----------------------------------------------
-
作者:
男 lsqtony (小白) ★☆☆☆☆ -
普通会员
2005/5/12 17:36:51
7楼: (当然我也试过'一二三a'传入后被截成'一二 ',我所谓的“截断”并非真正意义上的删除了,我在打开数据表是发现中文字符串的后面好像有一个非显示字符[未必是空格])

我发现系统自动截断字符的长度一般不会超过原长度的一半
所以我现在针对这种问题用了一个很笨的办法
我在用delphi向sql2000传'一二三'时,在其后加上若干个英文字符
然后在sql的存储过程中减调附加的英文字符,(当然,有些英文字符已被系统自行截断)

我这办法是一时应急的,还希望ptgfr大大指导我根除这个问题
----------------------------------------------
-
作者:
男 lsqtony (小白) ★☆☆☆☆ -
普通会员
2005/5/12 17:39:12
8楼: 在 SQL Server 上儲存 UTF-8 的資料
http://support.microsoft.com/kb/232580/zh-tw
----------------------------------------------
-
作者:
男 ptgfr (ptgfr) ★☆☆☆☆ -
盒子活跃会员
2005/5/13 10:56:49
9楼: 小弟是没在WINXP灌过SQL,
因为习惯用WIN2K,所以没遇过你所说的问题,
但若是UINCODE问题,UNICODE2与UINOCODE8,
那么只需将资料转换
上面那一微软的网址不是说:
在 Windows NT 或 Windows 2000 上,可以使用 Win32 函数 MultiByteToWideChar 及 WideCharToMultiByte,将常数 CP_UTF8 (65001) 当作函数的第一个参数来传递,以将 UTF-8 转换到 UCS-2 或从 UCS-2 转换到 UTF-8。 

那么在WINXP应也是相同的方式


function UnicodeEncode(Str:string;CodePage:integer):WideString;
var
  Len:integer;
begin
  Len:=Length(Str)+1;
  SetLength(Result,Len);
  Len:=MultiByteToWideChar(CodePage,0,PChar(Str),-1,PWideChar(Result),Len);
  SetLength(Result,Len-1); //end is #0
end;

function UnicodeDecode(Str:WideString;CodePage:integer):string;
var
  Len:integer;
begin
  Len:=Length(Str)*2+1;  //one for #0
  SetLength(Result,Len);
  Len:=WideCharToMultiByte(CodePage,0,PWideChar(Str),-1,PChar(Result),Len,nil,nil);
  SetLength(Result,Len-1);
end;

function Gb2Big5(Str:string):string;
begin
  SetLength(Result,Length(Str));
  LCMapString(GetUserDefaultLCID,LCMAP_TRADITIONAL_CHINESE,
    PChar(Str),Length(Str),
    PChar(Result),Length(Result));
    Result:=UnicodeDecode(UnicodeEncode(Result,936),950);
    //Result:=UnicodeEncode(Result,936);
end;

function Big52Gb(Str:string):string;
begin
  Str:=UnicodeDecode(UnicodeEncode(Str,950),936);
  SetLength(Result,Length(Str));
  LCMapString(GetUserDefaultLCID,LCMAP_SIMPLIFIED_CHINESE,
    PChar(Str),Length(Str),
    PChar(Result),Length(Result));
end;

//unicode 专用字串转换函数
function WideStringToString(const ws: WideString; codePage: Word): AnsiString;
var
  l: integer;
begin
  if ws ='' then
    Result :=''
  else
  begin
    l := WideCharToMultiByte(codePage,
      WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,
      @ws[1], - 1, nil, 0, nil, nil);
    SetLength(Result, l - 1);
    if l > 1 then
      WideCharToMultiByte(codePage,
        WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,
        @ws[1], - 1, @Result[1], l - 1, nil, nil);
  end;
end; { WideStringToString }

{:Converts Ansi string to Unicode string using specified code page.
  @param   s        Ansi string.
  @param   codePage Code page to be used in conversion.
  @returns Converted wide string.
}
function StringToWideString(const s: AnsiString; codePage: Word): WideString;
var
  l: integer;
begin
  if s ='' then
    Result :=''
  else
  begin
    l := MultiByteToWideChar(codePage, MB_PRECOMPOSED, PChar(@s[1]), - 1, nil, 0);
    SetLength(Result, l - 1);
    if l > 1 then
      MultiByteToWideChar(CodePage, MB_PRECOMPOSED, PChar(@s[1]),
        - 1, PWideChar(@Result[1]), l - 1);
  end;
end; { StringToWideString }



//GetWinDir是自定义函数,起功能是找出Windows\System\的路径.
function GetWinDir: String;
var
Buf: array[0..MAX_PATH] of char;
begin
GetSystemDirectory(Buf, MAX_PATH);
Result := Buf;
if Result[Length(Result)]<>'\' then Result := Result + '\';
end;
----------------------------------------------
to be ,not to be, is life!
until now, I still study life....
作者:
男 lsqtony (小白) ★☆☆☆☆ -
普通会员
2005/5/13 21:32:57
10楼: 谢谢哦,我再研究一下。
现在在准备毕业论文,所以没什么时间
但很感谢你给我的提示,我会把这个问题搞定的
谢谢啦!!
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行69.33594毫秒 RSS