库表字符集不一致导致的全表扫描问题

探讨了在MySQL中,当数据库建库字符集与表字符集不一致时,创建存储过程可能导致全表扫描的问题。通过示例展示了不同版本MySQL的行为差异,并分析了优化器跟踪结果。
背景:
当数据库的建库字符集和表不一样时,在库下针对表创建存储过程可能导致全表扫描

如下例:
drop database if exists xx1;
drop database if exists xx2;
create database xx1 character set utf8;    
create database xx2 character set gbk;

 

然后分别在xx1 和 xx2下执行:
CREATE TABLE t1 ( `col1` varchar(10) NOT NULL, `col2` bigint(11) NOT NULL DEFAULT '0', PRIMARY KEY (`col1`)) ENGINE=InnoDB DEFAULT CHARSET=gbk;
insert into t1 values ('ac',2),('del',3),('sp',5),('tr',12);
DELIMITER //
CREATE PROCEDURE proc1(IN isn CHAR(20))  
BEGIN  
     START TRANSACTION;   
     SELECT col2 FROM t1 WHERE col1= isn FOR UPDATE;  
     COMMIT;
END //
DELIMITER ;

 

在5.5版本中通过show processlist可以看到SQL进行了转换(简单的锁住行记录,执行存储过程,再show processlist):
use xx1;
call proc1(‘tr’); 参数isn会被展开成:NAME_CONST(‘isn’,_utf8 0x7472 COLLATE ‘utf8_general_ci’)
use xx2;
call proc1(‘tr’); 参数isn会被展开成:NAME_CONST(‘isn’,_gbk 0x7472 COLLATE ‘gbk_chinese_ci’)

在5.6版本里使用ROW模式时,不会展开sql,但内部采取的是同样的策略。
由于name_const中引用的的字符集和表定义不同,因此xx1.proc1()每次调用都会产生两次全表扫描。但奇怪的是,如果单独执行上述SQL(而不是调用存储过程),就不会全表扫描。

