精华内容
下载资源
问答
  • 1.在字节意义上:utf8和gbk他们之间区别是每一字节都是不同,每个汉字都有对应的utf8编码和gbk编码对应; 2.在字节个数上:utf8对应一个汉字是3个字节gbk对应一个汉字是两个字节。 本文是凭本人自己在实践中...

    最近公司搞个项目是要求对远程进行转码后发送的,这里就写一下我对utf8和gbk进行中文转换时候的一些肤浅理解:

    1.在字节意义上:utf8和gbk他们之间的区别是每一字节都是不同的,每个汉字都有对应的utf8编码和gbk编码对应;

    2.在字节个数上:utf8对应一个汉字是3个字节,gbk对应一个汉字是两个字节。

    本文是凭本人自己在实践中体会到的感想,如果哪里有问题,请多多提出您宝贵的意见,让我们共同学习、进步。

    展开全文
  • [目录]参考资料业务背景之前数据库的编码是 gbk,为了业务的国际化,需要把编码修改为 utf8由于 gbk utf8 对应汉字的存储字节不同,所以需要之前的字段做兼容性处理Oracal数据库当前字符编码查询sql:select ...

    [目录]

    参考资料

    业务背景

    之前数据库的编码是 gbk,为了业务的国际化,需要把编码修改为 utf8

    由于 gbk 和 utf8 对应汉字的存储字节不同,所以需要对之前的字段做兼容性处理

    Oracal数据库当前字符编码

    查询sql:select userenv('language') from dual;

    查询结果:SIMPLIFIED CHINESE_CHINA.ZHS16GBK

    f723beb83c1472c832f72823494884d6.png

    gbk 和 utf8 对应字节编码类型

    英文字节

    汉字字节

    gbk

    1

    2

    utf-8

    1

    3

    stringstrTmp="h";

    intascii=System.Text.Encoding.ASCII.GetBytes(strTmp).Length;

    intunicode=System.Text.Encoding.Unicode.GetBytes(strTmp).Length;

    intgbk=System.Text.Encoding.Default.GetBytes(strTmp).Length;

    intutf8=System.Text.Encoding.UTF8.GetBytes(strTmp).Length;

    Console.WriteLine("ascii-----:"+ascii);

    Console.WriteLine("unicode---:"+unicode);

    Console.WriteLine("gbk-------:"+gbk);

    Console.WriteLine("utf8------:"+utf8);

    Console.ReadKey();

    结果:

    ascii-----:1

    unicode---:2

    gbk-------:1

    utf8------:1stringstrTmp="汉";

    intascii=System.Text.Encoding.ASCII.GetBytes(strTmp).Length;

    intunicode=System.Text.Encoding.Unicode.GetBytes(strTmp).Length;

    intgbk=System.Text.Encoding.Default.GetBytes(strTmp).Length;

    intutf8=System.Text.Encoding.UTF8.GetBytes(strTmp).Length;

    Console.WriteLine("ascii-----:"+ascii);

    Console.WriteLine("unicode---:"+unicode);

    Console.WriteLine("gbk-------:"+gbk);

    Console.WriteLine("utf8------:"+utf8);

    Console.ReadKey();

    结果:

    ascii-----:1

    unicode---:2

    gbk-------:2

    utf8------:3

    修改思路

    从下表可知,gbk 和 utf8 英文都只占用1个字节

    gbk 1个汉字占用2个字节,utf8 占用3个,3/2=1.5

    编码类型

    英文字节

    汉字字节

    gbk

    1

    2

    utf-8

    1

    3

    如果之前的 gbk 编码类型长度为 255,修改为 utf8 后,对应类型长度应该为

    255*1.5 = 382.5

    为了更好的兼容,我们修改为之前长度的两倍 255*2

    使用 oracle dmu 得到需要扩容表和字段

    什么是 Oracle Database Migration Assistant for Unicode?Oracle Database Migration Assistant for Unicode (DMU) 是一款独特的下一代迁移工具,提供将数据库从传统编码迁移到 Unicode 的端到端解决方案。通过在整个迁移流程中为 DBA 提供指导并实现许多迁移任务的自动化,DMU 直观的用户界面极大简化了迁移流程并降低了对字符集迁移专业知识的要求。它采用可扩展的就地迁移架构,与传统的导出和导入迁移方法相比,可显著减少数据转换所需的工作和停机时间。对于迁移后的数据库和已经使用 Unicode 字符集的现有数据库,DMU 还提供了一种验证模式,可识别未正确用 Unicode 编码的数据,从而对数据库应用中的 Unicode 实现的潜在问题进行健康检查。

    从 2.1 版开始,DMU 与 Oracle GoldenGate 复制技术结合使用,支持近乎零停机时间的迁移模型。结合使用 DMU 与 GoldenGate 12.1.2.1.0 或更高版本,您可以设置这样一个迁移过程,利用 DMU 的数据准备和就地转换功能,利用 GoldenGate 复制迁移过程中生产系统上发生的增量数据更改,从而有效地消除停机时间窗口需求。

    思路

    功能大致如下

    1.全库扫描表字段,字段类型,字段值,字符编码

    2.把对应表的字符编码从 gbk 转换为 utf8,如果之前字段的长度能够存储对应内容,就通过

    3.如果之前字段的长度不能存储对应内容,比如存不下了,就会在 system.dum$exceptions 表里面添加对应表,行,列信息,这个字段就是需要扩展的字段

    7f82bea4dee2d8ede8c604a01705e671.png

    辅助查询

    查询表信息--查询表信息

    select*fromdba_objects

    whereupper(object_name)='Student'

    查询表对应的列信息--查询表对应的列信息

    select*fromdba_tab_columns

    whereTABLE_NAME='Student'

    查询兼容的异常信息--查询兼容的异常信息

    selectdecode(sde.type,

    2,

    'exceed column',

    4,

    'exceed datatype',

    8,

    'invalid')as"DMU_TYPE",

    sde.row_id,--表行Id

    sde.obj#, --表的Id

    sde.intcol# --表列Id

    fromsystem.dum$exceptions sde

    wheresde.obj# = 1301018 --表对象Id

    获取表对应行,列对应的值方法createorreplacefunctiondmu_data_detail_f(p_object_idinnumber,

    p_column_idinnumber,

    p_rowidinvarchar2)

    returnvarchar2is

    l_data_detail varchar2(4000);

    l_data_query_sql VARCHAR2(2000);

    l_column_name VARCHAR2(128);

    l_table_name VARCHAR2(128);

    l_owner_name VARCHAR2(128);

    begin

    selectdtc.column_name

    intol_column_name

    fromdba_objectsdo,dba_tab_columns dtc

    wheredo.object_name=dtc.TABLE_NAME

    anddo.OWNER=dtc.OWNER

    anddtc.COLUMN_ID=p_column_id

    anddo.object_id=p_object_id;

    selectobject_name,owner

    intol_table_name,l_owner_name

    fromdba_objects

    whereobject_id=p_object_id;

    l_data_query_sql:='select '||l_column_name||' from '||

    l_owner_name||'.'||l_table_name||

    ' where rowid='''||p_rowid||'''';

    --dbms_output.put_line(l_data_query_sql);

    execute immediate l_data_query_sql

    intol_data_detail;

    return(l_data_detail);

    enddmu_data_detail_f;

    查询对应表不兼容的字段-记录数少时使用--当查询结果记录数少时使用

    selectowneras"用户",

    object_nameas"对象名",

    object_typeas"对象类型",

    COLUMN_NAMEas"数据列",

    DATA_TYPEas"数据类型",

    DMU_TYPEas"扩展类型",

    dmu_data_detail_f(obj#, intcol#, row_id) as "例外数据"

    from(selectdo.owner,

    do.object_name,

    do.object_type,

    dto.COLUMN_NAME,

    dto.DATA_TYPE||'('||dto.DATA_LENGTH||')'as"DATA_TYPE",

    decode(sde.type,

    2,

    'exceed column',

    4,

    'exceed datatype',

    8,

    'invalid')as"DMU_TYPE",

    sde.row_id,

    sde.obj#,

    sde.intcol#

    fromsystem.dum$exceptions sde,

    dba_objectsdo,

    dba_tab_columns dto

    wheresde.obj# = do.object_id

    andsde.intcol# = dto.COLUMN_ID

    anddo.object_name=dto.TABLE_NAME

    anddo.OWNER=dto.OWNER

    andupper(do.object_name)=upper('&p_table_name')

    --andsde.type=&p_dmu_type

    orderbyOWNER,object_name,COLUMN_NAME,TYPE);

    查询对应表不兼容的字段-数据量大时使用select'用户.表','字段名称',字段名称,255data_length,cux_utf8_pub.count_byte_as_utf8(字段名称),rowid row_id

    from用户.表twhereexists(

    selectnull

    fromsystem.dum$exceptions sde,

    dba_objectsdo,

    dba_tab_cols dto

    wheresde.obj# = do.object_id

    andsde.intcol# = dto.internal_column_id

    anddo.object_name=dto.table_name

    anddo.owner=dto.owner

    anddo.owner='用户'

    anddto.column_name='字段名称'

    andupper(do.object_name)='表名称'

    andsde.row_id=t.rowid

    );

    修改 sql

    从上面得到对应的表和不兼容的字段,对应修改该字段的字段长度或类型即可,例如

    --=============================================

    --Author:luoma

    --Createdate:2019年4月9日15:48:25

    --Description:字符编码从SIMPLIFIED CHINESE_CHINA.ZHS16GBK修改为utf-8,所以对应字段要进行扩容

    --gbk和utf8英文都占用1个字符,gbk中文占用2个字符,utf8占用3个,所以对应字段需要扩容为之前的1.5倍,这里我们修改为2倍

    --=============================================

    alter tableStudent

    modifyNamevarchar2(383);

    字符串截取

    测试sql--=============================================

    --Author:luoma

    --Createdate:2019年4月11日10:50:24

    --Description:用utf8字符集截取对应表超过指定utf8编码长度的字符串

    --=============================================

    declare

    l_ret_var varchar2(32767);--存储需要截取的字符串

    l_var varchar2(3);--存储截取的单个字符串

    l_len number:=0;--用于已经截取的utf8字符总长度

    l_dump number:=0;--存储单个utf8字符长度

    p_lengthb number:=25;--需要截取的字符长度

    begin

    --获取超过指定用UTF8字符集计算字符串字节数的数据

    foritemin(selectno,namefromtest_v_hwhao1where(nvl(lengthb(name),0)-nvl(length(name),0))+nvl(lengthb(name),0)>p_lengthb)

    loop

    --初始化变量

    l_len:=0;

    l_ret_var:='';

    --处理超过指定长度的字段

    foriin1..length(item.name)

    loop

    --截取单个字符串

    l_var:=substr(item.name,i,1);

    --因为之前使用gbk编码,所以一个中文占用2个字符

    if(lengthb(l_var)=2)then

    --utf8一个中文字符长度为3

    l_dump:=3;

    else

    --utf8其它字符长度为1

    l_dump:=1;

    endif;

    --已经总共统计了多少个utf8字符长度

    l_len:=l_len+l_dump;

    --如果截取的长度还未达到需要截取的长度

    if(l_len<=p_lengthb)then

    --继续添加

    l_ret_var:=l_ret_var||l_var;

    endif;

    --如果截取的长度达到了需要截取的长度

    if(l_len>=p_lengthb)then

    --把截取后的长度修改到表字段

    update test_v_hwhao1

    setname=l_ret_var

    whereno=item.no;

    --提交修改

    commit;

    --退出循环

    exit;

    endif;

    endloop i;

    endloop;

    end;

    测试表

    测试完成后,结果应该为下图中红圈部分

    select * from test_v_hwhao1 order by no

    测试前

    f8f7f39d9391cb6772f553a017b4b5e0.png

    测试后

    f4b94631976bb767ebc3672c9393c40c.png

    cux_utf8_pubcreateorreplacepackagebody cux_utf8_pubis

    --用UTF8字符集计算字符串字节

    functioncount_byte_as_utf8(p_textinvarchar2)returnnumberis

    l_char_lenth number:=0;

    l_byte_lenth number:=0;

    begin

    l_char_lenth:=nvl(length(p_text),0);

    l_byte_lenth:=nvl(lengthb(p_text),0);

    return(l_byte_lenth-l_char_lenth)+l_byte_lenth;

    endcount_byte_as_utf8;

    --用UTF8字符集截取字符串,确保最后一位不是乱码

    functionsubstrb_use_utf8(p_textinvarchar2,p_lengthbinnumber)

    returnvarchar2is

    l_ret_var varchar2(32767);

    l_var varchar2(3);

    l_len number:=0;

    l_dump number:=0;

    begin

    if(count_byte_as_utf8(p_text)<=p_lengthb)then

    returnp_text;

    endif;

    foriin1..length(p_text)loop

    l_var:=substr(p_text,i,1);

    if(lengthb(l_var)=2)then

    l_dump:=3;

    else

    l_dump:=1;

    endif;

    l_len:=l_len+l_dump;

    if(l_len<=p_lengthb)then

    l_ret_var:=l_ret_var||l_var;

    endif;

    if(l_len>=p_lengthb)then

    returnl_ret_var;

    endif;

    endloop i;

    returnl_ret_var;

    endsubstrb_use_utf8;

    --用GBK字符集截取字符串,确保最后一位不是乱码

    functionsubstrb_use_gbk(p_textinvarchar2,p_lengthbinnumber)

    returnvarchar2is

    l_last_string1 varchar2(4000);

    l_last_string2 varchar2(4000);

    begin

    if(lengthb(p_text)<=p_lengthb)then

    returnp_text;

    endif;

    --截取逻辑

    if(length(substrb(p_text,p_lengthb,2))=1)then

    --截取少一位

    returnsubstrb(p_text,1,p_lengthb-1);

    else

    returnsubstrb(p_text,1,p_lengthb);

    endif;

    endsubstrb_use_gbk;

    procedure execute_substrb(p_ownerinvarchar2,

    p_table_nameinvarchar2,

    p_column_nameinvarchar2,

    p_debug_flaginvarchar2default'Y')is

    l_bakup_sql varchar2(4000);

    l_datafix_sql varchar2(4000);

    l_count_length_sql varchar2(4000);

    l_extend_sql varchar2(4000);

    g_max_length number:=4000;

    l_length number;

    begin

    --截断处理

    forcurin(selectt.rowid row_id,t.*,c.data_length

    fromcux_utf8_substr_list t,dba_tab_cols c

    wheret.table_name=c.table_name

    andt.owner=c.owner

    andt.column_name=c.column_name

    andc.data_type='VARCHAR2'

    andt.owner=nvl(p_owner,t.owner)

    andt.column_name=nvl(p_column_name,t.column_name)

    andt.table_name=nvl(p_table_name,t.table_name)

    andconvert_type='CUT')loop

    l_bakup_sql:='insert into cux_utf8_substr_bak

    (table_name, owner, column_name, bak_data, bak_date, data_row_id)

    select '''||cur.table_name||''','''||

    cur.owner||''','''||cur.column_name||''','||

    cur.column_name||',sysdate, t.rowid row_id from '||

    cur.owner||'.'||cur.table_name||

    ' t where exists (select null

    from system.dum$exceptions sde,

    dba_objects do,

    dba_tab_cols dto

    where sde.obj# = do.object_id

    and sde.intcol# = dto.internal_column_id

    and do.object_name = dto.table_name

    and do.owner = dto.owner

    and do.owner = upper('''||cur.owner||''')

    and dto.column_name = upper('''||

    cur.column_name||''')

    and upper(do.object_name) = upper('''||

    cur.table_name||''')

    and sde.row_id = t.rowid)';

    --dbms_output.put_line(l_sql);

    /*insert into cux_utf8_substr_bak

    (table_name, owner, column_name, bak_data, bak_date)

    select cur.table_name,

    cur.owner,

    cur.column_name,

    dmu_data_detail_f(obj#, intcol#, row_id),

    sysdate

    from system.dum$exceptions sde,

    dba_objects do,

    dba_tab_cols dto

    where sde.obj# = do.object_id

    and sde.intcol# = dto.internal_column_id

    and do.object_name = dto.table_name

    and do.owner = dto.owner

    and do.owner = upper(cur.owner)

    and dto.column_name = upper(cur.column_name)

    and upper(do.object_name) = upper(cur.table_name);*/

    l_datafix_sql:='update '||cur.owner||'.'||cur.table_name||

    ' t set '||cur.column_name||

    '=cux_utf8_pub.substrb_use_utf8('||cur.column_name||','||

    cur.data_length||

    ') where exists (select null

    from system.dum$exceptions sde,

    dba_objects do,

    dba_tab_cols dto

    where sde.obj# = do.object_id

    and sde.intcol# = dto.internal_column_id

    and do.object_name = dto.table_name

    and do.owner = dto.owner

    and do.owner = upper('''||cur.owner||''')

    and dto.column_name = upper('''||

    cur.column_name||''')

    and upper(do.object_name) = upper('''||

    cur.table_name||''')

    and sde.row_id = t.rowid)';

    if(p_debug_flag='N')THEN

    update cux_utf8_substr_list t

    sett.process_flag='P',

    t.process_date_start=sysdate,

    t.datafix_sql=l_datafix_sql,

    t.bakup_sql=l_bakup_sql

    whererowid=cur.row_id;

    execute immediate l_bakup_sql;

    execute immediate l_datafix_sql;

    update cux_utf8_substr_list t

    sett.process_flag='S',t.process_date_end=sysdate

    whererowid=cur.row_id;

    commit;

    else

    dbms_output.put_line('bakup:');

    dbms_output.put_line(l_bakup_sql);

    dbms_output.put_line('');

    dbms_output.put_line('datafix:');

    dbms_output.put_line(l_datafix_sql);

    endif;

    endloop cur;

    --扩展处理

    forcurin(selectt.rowid row_id,t.*,c.data_length

    fromcux_utf8_substr_list t,dba_tab_cols c

    wheret.table_name=c.table_name

    andt.owner=c.owner

    andt.column_name=c.column_name

    andc.data_type='VARCHAR2'

    andt.owner=nvl(p_owner,t.owner)

    andt.column_name=nvl(p_column_name,t.column_name)

    andt.table_name=nvl(p_table_name,t.table_name)

    andconvert_type='EXT')loop

    l_count_length_sql:='SELECT max(cux_utf8_pub.count_byte_as_utf8('||

    cur.column_name||')) from '||cur.owner||'.'||

    cur.table_name||' t'||

    ' where exists (select null

    from system.dum$exceptions sde,

    dba_objects do,

    dba_tab_cols dto

    where sde.obj# = do.object_id

    and sde.intcol# = dto.internal_column_id

    and do.object_name = dto.table_name

    and do.owner = dto.owner

    and do.owner = upper('''||cur.owner||''')

    and dto.column_name = upper('''||

    cur.column_name||''')

    and upper(do.object_name) = upper('''||

    cur.table_name||''')

    and sde.row_id = t.rowid)';

    execute immediate l_count_length_sql

    intol_length;

    if(l_length>g_max_length)then

    dbms_output.put_line(cur.owner||'.'||cur.table_name||'.'||

    cur.column_name||'扩展后的长度:'||l_length||

    '超过4000');

    update cux_utf8_substr_list t

    sett.process_flag='E',t.process_date_start=sysdate

    whererowid=cur.row_id;

    commit;

    continue;

    endif;

    l_extend_sql:='alter table '||cur.owner||'.'||cur.table_name||

    ' modify '||cur.column_name||' VARCHAR2('||

    l_length||')';

    l_bakup_sql:='alter table '||cur.owner||'.'||cur.table_name||

    ' modify '||cur.column_name||' VARCHAR2('||

    cur.data_length||')';

    if(p_debug_flag='N')THEN

    update cux_utf8_substr_list t

    sett.process_flag='P',

    t.process_date_start=sysdate,

    t.extend_sql=l_extend_sql,

    t.bakup_sql=l_bakup_sql

    whererowid=cur.row_id;

    execute immediate l_extend_sql;

    update cux_utf8_substr_list t

    sett.process_flag='S',t.process_date_end=sysdate

    whererowid=cur.row_id;

    commit;

    else

    dbms_output.put_line('extend sql:');

    dbms_output.put_line(l_extend_sql);

    dbms_output.put_line('bakup_sql:');

    dbms_output.put_line(l_bakup_sql);

    endif;

    endloop cur;

    endexecute_substrb;

    procedure get_quick_query_sql(p_ownerinvarchar2defaultnull,

    p_table_nameinvarchar2,

    p_column_nameinvarchar2defaultnull)is

    l_sql varchar2(4000);

    begin

    forcurin(selectdto.data_length,

    do.object_name,

    do.owner,

    dto.column_name,

    do.object_id,

    dto.internal_column_id

    fromdba_objectsdo,

    dba_tab_cols dto,

    cux_utf8_error_info cu

    wheredo.object_name=dto.table_name

    anddo.owner=dto.owner

    anddo.owner=cu.owner

    anddto.column_name=cu.column_name

    anddo.object_name=cu.table_name

    andcu.owner=nvl(upper(p_owner),cu.owner)

    andcu.table_name=upper(p_table_name)

    andcu.column_name=

    nvl(upper(p_column_name),cu.column_name))loop

    l_sql:='select '''||cur.owner||'.'||cur.object_name||

    ''','''||cur.column_name||''','||cur.column_name||' ,'||

    cur.data_length||

    ' data_length,cux_utf8_pub.count_byte_as_utf8('||

    cur.column_name||'),rowid row_id from '||cur.owner||'.'||

    cur.object_name||' t where exists (select null

    from system.dum$exceptions sde,

    dba_objects do,

    dba_tab_cols dto

    where sde.obj# = do.object_id

    and sde.intcol# = dto.internal_column_id

    and do.object_name = dto.table_name

    and do.owner = dto.owner

    and do.owner = '''||cur.owner||'''

    and dto.column_name = '''||cur.column_name||'''

    and upper(do.object_name) = '''||cur.object_name||'''

    and sde.row_id = t.rowid);';

    dbms_output.put_line(l_sql);

    dbms_output.put_line('');

    endloop cur;

    endget_quick_query_sql;

    endcux_utf8_pub;

    展开全文
  • 如果想区分一个完整字符串是 GBK 还是 UTF8 其实蛮简单。虽然做不到 100% 有效,但也比上面方法强许多。 UTF8 是兼容 ascii ,所以 0~127 就 ascii 完全一致了。 gbk 第一字节是高位为 1 ,第 2...
    如果想区分一个完整的字符串是 GBK 还是 UTF8 其实蛮简单的。虽然做不到 100% 有效,但也比上面的方法强许多。

    UTF8 是兼容 ascii 的,所以 0~127 就和 ascii 完全一致了。

    gbk 的第一字节是高位为 1 的,第 2 字节可能高位为 0 。这种情况一定是 gbk ,因为 UTF8 对 >127 的编码一定每个字节高位为 1 。

    另外,对于中文,UTF8 一定编码成 3 字节。(似乎亚洲文字都是,UTF8 中双字节好象只用于西方字符集)

    所以型如 110***** 10****** 的,我们一概看成 gbk/gb2312 编码。这就解决了“位”的问题。

    汉字以及汉字标点(包括日文汉字等),在 UTF8 中一定被编码成:1110**** 10****** 10******

    连续汉字数量不是 3 的倍数的 gb2312 编码的汉字字符串一定不会被误认为 UTF8 。用了一些gbk 扩展字,或是插入了一些 ascii 符号的字符串也几乎不会被认为是 UTF8 。

    一般说来,只要汉字稍微多几个,gbk 串被误认为 UTF8 的可能性极其低。(只需要默认不使用 UTF8 中双字节表示的字符)可能性低,这里还有另外一个原因。UTF8 中汉字编码的第一个字节是 1110**** ,这处于汉字的 gb2312 中二级汉字(不常用汉字,区码从 11011000 开始)的编码空间。一般是一些生僻字才会碰上。


    可用如下代码确认是不是汉字

    int isChinese(unsigned char bhead, unsigned char btail)
    {
    int r=0;
    int iHead = bhead & 0xff;
    int iTail = btail & 0xff;

    if ((iHead>=0x81 && iHead<=0xfe &&
    (iTail>=0x40 && iTail<=0x7e || iTail>=0x80 && iTail<=0xfe)) ||
    (iHead>=0xa1 && iHead<=0xf7 && iTail>=0xa1 && iTail<=0xfe) ||
    (iHead>=0xa1 && iHead<=0xf9 &&
    (iTail>=0x40 && iTail<=0x7e || iTail>=0xa1 && iTail<=0xfe)))
    {
    return 1;
    }
    return 0;
    }


    [摘自云风的blog]
    展开全文
  • 导读: ...英文,在al32utf8中仍然zhs16gbk一样用1个字节表示,因此导入固定长度英文字符数据时不会出错。 对于中文: 例如在字符集为zhs16gbk 数据库中创建表时指定字段 val char(15),该...
    导读:
    此文章是对于上一个实验的补充,上一次实验仅仅考虑的 varchar2 的情况。这次考虑到对于char类型的含有中文数据的情况。
    对于英文:
    对英文,在al32utf8中仍然和zhs16gbk一样用1个字节表示,因此导入固定长度英文字符数据时不会出错。
    对于中文:
    例如在字符集为zhs16gbk 数据库中创建表时指定字段 val char(15),该字段含有数据 ‘阿里云计算公司’在字符集为zhs16gbk 数据库中占用14个字

    节,而在字符集为al32utf8 数据库中占用21个字节 大于 char(15)所指定的长度15.此时导入数据就会失败。
    下面对于上述情况给以说明。
    =======================迁移 英文固定长度字符数据====================
    =======================创建表,含有英文固定长度字符数据=============
    yang@ORACL> create table fixed_char ( val char(15) );
    表已创建。
    yang@ORACL> insert into fixed_char select
      2  dbms_random.string('l',15) from dual
      3  connect by level <125;
    已创建124行。
    yang@ORACL> select val from fixed_char;
    VAL
    ---------------
    oxmjgwgzbjhthcr
    elbdlcpkfajsmrc
    jrwccslaywxpiwj
    ...............
    ljkowkocmdqnkgj
    idialvaxohrahah
    zwrqynvtevfujao
    funkxaokotsblww
    snyetpafaneicjm
    kgrcrpbwlvtotcv
    knhcazjkgotzvmg
    myqgvjqnsingmxv
    klthqehltsyzrxe
    voucbpykpnsbopx
    vtvavjddyafwqxt
    omcnkpvlhlxdvvg
    ccfpttivbdvursz
    已选择124行。
    yang@ORACL> spool d:\fixed_char.txt
    yang@ORACL> insert into fixed_char select
      2  dbms_random.string('l',15) from dual
      3  connect by level <125;
    已创建124行。
    yang@ORACL> select val from fixed_char where rownum <10;
    VAL
    ---------------
    oxmjgwgzbjhthcr
    elbdlcpkfajsmrc
    jrwccslaywxpiwj
    clizpikggppgfwy
    yqqxljlscqaiqli
    lrwoayaxyjzgdhy
    rkqpujyupltmrqb
    qvycepfgtwipwat
    iccsgvrpfxwligq
    已选择9行。
    yang@ORACL> commit;
    提交完成。
    =========================导出数据================================
    C:\Users\aaaa>expdp yang/yang tables=fixed_char directory=dumpdir dumpfile=fixed_char_zhs16gbk.dmp l
    ogfile=fixed_char.log
    Export: Release 11.1.0.6.0 - Production on 星期六, 12 3月, 2011 12:25:55
    Copyright (c) 2003, 2007, Oracle.  All rights reserved.
    连接到: Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
    With the Partitioning, OLAP, Data Mining and Real Application Testing options
    启动 "YANG"."SYS_EXPORT_TABLE_01":  yang/******** tables=fixed_char directory=dumpdir dumpfile=fixed
    _char_zhs16gbk.dmp logfile=fixed_char.log
    正在使用 BLOCKS 方法进行估计...
    处理对象类型 TABLE_EXPORT/TABLE/TABLE_DATA
    使用 BLOCKS 方法的总估计: 64 KB
    处理对象类型 TABLE_EXPORT/TABLE/TABLE
    . . 导出了 "YANG"."FIXED_CHAR"                         9.851 KB     248 行
    已成功加载/卸载了主表 "YANG"."SYS_EXPORT_TABLE_01"
    ******************************************************************************
    YANG.SYS_EXPORT_TABLE_01 的转储文件集为:
      D:\DUMP\FIXED_CHAR_ZHS16GBK.DMP
    作业 "YANG"."SYS_EXPORT_TABLE_01" 已于 12:27:32 成功完成
    =====================================导入数据=============================================
    oracle@rac1:rac1 /tmp/dump>impdp yang/yang tables=fixed_char directory=dumpdir dumpfile=fixed_char_zhs16gbk.dmp

    log=fixedchar_zhs16gbk_to_al32utf8.log
    Import: Release 11.2.0.1.0 - Production on Sat Mar 12 12:31:34 2011
    Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.
    Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
    With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
    Data Mining and Real Application Testing options
    Legacy Mode Active due to the following parameters:
    Legacy Mode Parameter: "log=fixedchar_zhs16gbk_to_al32utf8.log" Location: Command Line, Replaced with:

    "logfile=fixedchar_zhs16gbk_to_al32utf8.log"
    Master table "YANG"."SYS_IMPORT_TABLE_01" successfully loaded/unloaded
    Starting "YANG"."SYS_IMPORT_TABLE_01":  yang/******** tables=fixed_char directory=dumpdir dumpfile=fixed_char_zhs16gbk.dmp

    logfile=fixedchar_zhs16gbk_to_al32utf8.log
    Processing object type TABLE_EXPORT/TABLE/TABLE
    Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
    . . imported "YANG"."FIXED_CHAR"                         9.851 KB     248 rows
    Job "YANG"."SYS_IMPORT_TABLE_01" successfully completed at 12:31:38
    ==================================在目标库里验证数据====================================
    yang@rac1>select table_name from user_tables;
    TABLE_NAME
    ------------------------------
    CHARSET
    CHART
    TCHAR
    FIXED_CHAR
    yang@rac1>desc fixed_char
    Name                     Null?    Type
    ----------------------- -------- -------
    VAL                              CHAR(15)
    yang@rac1>select val from fixed_char where rownum <12;
    VAL
    ---------------
    oxmjgwgzbjhthcr
    elbdlcpkfajsmrc
    jrwccslaywxpiwj
    clizpikggppgfwy
    yqqxljlscqaiqli
    lrwoayaxyjzgdhy
    rkqpujyupltmrqb
    qvycepfgtwipwat
    iccsgvrpfxwligq
    zrtwmeviosnsgmv
    chwsezhjfgnsjll
    11 rows selected.
    yang@rac1>select dump(val) from fixed_char where rownum <10;
    DUMP(VAL)
    --------------------------------------------------------------------------
    Typ=96 Len=15: 111,120,109,106,103,119,103,122,98,106,104,116,104,99,114
    Typ=96 Len=15: 101,108,98,100,108,99,112,107,102,97,106,115,109,114,99
    Typ=96 Len=15: 106,114,119,99,99,115,108,97,121,119,120,112,105,119,106
    Typ=96 Len=15: 99,108,105,122,112,105,107,103,103,112,112,103,102,119,121
    Typ=96 Len=15: 121,113,113,120,108,106,108,115,99,113,97,105,113,108,105
    Typ=96 Len=15: 108,114,119,111,97,121,97,120,121,106,122,103,100,104,121
    Typ=96 Len=15: 114,107,113,112,117,106,121,117,112,108,116,109,114,113,98
    Typ=96 Len=15: 113,118,121,99,101,112,102,103,116,119,105,112,119,97,116
    Typ=96 Len=15: 105,99,99,115,103,118,114,112,102,120,119,108,105,103,113
    9 rows selected.
    对于英文字符可以实现由zhs16gbk 到 al32utf8的转换。
    解释:用UTF-8,UNICODE的2字节字符用变长个(1-3个字节)表示:
    1. 对英文,仍然和ASCII一样用1个字节表示,这个字节的值小于128(\x80);
    2. 扩展的ASCII字符(主要是西欧),第一字节用C2 - DF之间的范围,双字节表示。
    3.对其他语言,比如亚洲语系,还有各种特殊符号,使用3个字节表示;
    因此,在应用中程序处理过程中所有字符都是16位(双字节),但在存取转换成字节流时使用UTF-8格式转换,对于英文字符来说和原来用ASCII方式存取

    时相比大小仍然是一样的,而对中文来说和原来的GB2312编码方式相比,大小为:(3字节/2字节)=1.5倍,这也是下面导入数据失败的原因。
    ==================================迁移含有汉字 固定字符数据=============================
    =====================创建表,含有汉字的固定字符数据======================================
    yang@ORACL> create table fixed( val1 char(15),val2 char(15) );
    表已创建。
    yang@ORACL> insert into fixed select
      2  dbms_random.string('l',15) val1,
      3  '阿里云算公司' as val2
      4  from dual
      5  connect by level <500;
    已创建499行。
    yang@ORACL> select dump('阿里云计算公司') from dual;
    DUMP('阿里云计算公司')
    ----------------------------------------------------------------------
    Typ=96 Len=14: 176,162,192,239,212,198,188,198,203,227,185,171,203,190
    yang@ORACL> commit;
    提交完成。
    yang@ORACL> select count(*) from fixed;
      COUNT(*)
    ----------
           499
    yang@ORACL>
    ========================导出操作===========================================
    C:\Users\aaaa>expdp yang/yang tables=fixed directory=dumpdir dumpfile=fixed_zhs16gbk.dmp logfile=fixed.log
    Export: Release 11.1.0.6.0 - Production on 星期六, 12 3月, 2011 12:50:05
    Copyright (c) 2003, 2007, Oracle.  All rights reserved.
    连接到: Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
    With the Partitioning, OLAP, Data Mining and Real Application Testing options
    启动 "YANG"."SYS_EXPORT_TABLE_01":  yang/******** tables=fixed directory=dumpdir dumpfile=fixed_zhs1
    6gbk.dmp logfile=fixed.log
    正在使用 BLOCKS 方法进行估计...
    处理对象类型 TABLE_EXPORT/TABLE/TABLE_DATA
    使用 BLOCKS 方法的总估计: 64 KB
    处理对象类型 TABLE_EXPORT/TABLE/TABLE
    . . 导出了 "YANG"."FIXED"                              22.94 KB     499 行
    已成功加载/卸载了主表 "YANG"."SYS_EXPORT_TABLE_01"
    ******************************************************************************
    YANG.SYS_EXPORT_TABLE_01 的转储文件集为:
      D:\DUMP\FIXED_ZHS16GBK.DMP
    作业 "YANG"."SYS_EXPORT_TABLE_01" 已于 12:50:53 成功完成
    C:\Users\aaaa>
    ========================导入操作=====================================================================
    oracle@rac1:rac1 /tmp/dump>impdp yang/yang tables=fixed directory=dumpdir dumpfile=fixed_zhs16gbk.dmp

    log=fixed_zhs16gbk_to_al32utf8.log
    Import: Release 11.2.0.1.0 - Production on Sat Mar 12 12:52:38 2011
    Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.
    Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
    With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
    Data Mining and Real Application Testing options
    Legacy Mode Active due to the following parameters:
    Legacy Mode Parameter: "log=fixed_zhs16gbk_to_al32utf8.log" Location: Command Line, Replaced with:

    "logfile=fixed_zhs16gbk_to_al32utf8.log"
    Master table "YANG"."SYS_IMPORT_TABLE_01" successfully loaded/unloaded
    Starting "YANG"."SYS_IMPORT_TABLE_01":  yang/******** tables=fixed directory=dumpdir dumpfile=fixed_zhs16gbk.dmp

    logfile=fixed_zhs16gbk_to_al32utf8.log
    Processing object type TABLE_EXPORT/TABLE/TABLE
    Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
    ORA-02374: conversion error loading table "YANG"."FIXED"
    ORA-12899: value too large for column VAL2 (actual: 21, maximum: 15)===> 需要21个字节但是 char(15)规定val2字段长度是15
    ORA-02372: data for row: VAL2 : 0X'B0A2C0EFD4C6CBE3B9ABCBBE202020'
    ORA-02374: conversion error loading table "YANG"."FIXED"
    ORA-12899: value too large for column VAL2 (actual: 21, maximum: 15)
    ORA-02372: data for row: VAL2 : 0X'B0A2C0EFD4C6CBE3B9ABCBBE202020'
    ORA-02374: conversion error loading table "YANG"."FIXED"
    ORA-12899: value too large for column VAL2 (actual: 21, maximum: 15)
    ORA-02372: data for row: VAL2 : 0X'B0A2C0EFD4C6CBE3B9ABCBBE202020'
    ORA-02374: conversion error loading table "YANG"."FIXED"
    ORA-12899: value too large for column VAL2 (actual: 21, maximum: 15)
    ORA-02372: data for row: VAL2 : 0X'B0A2C0EFD4C6CBE3B9ABCBBE202020'
    ORA-02374: conversion error loading table "YANG"."FIXED"
    ORA-12899: value too large for column VAL2 (actual: 21, maximum: 15) 
    展开全文
  • UTF-8GBK,GB2313,Unicode,ANSI区别联系 基本概念: ASCII(全名:American Standard Code for Information Interchange):ASCII码中,一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个...
  • utf8、unicode与gbk

    2017-12-15 18:19:00
    汉字实在是太多了,包括繁体各种字符,于是产生了 GBK汉字:两个字节)编码,它包括了 GB2312 中编码,同时扩充了很多。 中国是个多民族国家,各个民族几乎都有自己独立语言系统,为了表示那些字符,继续...
  • 字符集 1)、ASII:美国标准信息交换码,用一个字节的7位可以表示; 2)、ISO8859-1:拉丁码表,欧洲码表,用一个字节的8位可以...6)、utf-8:变长编码方式,可用1-4个字节来表示一个字符。现在最多又有6个字节
  • UTF-8、GB2312、GBK编码格式详解 参考文章 UTF-8 使用1~4个字节对每个字符进行编码 128个ASCII字符字需要一个字节编码 带有附加符号拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及它拿...
  • UTF-8的一个特别好处是它与ISO-8859-1完全兼容,可以表示世界上所有字符,汉字通常用3个字节来表示。 GB2312code page是CP20936。GBK的code page是CP936。GB18030支持字符数更多。GB2312、GBK、GB18030均...
  • ASCII码 标准ASCII码长度为1个字节,指定一个字节的低7位来表示128种可能字符。 包括所有大写小写字母,数字0 到9、标点符号等,如大写字母A...GB2312对汉字采用双字节编码,收录7445个图形字符,其中包...
  • 题目:编写一个截取字符串函数,输入为一个字符串和字节数, 输出为按字节截取字符串,但要保证汉字不被截取半个,如...例如:gbk和gb2312都是用两个字节存储一个汉字,而UTF-8是用三个字节存储一个汉字。关于字符编码
  • 英文字母中文汉字在不同字符集编码下的字节数 英文字母: 字节数 : 1;编码:GB2312 字节数 : 1;编码:GBK 字节数 : 1;编码:GB18030 字节数 : 1;编码:ISO-8859-1 字节数 : 1;编码:UTF-8 ...
  • 一、汉字编码种类  汉字编码中现在主要用到有三类,包括GBK,GB2312Big5。  1、GB2312又称国标码,由国家标准总局发布,1981年5月1日实施,通行于大陆。新加坡等地也使用此编码。它是一个...
  • mysql utf-8 中文

    2019-08-08 15:16:47
    在MySQL 5.0以上版本: UTF-8:一个汉字=3个字节 ... 而不是 n/3或者 n/2 个,无论汉字和英文,Mysql都能存入n个字符,仅是实际字节长度有所区别,MySQL 并不会超过长度字符报错,而是直接截断了。 ...
  • 字节注入攻击 什么是宽字节注入? 如今有很多人在编码时候,大多数人程序编码都使用unicode编码...也有一些cms为了考虑老用户,所以出了gbk和utf-8 两个版本。一个gbk编码汉字,占用2个字节。一个utf-8编码...
  • 我在学习mysql中显然是不一样,查阅资料发现:mysql 5.0 之后 varchar(1)是可以存一个字符,不管是数字、英文字母还是汉字都可以(UTF8,三个字节也可以)!而在oracle中不管是varchar还是varchar2,都要严格...
  • UTF-8:一个汉字=3个字节 GBK:一个汉字=2个字节 2.在MySQL中 varchar(n)char(n)表示n个字符,无论汉字和英文,Mysql都能存入n个字符,仅是实际字节长度有所区别 即 MySQL 并不会超过长度字符报错,而是直接...
  • C 语言数组存储汉字问题小结

    千次阅读 2020-10-25 14:52:40
    常见中文编码 GB2312(国标简体中文字符集) GBK(国标扩展)使用 2 个字节编码来表示一个汉字,不常用 GB18030 使用 4 个字节编码来表示一个汉字,更通用 UTF-8 编码使用 3 个字节编码来表示一个汉字。...
  • 由于字节中文操作不是特别方便,所以java提供了字符流。 字符流 = 字节流+编码表 为什么字节流有中文可以识别? 因为汉字存储时候,无论使用哪一种编码,中文第一个字节为负。 utf-8:三个字节 GBK:2个字节 ...
  • varcharvarchar2区别

    2020-08-10 14:12:38
    具体要看数据库使用字符集,比如GBK汉字就会占两个字节,英文1个,如果是UTF-8汉字一般占3个字节,英文还是1个。 varchar空串不处理,varchar2将空串当做null来处理。 varchar存放固定长度字符串,最大...
  • 具体要看数据库使用字符集,比如GBK汉字就会占两个字节,英文1个,如果是UTF-8汉字一般占3个字节,英文还是1个。 varchar空串不处理,varchar2将空串当做null来处理。 varchar存放固定长度字符串,最大...
  • 乱码原因处理

    2015-05-25 17:21:24
    乱码原因处理  1.乱码原因:  造成乱码原因主要是前端页面编码格式服务端编码格式不同,这就造成了中文处理...1.ISO-8859-1:只取一个字节2.GBK-GB2312:汉字占用2个字节3.UTF-8:一个汉字占用3个...
  •  在MySQL中,最常见字符集有ASCII字符集、latin字符集、GB2312字符集、GBK字符集、UTF8字符集等,下面我们简单介绍下这些字符集: ASCII字符集  这个字符集使用1个字节进行编码,一个字节具有8位,总共可以保存...
  • 各种编码格式比较

    千次阅读 2015-12-31 10:46:51
    各种编码格式都可以中文进行处理,GB2312和GBK编码规则类似,差别在于GBK存储汉字的范围更大一些,可以处理几乎全部的汉字,所以用GB2312编码的,完全可以用GBK去解码,完美解码。从这一点上看GBK兼容GB2312。所以...
  • 一.mySQL中gbk和utf8的区别在MySQL中,如果数据库只需要支持一般中文,数据量很大,性能要求也比较高,那么就最好选择GBK,因为相对于UTF-8而言,GBK占用空间较小,每个汉字只占2个字节,而UTF-8汉字编码需要3个...
  • 【ZT】关于字符集

    2017-04-13 09:35:00
    utf8 全包容了gbk ,并不是说超集子集;...其中,utf8 编码中 字符大多是三字节的编码,一个汉字是3字节的编码;zhs16gbk并不是unicode 编码,只是提供了对gbk汉字编码支持, 一个汉字为双字节;u...
  • 长度为一个字节UTF-8:互联网广泛支持Unicode字符集,长度为一到四个字节 GBK:主要用于显示汉字,长度为二个字节 三、查看MySQL字符集校对规则 1.查看MySQL服务器字符集 show charsetset/character set ...

空空如也

空空如也

1 2 3 4
收藏数 78
精华内容 31
关键字:

gbk和utf8对汉字的字节