zoukankan      html  css  js  c++  java
  • sql server字符集

    今天需要修改机器A中的sql server2008 R2的表里一个姓名字段,于是直接select * from tableName  where name='张三',发现虽然表中有这个张三的记录,但是却查不出来,于是换一个机器B新建一个同类型的nvarchar字段一试可以查出,想想估计是字符集出问题了,查看B中的字符集是Chinese_PRC_CI_AS,查看A是Latin1_General_CI_AS,于是搜索“sqlserver 字符集 查询中文”关键字,遂找到可以使用select * from tableName  where name=N'张三'这种形式查询,一试果然,于是搜索其中详细信息,得如下一篇,遂写一博记之:

    1. 字符集是支持双字节的字符集如中文字符集(Collation name为Chinese_PRC_CI_AS)

    <1>. 定义varchar(2)

       (1) 正式表
        总结:在中文字符集下,定义varchar(x),
         不论使用不使用N'',英文字符都占1个字节,即可以存x个英文字符;
         不论使用不使用N'',中文字符都占2个字节,即可以存(x / 2)个中文,select结果为汉字本身,不是乱码;
        
       (2) 临时表
        总结:在中文字符集下,定义varchar(x),
         和正式表表现一样;
      
    <2>. 定义nvarchar(2)

       (1) 正式表
        总结:在中文字符集下,定义nvarchar(x),
         不论使用不使用N'',英文字符都占2个字节,即可以存x个英文字符;
         不论使用不使用N'',中文字符都占2个字节,即可以存x个中文,select结果为汉字本身,不是乱码;
        
       (2) 临时表
        总结:在中文字符集下,定义nvarchar(x),
         和正式表表现一样;
        
    <3>. 类型为varchar时,长度 x 和 datalength()对应,都指字节大小;
         英文len() = datalength();
         中文len() = datalength() / 2;
        
        类型为nvarchar时,长度 x 和 len()对应,都指字符长度;
       
    2. 字符集是支持单字节的字符集如拉丁字符集(Collation name为Latin1_General_CI_AS)
      
    <1>. 定义varchar(2)

       (1) 正式表
        总结:在英文字符集下,定义varchar(x),
         不论使用不使用N'',英文字符都占1个字节,即可以存x个英文字符;
         不论使用不使用N'',中文字符都占1个字节,即可以存x个中文,但只保存前半截中文编码,所以select结果为乱码;
         (特殊:如果使用N'',此时插入的字符数最大为4000)
         英文和中文 len() = datalength();
        
       (2) 临时表
        总结:在英文字符集下,定义varchar(x),
         不论使用不使用N'',英文字符都占1个字节,即可以存x个英文字符;
         不使用N''时,中文占1个字节,可以存x个汉字,但都只存入汉字前半截字符编码,显示为乱码;
         使用N''时,中文占2个字节,只可以存 x/2 个汉字,没有乱码,取出仍为汉字,说明在英文字符集下通过使用N''是可以保存汉字的;
        
         除用N''保存的中文外,其余英文和中文 len() = datalength();
         用N''保存的中文字符len() = datalength() / 2;
        
    <2>. 定义nvarchar(2)

       (1) 正式表
        总结:在英文字符集下,定义nvarchar(x),
         不论使用不使用N'',英文字符都占2个字节,即可以存x个英文字符;(注意每个字符比varchar用的空间大)
         不论使用不使用N'',中文字符都占2个字节,即可以存x个中文字符,
         但不使用N''只保存前半截中文编码,所以select结果为乱码;
         使用N''则保存和取出都为汉字本身;
        
       (2) 临时表
        总结:在英文字符集下,定义nvarchar(x),
         和正式表表现相同;
        
    <3>. 类型为varchar时,长度 x 和 datalength()对应,都指字节大小;
         (临时表中N''中文字符长度比较特殊;)
        类型为nvarchar时,长度 x 和 len()对应,都指字符长度;

    二、 使用归类
    抛开不常用的临时表不谈,只看正式表,再加上varchar和nvarchar类型的最大长度,得到以下经验:

    <1> 最大长度问题
       1. 在中文字符集下使用varchar,最大长度可定义8000,这个8000是指字节数(datalength()),即最大可以保存8000个英文字符,4000个中文字符;
        特殊:若存入字符N'a',则最大能保存4000个字符,但其所占空间为4000字节;
       2. 在中文字符集下使用nvarchar,最大长度可定义4000,这个4000是指字符个数(len()),即最大可以保存4000个英文字符,4000个中文字符;

       3. 在英文字符集下使用varchar,最大长度可定义8000,这个8000是指字节数(datalength()),由于中文英文都保存为1字节,故最大可以保存8000个英文、中文字符;
       4. 在英文字符集下使用nvarchar,最大长度可定义4000,这个4000是指字符个数(len()),即最大可以保存4000个英文字符,4000个中文字符;
    <2> 文字显示问题
       1. N''要和数据类型nvarchar, nchar一起使用,如果对varchar, char字段类型强制使用N'',则会产生一些特殊现象,甚至无法控制;
       2. 在英文字符集下,想要保存特殊符号字符、中文等双字节字符,在定义表结构时要使用nvarchar或者nchar,在保存时要用N'';
       3. 在中文字符集下,数据库系统缺省已经可以保存特殊符号字符、中文等双字节字符。即使用不使用N'',都按双字节处理。但为了统一期间建议:
        在定义表结构时如果使用nvarchar或者nchar,在保存时要用N'',
        在定义表结构时如果使用varchar和char,此时不要使用N''操作;
       4. SUBSTRING ( expression , start , length )
        length:是一个整数,指定子串的长度(要返回的字符数或字节数)。
        中文字符集中按字符数取;
        英文字符集中,char, varchar按字节数取,nchar, nvarchar按字符数取;

  • 相关阅读:
    ClientDataSet 心得
    TClientDataSet中关于TField、TFieldDef动态创立字段的应用
    Delphi CxGrid 汇总(4)
    Delphi CxGrid 汇总(3)
    Delphi CxGrid 汇总(2)
    Delphi cxGrid使用汇总(一)
    修改后的SQL分页存储过程,利用2分法,支持排序
    字符串操作之格式化
    关于 cxGrid 的过滤问题
    cxGrid实现取消过滤和排序后定位到首行(单选和多选)
  • 原文地址:https://www.cnblogs.com/zhangxu724100/p/2861768.html
Copyright © 2011-2022 走看看