本地PL/SQL导出sql文件导入到Linux服务器上的Oracle数据库出现数据乱码
检查数据库字符集参数“NLS_LANGUAGE”、 “NLS_TERRITORY”、 “NLS_CHARACTERSET'”的值。
select parameter,value from nls_database_parameters where parameter in('NLS_LANGUAGE','NLS_TERRITORY','NLS_CHARACTERSET');
或者select userenv('language') from dual;查询字符集编码
可以发现本地数据库字符集和服务器字符集编码不同
修改数据库所在机器操作系统的字符集“NLS_LANG”变量。
Windows系统在cmd窗口输入:set NLS_LANG=AMERICAN_AMERICA.AL32UTF8
该命令只对当前窗口有效,Linux系统输入: export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
因为导出dump文件的字符编码只和NLS_LANG环境变量有关,所以我们也可以通过直接修改Windows机器的环境变量实现:
还有一种简单的方式是修改dump文件,dump用16进制打开,它的第2、3个字节就表示使用的字符集:
如图所示字符集的编号是0369,在数据库中可以查询到编号对应的字符集也可以查询字符集对应的编号,因为我们直接修改这两个字节就可以改变dump文件的字符集。。查询编号对应的字符集:
select nls_charset_name(to_number('0369','xxxx')) from dual;
查询字符集对应的编号:
select to_char(nls_charset_id('ZHS16GBK'), 'xxxx') from dual;
下面演示导出导入dump文件的步骤:
1、导出dump文件
本地是Windows系统安装的oracle,使用exp导出dump文件,先打开命名行界面,输入导出命令如下:
exp username/password@localhost/sid file=d:\dd.dump log=d:dd.log
2、将dump文件和log文件放到远程服务器上
3、切换到oracle用户执行导入dump文件的命令
su – oracle
imp customerchat/customerchat@localhost/NJORCL file=/database/app/oracle/oradata/ccorcl/dd.dump log=/database/app/oracle/oradata/ccorcl/dd.log
1)报错:
IMP-00030: failed to create file /database/app/oracle/oradata/ccorcl/dd.log for write
IMP-00000: Import terminated unsuccessfully
从错误信息可以知道是由于文件只读造成的,这是由于上传到服务使用的用户不是oracle用户,所以oracle对这个文件是只读的,需要切换到root用户将文件所属用户和组改为oracle:
chown –R 用户:用户组 文件或目录名
2)切换到oracle用户重新执行imp命令:
报错:
IMP-00058: ORACLE error 12541 encountered
ORA-12541: TNS:no listener
IMP-00000: Import terminated unsuccessfully
从错误可以看出是报找不到监听器的错误,可以通过lsnrctl status查看监听器是否启动,检查发现监听器正常启动,很奇怪为什么报错,仔细检查发现是导入命令漏写了端口号。。。加上端口好继续执行
imp customerchat/customerchat@localhost:10000/NJORCL file=/database/app/oracle/oradata/ccorcl/dd.dump log=/database/app/oracle/oradata/ccorcl/dd.log
3)继续执行报如下错误
Export file created by EXPORT:V11.02.00 via conventional path
IMP-00013: only a DBA can import a file exported by another DBA
IMP-00000: Import terminated unsuccessfully
从错误可以看出是要导入数据的用户没有dba权限,可以登录到sysdba用户将dba权限分配给该用户:
sqlplus / as sysdba
grant sysdba to username;
grant imp_full_database to username;
4)继续执行报如下错误
Export file created by EXPORT:V11.02.00 via conventional path
import done in US7ASCII character set and AL16UTF16 NCHAR character set
import server uses AL32UTF8 character set (possible charset conversion)
export client uses AL32UTF8 character set (possible charset conversion)
IMP-00031: Must specify FULL=Y or provide FROMUSER/TOUSER or TABLES arguments
IMP-00000: Import terminated unsuccessfully
从报错可以看出需要指定从哪个用户导入到哪个用户,可以指定,如果不知道可以直接使用full=y代替:
imp customerchat/customerchat@localhost:10000/NJORCL file=/database/app/oracle/oradata/ccorcl/dd.dump log=/database/app/oracle/oradata/ccorcl/dd.log fromuser=customerchat touser=customerchat
执行成功:
登录root用户将刚才分配的权限收回:
sqlplus / as sysdba
revoke sysdba from username;
revoke imp_full_database from username;