sqlplus执行sql文件报错

一:问题描述:今天别的公司给的sql文件(201901.sql),内容如下:Insert into T_ORDER (ORDER_NO,ORG_ORDER_NO,MCHNT_NO,MCHNT_NAME,ORG_NAME,ORG_ID,MD,ORDER_AMOUNT,AMOUNT,CREATED,SOURCE,PAY_ST,TIME_PAID,OPEN_ID) values ('15463005906703193844','15463005906703193844','193298','王学政源','支行','005265','转入',200000,200000,to_timestamp('01-1月 -19 07.56.30.670000000 上午','DD-MON-RR HH.MI.SSXFF AM'),0,2,to_timestamp('01-1月 -19 07.56.13.000000000 上午','DD-MON-RR HH.MI.SSXFF AM'),'694BED617AEA24F48F8E564393AFE851');

数据量大概是1000多万,所以采用批量执行sql文件来导入数据库,但是报错,两个问题!

SQL>@201901.sql

问题1,具体报错如下,这个问题是字符集的问题,

ORA-01756: quoted string not properly terminated

问题2 ,具体报错如下,这个问题是日期格式参数的问题

ORA-01843: not a valid month

然而用plssql developer工具执行一条数据,是可以成功的,这说明数据本身是没有问题,plssql developer强大之处在于它可以作为数据库和客户端的无缝兼容,格式自动转换,字符集以及其他的格式转换

二:问题解决:

一:解决字符集问题:

1.1.file -i 看文件的字符集,发现是utf-8

[oracle@ory-mysql-east-01 backup]$ file -i 2019012.sql

2019012.sql: text/plain; charset=utf-8

1.2.然后设置oracle用户的环境变量NLS_LANG(保持和文件的字符集一样)

export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
二:解决日期格式参数的问题


因为sql文件中的日期是中文的,例如:01-1月 -19 07.56.13.000000000 上午,但是数据库的日期格式是英文的,

如下所示,所以只需要修改下日期的格式即可,NLS_DATE_LANGUAGE设置为简体中文,为防止系统出现问题,只需要修改session级别的即可!

2.1.刚开始 是英文的如下所示:

SQL> select * from nls_session_parameters where parameter='NLS_DATE_LANGUAGE';

PARAMETER                             VALUE

--------------------------------------------------------------------------------

NLS_DATE_LANGUAGE           AMERICAN

SQL> select sysdate from dual;

SYSDATE

------------------

30-AUG-19

2.2修改为简体中文的:

SQL> alter session set nls_date_language='SIMPLIFIED CHINESE';

Session altered.

SQL> select sysdate from dual;

SYSDATE

--------------

30-8月 -19

SQL> select * from nls_session_parameters where parameter='NLS_DATE_LANGUAGE';

PARAMETER                             VALUE

--------------------------------------------------------------------------------

NLS_DATE_LANGUAGE           SIMPLIFIED CHINESE
三:问题分析:

一:关于字符集:oracle在处理数据的时候,简单分成两类 insert和select

insert 的过程:首先以Oracle客户端的字符集(lang)编码------->然后通过客户端nls_lang告诉sqlplus是以那种字符集编码的------->然后Oracle数据库得知nls_lang后,借助自己的编码表来转换成数据库的字符集(注意数据库的字符集可以和nls_lang不一样!),如果使用lang=utf8编码,然后nls_lang=gbk,等Oracle转换的时候,通过gbk的编码表来转换,那么肯定会乱码的!!!!!!!所以 只需要lang和nls_lang一样,那么insert就不会乱码!!!!不管数据库的字符集和他一样不一样!!!也就是说Oracle会做字符集转换的工作,客户端不会转换,只会根据lang来查找对应的字符串, 然后如果是执行一个文件,那么只需要保证NLS_LANG设置的和文件的字符集一样即可!

select的过程:Oracle数据库根据数据库的字符集utf8把查询的内容进行编码--------->然后告诉sqlplus程序我查出来的内容是以utf8进行编码的,然后sqlplus告诉Oracle他们需要的是nls_lang=gbk,于是Oracle发现不一样,这样Oracle就根据自己的编码表来找gbk的对应编码,然后传给sqlplus程序------>sqlplus直接把得到的这串编码扔给客户端操作系统,而操作系统只有ZHS16GBK编码表,它不会问得到的这串编码是什么格式的! 所以当你使用sqlplus / as sysdba连接数据库查询的时候你只需要保证你的NLS_LANG设置的和你的工具(例如CRT或者xshell)字符集一样即可!,不需要保证NLS_LANG和你的数据库一样(oracle会自动转换)
二:关于 日期格式参数nls_date_language的知识

SQL> show parameter nls_date_language;
NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

nls_date_language                    string
没有设置,是默认值,参看文档:默认值取自于 NLS_LANGUAGE

Property Description
Parameter type String
Syntax NLS_DATE_LANGUAGE = language
Default value Derived from NLS_LANGUAGE
Modifiable ALTER SESSION
Range of values Any valid NLS_LANGUAGE value

然后查看nls_language发现是英文的!SQL> show parameter nls_language;
NAME                                 TYPE        VALUE------------------------------------ ----------- ------------------------------nls_language                         string      AMERICAN当真正出现问题的时候,你只需要关注session级别的nls_date_language参数的值即可:如下查看

SQL> select * from nls_session_parameters where parameter='NLS_DATE_LANGUAGE';

PARAMETER                             VALUE

--------------------------------------------------------------------------------

NLS_DATE_LANGUAGE           SIMPLIFIED CHINESE

保证你的session级别的nls_date_languag是你想要的值,就没没问题!

总结:出现问题了不要去找数据的问题,因为这么大的数据量,一般都是批量导出的,更何况通过plsql developer工具执行一天数据可以成功,一般不会出现问题的,只可能是数据库的配置不一样导致。


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29654823/viewspace-2655618/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/29654823/viewspace-2655618/

你可能感兴趣的:(sqlplus执行sql文件报错)