数据库中出现问号乱码的处理办法?
(2009-11-02 11:21:17)
标签:
杂谈 |
分类: .NET学习 |
解决的方法是:
update
[RentHouse].[dbo].[rh_reHouseInfo]
set projName=replace(projName,right(projName,1),'')
where ASCII(right(projName,1))=0x3f
方法的来源是:
http://www.diybl.com/course/7_databases/sql/sqlServer/2007921/72303.html
方法的产生原因是:
最近在处理客户的FTP下来的资料,出现如题的问题
txt文本里有如下记录:
广东省某某某某某某某某某公司-IC卡,100,100
广东省某某某某某某某某公司-IC?100,100
问题,下面这行的分隔符不见了,造成数据无法导入本地SQL2000
这个字段类型是varchar(30),这是最近的文档资料,但我发现导出的资料有超过30长度的。证明这个字段现在只是修改了文档资料为30长度,而数据库必然是大于30的,只是从其它工单表里转入资料时作了切断来满足现在文档的要求,否则也不可能完整存放长度大于30的字符串(第一行)。
而这个切断就出现了问题,其实我们看到的问号,并非是英文的问号,而是半个汉字与逗号的结合造成的乱码。
所以总结一下就是:数据长度刚好30,而且英文字符的数量是奇数,并且以汉字结尾。
当然,如果是以英文结束并切断英文部分,是不会造成这个问题的;如果英文字符数量是偶数也没问题。
彻底解决方法:
这个问题的澈底解决方法是不要作切断,否则肯定会出现或多或少的问题。而至于要完整的切断一个中文,在处理效率上不现实。当然这是程序的问题了。
折衷的解决方法:
1. 本地文本替换问号为逗号,但不一定保险。因为目前除问号问题外,还出现了数据折行显示,甚至跳过几行等问题,其归根结底是中文切字造成不可见字符造成的。而且这个没什么规律。
因为我们虽然在notepad里看到的是问号"?",并且可以替换,但是编程来替换就不行,因为末字符是ascii>127的,而且你无法判断是半个字符,因为汉字就是两个半个字符组合而成,除非用我上面用黑体显示的那个规律来判断之。(与notepad里能看到问号是两码事)
2. 本地表加宽成varchar(40),导出是增加一个“A-Z”的字符,如果后面有半个字符则结合成一个字或者问号,从而不会与逗号结合。如果没有半个字符则显示出这个英文,影响也不大。
导出时选择用一条sql语句来筛选:select id,name=name+'A',price from tab_name where 1=1
我在sql2000里测试增加一个'A':IP专?3269334变成了: IP专蟌,3269334
如果末尾加英文的空格,显然比较贴切,有半个字符的显示为问号,但不吃掉逗号,而正常的记录只是多一个空格出来,完全不影响实际上使用。(推荐)
select id,name=name+' ',price from tab_name where 1=1
IP专?3269334 变成了: IP专?,3269334
当然聪明的人能想到,先在末尾添加一个字符,再用left(name,len(name)-1)来处理也是可以的,因为left是基于一个完整的字符,英文算一个,汉字也算一个。
select id,name=left(name+'A ',len(name+'A')-1),price from tab_name where 1=1
(结果非常完美)
当然还有人认为不用添加一个字符,直接切掉末尾字符,当然没问题的字段也会被切掉一个,当然不可以。
3. 判断长度为30而且英文字符数为奇数,则切断末尾的半个汉字。这个方法太费劲。而且这种方法不是数据库维护人员能做到的。(简直没必要费这个劲)
4. 在导出时用sql语句把字段转换成nvarchar(30),我在sql2000里测试ok.
select
id,name=cast(name
即说2,4的方法是可行的。windowxp+sql2000里我测试过。其它DBsys和OS未作测试。