还好MySQL5.6开始有了optimizer_trace这个利器,打开optimizer trace就一目了然了,对比单独执行SQL和执行存储过程:
call xx1.proc1(‘tr’)
| SELECT col2 FROM t1 WHERE col1=  NAME_CONST(‘isn’,_utf8’tr’ COLLATE ‘utf8_general_ci’) FOR UPDATE | {
“steps”: [
{
“join_preparation”: {
“select#”: 1,
“steps”: [
{
           “expanded_query”: “/* select#1 */ select `t1`.`col2` AS `col2` from `t1` where (convert(`t1`.`col1` using utf8) = isn@0)”
}
]
}
},
{
“join_optimization”: {
“select#”: 1,
“steps”: [
{
“condition_processing”: {
“condition”: “WHERE”,
“original_condition”: “(convert(`t1`.`col1` using utf8) = isn@0)”,
“steps”: [
{
“transformation”: “equality_propagation”,
“resulting_condition”: “(convert(`t1`.`col1` using utf8) = isn@0)”
},
{
“transformation”: “constant_propagation”,
“resulting_condition”: “(convert(`t1`.`col1` using utf8) = isn@0)”
},
{
“transformation”: “trivial_condition_removal”,
“resulting_condition”: “(convert(`t1`.`col1` using utf8) = isn@0)”
}
]
}
},
{
“table_dependencies”: [
{
“table”: “`t1`”,
“row_may_be_null”: false,
“map_bit”: 0,
“depends_on_map_bits”: [
]
}
]
},
{
“ref_optimizer_key_uses”: [
]
},
{
“rows_estimation”: [
{
“table”: “`t1`”,
“table_scan”: {
“rows”: 4,
“cost”: 1
}
}
]
},
{
“considered_execution_plans”: [
{
“plan_prefix”: [
],
“table”: “`t1`”,
“best_access_path”: {
“considered_access_paths”: [
{
“access_type”: “scan”,
“rows”: 4,
“cost”: 1.8,
“chosen”: true
}
]
},
“cost_for_plan”: 1.8,
“rows_for_plan”: 4,
“chosen”: true
}
]
},
{
“attaching_conditions_to_tables”: {
“original_condition”: “(convert(`t1`.`col1` using utf8) = isn@0)”,
“attached_conditions_computation”: [
],
“attached_conditions_summary”: [
{
“table”: “`t1`”,
“attached”: “(convert(`t1`.`col1` using utf8) = isn@0)”
}
]
}
},
{
“refine_plan”: [
{
“table”: “`t1`”,
“access_type”: “table_scan”
}
]
}
]
}
},
{
“join_execution”: {
“select#”: 1,
“steps”: [
]
}
}
]
}
call xx2.proc1(‘tr’)
SELECT col2 FROM t1 WHERE col1=  NAME_CONST(‘isn’,_gbk’tr’ COLLATE ‘gbk_chinese_ci’) FOR UPDATE | {
“steps”: [
{
“join_preparation”: {
“select#”: 1,
“steps”: [
{
“expanded_query”: “/* select#1 */ select `t1`.`col2` AS `col2` from `t1` where (`t1`.`col1` = isn@0)”
}
]
}
},
{
“join_optimization”: {
“select#”: 1,
“steps”: [
{
“condition_processing”: {
“condition”: “WHERE”,
“original_condition”: “(`t1`.`col1` = isn@0)”,
“steps”: [
{
“transformation”: “equality_propagation”,
“resulting_condition”: “multiple equal(isn@0, `t1`.`col1`)”
},
{
“transformation”: “constant_propagation”,
“resulting_condition”: “multiple equal(isn@0, `t1`.`col1`)”
},
{
“transformation”: “trivial_condition_removal”,
“resulting_condition”: “multiple equal(isn@0, `t1`.`col1`)”
}
]
}
},
{
“table_dependencies”: [
{
“table”: “`t1`”,
“row_may_be_null”: false,
“map_bit”: 0,
“depends_on_map_bits”: [
]
}
]
},
{
“ref_optimizer_key_uses”: [
{
“table”: “`t1`”,
“field”: “col1″,
“equals”: “isn@0″,
“null_rejecting”: false
}
]
},
{
“rows_estimation”: [
{
“table”: “`t1`”,
“rows”: 1,
“cost”: 1,
“table_type”: “const”,
“empty”: false
}
]
},
{
“condition_on_constant_tables”: “1”,
“condition_value”: true
},
{
“attaching_conditions_to_tables”: {
“original_condition”: “1”,
“attached_conditions_computation”: [
],
“attached_conditions_summary”: [
]
}
},
{
“refine_plan”: [
]
}
]
}
},
{
“join_execution”: {
“select#”: 1,
“steps”: [
]
}
}
]
}
use xx1;

SELECT col2 FROM t1 WHERE col1=
NAME_CONST
(‘isn’,_utf8’tr’ COLLATE ‘utf8_general_ci’)
 FOR UPDATE
 SELECT col2 FROM t1 WHERE col1=  NAME_CONST(‘isn’,_utf8’tr’ COLLATE ‘utf8_general_ci’) FOR UPDATE | {

  “steps”: [

    {

      “join_preparation”: {

        “select#”: 1,

        “steps”: [

          {

            “expanded_query”: “/* select#1 */ select `t1`.`col2` AS `col2` from `t1` where (`t1`.`col1` = convert(NAME_CONST(‘isn’,(_utf8’tr’ collate utf8_general_ci)) using gbk))”

          }

        ]

      }

    },

    {

      “join_optimization”: {

        “select#”: 1,

        “steps”: [

          {

            “condition_processing”: {

              “condition”: “WHERE”,

              “original_condition”: “(`t1`.`col1` = convert(NAME_CONST(‘isn’,(_utf8’tr’ collate utf8_general_ci)) using gbk))”,

              “steps”: [

                {

                  “transformation”: “equality_propagation”,

                  “resulting_condition”: “multiple equal(convert(NAME_CONST(‘isn’,(_utf8’tr’ collate utf8_general_ci)) using gbk), `t1`.`col1`)”

                },

                {

                  “transformation”: “constant_propagation”,

                  “resulting_condition”: “multiple equal(convert(NAME_CONST(‘isn’,(_utf8’tr’ collate utf8_general_ci)) using gbk), `t1`.`col1`)”

                },

                {

                  “transformation”: “trivial_condition_removal”,

                  “resulting_condition”: “multiple equal(convert(NAME_CONST(‘isn’,(_utf8’tr’ collate utf8_general_ci)) using gbk), `t1`.`col1`)”

                }

              ]

            }

          },

          {

            “table_dependencies”: [

              {

                “table”: “`t1`”,

                “row_may_be_null”: false,

                “map_bit”: 0,

                “depends_on_map_bits”: [

                ]

              }

            ]

          },

          {

            “ref_optimizer_key_uses”: [

              {

                “table”: “`t1`”,

                “field”: “col1″,

                “equals”: “convert(NAME_CONST(‘isn’,(_utf8’tr’ collate utf8_general_ci)) using gbk)”,

                “null_rejecting”: false

              }

            ]

          },

          {

            “rows_estimation”: [

              {

                “table”: “`t1`”,

                “rows”: 1,

                “cost”: 1,

                “table_type”: “const”,

                “empty”: false

              }

            ]

          },

          {

            “condition_on_constant_tables”: “1”,

            “condition_value”: true

          },

          {

            “attaching_conditions_to_tables”: {

              “original_condition”: “1”,

              “attached_conditions_computation”: [

              ],

              “attached_conditions_summary”: [

              ]

            }

          },

          {

            “refine_plan”: [

            ]

          }

        ]

      }

    },

    {

      “join_execution”: {

        “select#”: 1,

        “steps”: [

        ]

      }

    }

  ]
}

 

 


注意这expanded_query一项,对于这种方式的查询,需要读取每一条记录,进行字符集转换再比较:
expanded_query”: “/* select#1 */ select `t1`.`col2` AS `col2` from `t1` where (convert(`t1`.`col1` using utf8) = isn@0)

由于本人对优化器模块了解不深,也不确定是否是Bug,先Report到了一个小bug到Bug list,ref:http://bugs.mysql.com/bug.php?id=76002
Updated @2015/2/25, 存储过程的输入列需要显式的定义输入字符集,否则其输入列的字符集将继承自库的字符集。参考bug中的回复。

 


<think>我们正在处理一个关于Oracle 11g数据库查询时转换字段字符集问题。根据用户的需求,他希望在查询时转换某个字段的字符集编码。我们有一些引用资料可以参考。 首先,引用[1]提到:在客户端向服务器端提交SQL语句时,客户端会根据NLS_LANG服务器数据库字符集对SQL中的字符进行转换处理。如果NLS_LANG设置的字符集与服务器数据库字符集相同,则作转换,否则要转换成服务器端字符集。 引用[2]提供了一个具体的例子:当两个数据库字符集同(一个为ZHS16GBK,另一个为WE8ISO8859P1)时,查询中文字段会出现乱码。他们采用的解决方案是: 1. 在源数据库字符集为ZHS16GBK)中创建视图,使用`utl_raw.cast_to_raw`将中文字段转换为原始二进制。 2. 在目标数据库字符集为WE8ISO8859P1)中,通过DBLINK查询该视图,并使用`convert(utl_raw.cast_to_varchar2(chinese_field), 'WE8ISO8859P1')`将字段转换回字符串,同时指定目标字符集。 引用[5]提到可以查询字符集设置:`select * from nls_database_parameters where parameter in('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET');` 因此,我们可以采用类似引用[2]的方法,在查询时转换字段的字符集。具体步骤如下: 1. 确定源数据库目标数据库字符集(用户可能是在同一个数据库中转换,也可能是跨数据库查询,但用户的问题是在同一个数据库查询时转换字段,所以我们可以假设用户需要将字段从数据库当前字符集转换为另一个字符集,或者从存储的字符集转换为另一种编码)。 2. 在Oracle中,如果字段的字符集数据库字符集一致,但用户想以另一种字符集显示,我们可以使用`CONVERT`函数,或者使用`UTL_RAW.CAST_TO_RAW``UTL_RAW.CAST_TO_VARCHAR2`结合`CONVERT`函数。 但是注意:`CONVERT`函数的语法是: CONVERT(字符串, 目标字符集, 源字符集) 如果省略源字符集,则使用数据库字符集。 因此,我们可以这样写: SELECT CONVERT(字段名, '目标字符集', '源字符集') FROM 名; 但是,用户可能知道源字符集目标字符集的具体名称。我们可以通过以下查询获取数据库字符集: SELECT value FROM nls_database_parameters WHERE parameter = 'NLS_CHARACTERSET'; 然而,用户可能希望转换到另一个字符集(比如从ZHS16GBK转换为UTF8)。那么,在查询时,我们可以这样写: SELECT CONVERT(字段名, 'AL32UTF8', 'ZHS16GBK') FROM 名; 但是,如果字段的存储字符集数据库字符集一致,那么可能存储的就是二进制数据,或者已经经过转换。通常,在数据库中的字符数据是按照数据库字符集存储的。 如果用户是在同一个数据库内转换,那么源字符集就是数据库字符集。因此,可以简写为: SELECT CONVERT(字段名, '目标字符集') FROM 名; 但需要注意的是,`CONVERT`函数要求数据库支持这种转换,并且转换的字符集必须是数据库支持的。 另外,引用[2]中使用了另一种方法:先将字段转换为原始二进制(`utl_raw.cast_to_raw`),然后再用`utl_raw.cast_to_varchar2`配合`CONVERT`。这种方法实际上是在绕过Oracle的自动转换,直接操作二进制,然后手动指定转换。这种方法在跨数据库字符集查询时比较有效。 因此,我们提供两种方法: 方法一:使用CONVERT函数(适用于已知源字符集目标字符集,且数据库支持转换) SELECT CONVERT(字段名, '目标字符集', '源字符集') FROM 名; 方法二:使用二进制中转(当自动转换奏效时,如引用[2]的情况) SELECT CONVERT(UTL_RAW.CAST_TO_VARCHAR2(字段名), '目标字符集') FROM 名; 但是注意,这种方法要求字段名是二进制类型(如RAW),或者先用`UTL_RAW.CAST_TO_RAW`将字符串转为二进制,然后再转换字符集?实际上,引用[2]的做法是: 在源数据库:将字符串字段用`UTL_RAW.CAST_TO_RAW`转换成RAW类型(这样就会被转换)存入视图。 在目标数据库:使用`CONVERT(UTL_RAW.CAST_TO_VARCHAR2(RAW字段), '目标字符集')`,这里`UTL_RAW.CAST_TO_VARCHAR2`实际上是将RAW按当前数据库字符集解释成字符串,然后`CONVERT`再转换到目标字符集?这似乎对。 重新理解引用[2]: 在源数据库(ZHS16GBK)中,他们创建视图:`SELECT Utl_Raw.cast_to_raw(chinese_field) FROM table_name`,这里`Utl_Raw.cast_to_raw`将字符串(按照数据库字符集ZHS16GBK)转换为二进制RAW数据。 然后在目标数据库(WE8ISO8859P1)中,他们这样查询:`select convert(utl_raw.cast_to_varchar2(chinese_field), 'WE8ISO8859P1') from ...`。这里,`utl_raw.cast_to_varchar2`将RAW数据按照目标数据库的当前字符集(WE8ISO8859P1)解释成字符串,然后`convert`函数再转换一次?实际上,这里`convert`函数的第二个参数是目标字符集,但源字符集没有指定,所以默认是数据库字符集(WE8ISO8859P1),所以实际上没有转换。所以这个做法可能是错误的?或者他们实际上想达的是:在目标数据库,他们用`utl_raw.cast_to_varchar2`将RAW数据直接解释成字符串,而解释时使用的字符集是目标数据库字符集(WE8ISO8859P1),但是原始数据是ZHS16GBK编码的,这样直接解释就会乱码。所以这里需要转换。 因此,正确的方法应该是:在目标数据库,将RAW数据用`CONVERT`函数从源字符集(ZHS16GBK)转换为目标字符集(WE8ISO8859P1): SELECT CONVERT(UTL_RAW.CAST_TO_VARCHAR2(chinese_field), 'WE8ISO8859P1', 'ZHS16GBK') FROM ... 但是,这样写的前提是`UTL_RAW.CAST_TO_VARCHAR2(chinese_field)`能够正确地将二进制数据解释为源字符集的字符串?实际上,`UTL_RAW.CAST_TO_VARCHAR2`会按照当前数据库字符集来解释二进制数据,所以如果当前数据库字符集是WE8ISO8859P1,那么解释出来的字符串就是乱码,然后再用`CONVERT`转换,这样是对的。 所以,引用[2]的方法实际上应该是:在目标数据库,直接使用`CONVERT`函数,但是将RAW数据作为二进制输入,然后指定源字符集目标字符集?但是`CONVERT`函数要求第一个参数是字符串,而是RAW。 因此,我们需要重新考虑: 在目标数据库,应该这样: SELECT CONVERT(UTL_RAW.CAST_TO_VARCHAR2(chinese_field), 'WE8ISO8859P1', 'ZHS16GBK') 但是,这样行,因为`UTL_RAW.CAST_TO_VARCHAR2(chinese_field)`已经按照当前数据库字符集(WE8ISO8859P1)将二进制解释成字符串了,这个字符串已经是乱码了,再转换也无法恢复。 所以,正确的做法是:在目标数据库,使用`CONVERT`函数,但是直接传入RAW数据,并指定源字符集目标字符集?但是`CONVERT`函数支持RAW类型。 因此,我们可以这样:在目标数据库,先将RAW数据用`CONVERT`函数转换为目标字符集,但是这里需要先将RAW数据转换为字符串,但指定源字符集?Oracle没有直接提供这样的函数。 另一种思路:在目标数据库,使用`UTL_I18N.RAW_TO_CHAR`函数,它可以指定字符集将RAW转换为字符串: SELECT UTL_I18N.RAW_TO_CHAR(chinese_field, '源字符集') FROM ... 然后,如果还需要转换为另一个字符集,可以再用`CONVERT`,但这样已经转换到目标字符集了,所以直接: SELECT UTL_I18N.RAW_TO_CHAR(chinese_field, 'ZHS16GBK') FROM ... 这样在目标数据库(WE8ISO8859P1)中,就会将RAW数据(原始是ZHS16GBK编码的字符串)转换为字符串,而数据库会按照目标数据库字符集显示这个字符串(如果目标数据库字符集是WE8ISO8859P1,那么它显示的是将ZHS16GBK字符串转换为WE8ISO8859P1后的结果?实际上,`UTL_I18N.RAW_TO_CHAR`只是将二进制数据按照指定的字符集解码成字符串,这个字符串在目标数据库中以Unicode形式存在,当显示时,如果客户端字符集设置正确,就可以正确显示。但是,如果目标数据库字符集支持某些字符,可能会出现问题。 所以,引用[2]的方法可能是完善的。实际上,在Oracle中,跨字符集数据库查询,最可靠的方法是使用数据库链接(DBLINK)`UTL_I18N`包。 因此,我们推荐的方法: 方法1:使用`CONVERT`函数(适用于同数据库内转换,且知道源目标字符集) SELECT CONVERT(column_name, 'target_charset', 'source_charset') FROM table_name; 方法2:使用`UTL_I18N.RAW_TO_CHAR`(适用于从RAW数据按指定字符集解码) SELECT UTL_I18N.RAW_TO_CHAR(column_name, 'source_charset') FROM table_name; 注意:这个方法要求column_name是RAW类型。所以如果原字段是字符串,需要先转换为RAW,但转换时能改变其二进制值。我们可以用`UTL_RAW.CAST_TO_RAW`将字符串转成RAW,然后再用`UTL_I18N.RAW_TO_CHAR`按源字符集转换?这样行,因为`UTL_RAW.CAST_TO_RAW`会将字符串按照当前数据库字符集转换为二进制,如果当前数据库字符集字符集一致,那么转换出来的二进制就是源字符集的编码了。 因此,如果字段原本是字符串类型,那么它存储的二进制数据就是按照数据库字符集编码的。所以,如果用户想以另一种字符集来显示这个字段,那么可以使用`CONVERT`函数,将数据库字符集(源)转换为目标字符集。 总结:用户的问题是在同一个数据库查询时转换字段的字符集编码。我们假设字段的当前存储编码是数据库字符集(比如ZHS16GBK),用户想转换为UTF-8(AL32UTF8)。那么,我们可以这样查询: SELECT CONVERT(column_name, 'AL32UTF8', 'ZHS16GBK') FROM table_name; 但是,如果用户知道数据库字符集,我们可以先查询: SELECT value FROM nls_database_parameters WHERE parameter = 'NLS_CHARACTERSET'; 假设查询结果是'ZHS16GBK',那么就可以使用上面的转换。 另外,如果用户想将字段转换为国家字符集(NCHAR),那么可以使用`TO_NCHAR`函数,但这是转换字符集,而是转换到国家字符集。 注意:`CONVERT`函数可能会因为字符集支持某些字符而转换失败,或者出现乱码。 因此,我们给出以下步骤: 步骤1:查询当前数据库字符集。 SELECT value FROM nls_database_parameters WHERE parameter = 'NLS_CHARACTERSET'; 步骤2:在查询中使用`CONVERT`函数,将字段从当前数据库字符集(或指定的源字符集)转换为目标字符集。 示例: -- 假设数据库字符集是ZHS16GBK,目标字符集是AL32UTF8 SELECT CONVERT(my_column, 'AL32UTF8', 'ZHS16GBK') FROM my_table; 如果用户想直接在查询结果中看到转换后的字符串,那么这样就可以了。 但是,如果用户需要将结果作为字符串在应用程序中使用,那么转换后的字符串在数据库中的存储编码是AL32UTF8,而数据库字符集仍然是ZHS16GBK,所以当它被返回给客户端时,客户端会按照客户端的设置(NLS_LANG)进行转换。因此,为了确保客户端正确显示,客户端的NLS_LANG应该设置为AL32UTF8。 另外,引用[5]还提到可以查询会话的字符集设置:`select * from nls_session_parameters`。 所以,我们也可以临时修改会话的字符集,但Oracle允许直接修改NLS_CHARACTERSET,它是由数据库客户端设置决定的。 因此,我们主要使用`CONVERT`函数。 最后,我们生成相关问题。</think>在 Oracle 11g 中查询时转换字段字符集,需结合 `CONVERT` 函数或二进制转换方法实现。以下是详细步骤解决方案: --- ### 一、字符集转换原理 1. **字符集基础** Oracle 中字符数据按数据库字符集(如 `ZHS16GBK`、`AL32UTF8`)存储。查询时若客户端字符集(`NLS_LANG`)与服务端一致,可能导致乱码。 2. **转换核心** 使用 `CONVERT(字段, 目标字符集, 源字符集)` 函数显式转换编码,或通过 `UTL_RAW.CAST_TO_RAW` 处理二进制数据避免自动转换[^1][^2]。 --- ### 二、查询时转换字段字符集的两种方法 #### 方法1:直接使用 `CONVERT` 函数 ```sql SELECT CONVERT(column_name, '目标字符集', '源字符集') FROM table_name; ``` **示例**(将 `ZHS16GBK` 的字段转为 `WE8ISO8859P1`): ```sql SELECT CONVERT(remark, 'WE8ISO8859P1', 'ZHS16GBK') AS converted_text FROM your_table; ``` **注意**: - 源/目标字符集需与数据库支持的字符集匹配(通过 `SELECT * FROM V$NLS_VALID_VALUES;` 查询)。 #### 方法2:通过二进制中转(跨字符集查询) 1. **在源数据库创建视图**(若字段原字符集为 `ZHS16GBK`): ```sql CREATE OR REPLACE VIEW v_raw_view AS SELECT id, UTL_RAW.CAST_TO_RAW(chinese_column) AS raw_column FROM source_table; ``` 2. **在目标数据库查询**(字符集为 `WE8ISO8859P1`): ```sql SELECT id, CONVERT(UTL_RAW.CAST_TO_VARCHAR2(raw_column), 'WE8ISO8859P1') AS converted_text FROM v_raw_view@dblink_name; ``` **优势**:避免 Oracle 客户端自动转换导致的乱码[^2]。 --- ### 三、关键辅助操作 1. **确认数据库字符集**: ```sql SELECT parameter, value FROM nls_database_parameters WHERE parameter IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET'); ``` - `NLS_CHARACTERSET`:普通字符集(如 `ZHS16GBK`) - `NLS_NCHAR_CHARACTERSET`:国家字符集(如 `AL16UTF16`)[^5]。 2. **检查会话字符集**: ```sql SELECT * FROM nls_session_parameters; ``` --- ### 四、注意事项 1. **字符集兼容性** - 若目标字符集支持某些字符(如中文),转换后可能出现 `?` 或乱码。 2. **性能影响** `CONVERT` 函数可能导致全表扫描,大数据量时需优化查询或添加索引。 3. **替代方案** - 持久性转换:使用 `ALTER TABLE ... MODIFY column` 修改字段字符集(需停机维护)。 - 导出/导入:通过 `Data Pump` 导出时指定字符集转换。 --- ### 五、示例场景 **需求**:将 `employees` 的 `name` 字段(原字符集 `ZHS16GBK`)以 `AL32UTF8` 格式查询。 **查询语句**: ```sql SELECT employee_id, CONVERT(name, 'AL32UTF8', 'ZHS16GBK') AS utf8_name FROM employees; ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值