使用sqlldr导入多个csv数据到Oracle中,对数据中存在空格的处理

本周公司分配任务,将一个导入数据的任务分配给了我,要求使用sqlldr导入oracle数据库,本人是Java程序员,从来没听说过sqlldr(各位大神莫嘲笑~),在网上搜了几天,终于搞定了,一些小心得分享给大家。

需求:使用java定期定时自动将多个.csv的数据导入到一张oracle表中,处理掉里面的一些垃圾数据。

在网上搜了下sqlldr,现学现卖写了下:

 

ctl文件如下:

LOAD DATA    
INFILE 'c:\sqlldr\data1.csv'     
REPLACE INTO TABLE T_TEST
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
(A,B)

 

data1.csv中的数据共有3列,我只将其中两列导入到数据库中,数据库中对应的字段分别为A和B。把ctl文件放入指定的文件夹中,待启动文件使用。

注:ctl文件是指后缀是.ctl结尾的文件。

 

启动文件如下:

sqlldr test/test@orcl control=C:\sqlldr\sqlldr_impdata.ctl log=C:\sqlldr\sqlldr.log

 

启动文件会调用上面编写的ctl文件,并在文件夹里生成log日志。

注:启动文件在cmd命令行里执行。

 

注意!成功后指示将一个csv文件导入到了数据库中,而我们的需求是将多个csv文件导入到系统!

 

我的第一个想法是循环将csv文件导入到系统,但是很快我觉得这样做不现实!原因是我的需求是要由机器去导入数据,不需要人工来修来ctl文件、启动文件。

如果使用机器来模拟人工的这种方式做的,需要反复的修改ctl文件,再反复的执行启动文件,实现起来比较麻烦,故果断pass,寻找其他方案。

 

又在网上查了下(哈哈,总去网上查),想想可以不可以找到使用sqlldr一次性导入多个csv数据的方案,结果有点失望啊~~sqlldr不支持同时使用多个数据源导入一张数据库表的方式(至少我没有找到T_T)

比如:下面这种方式,是不支持的!!!一定注意,是不支持的!!

LOAD DATA    
INFILE 'c:\sqlldr\data1.csv'     
INFILE 'c:\sqlldr\data2.csv' 
INFILE 'c:\sqlldr\data3.csv' 
INFILE 'c:\sqlldr\data4.csv' 
REPLACE INTO TABLE T_test TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
(PAYSYSBANKCODE,IBPSNAME)


不过找到了一种其他的方式来解决这个问题:既然sqlldr只支持单个文件进行导入的话,那可不可以把多个csv文件整合成一个来导入呢?

 

答案是可以的!

 

可以使用批处理的方式来处理多个csv文件,将多个csv文件整合成一个txt文件,再导入到数据库中!(⊙﹏⊙b汗,原谅我的无知吧,阿门~~我也从来没用过批处理。。。)

 

批处理代码如下:

for /r C:\sqlldr %%a in (*.csv) do type "%%a" >>%%~dpanewcsv.txt


注:把批处理的代码放在一个txt里面,再把后缀改成.bat文件。直接回车就可以执行了。

 

执行成功后生成了一个名为newcsv.txt的文件,里面包含了所有csv文件中的数据,按照我们预先约定的方式顺利导入到数据库~~当当当当~~问题出现了!!!


在以这种方式导入到数据库中的数据,有一点问题,由于我要处理掉一些垃圾数据,这些垃圾数据是由一些字母和星号***构成的,正确的数据是由数字构成的,故我要编写sql来删除掉这样的垃圾数据。

 

搜索不是数字的sql如下:

select * from t_test where trim(translate(A,'0123456789',' ')) is not NULL;

 

执行后我发现居然不好使!!这个sql是绝对没有问题的,是正确的,那么问题是出现在哪里了呢?没错,是数据的错误!

我发现导入的数据里每个数据后面都会有一串空格,我试着用trim来去掉这些空格,但是不好用,这非常奇怪,我又查看了刚才我们用批处理生成txt文件,发现这里面的数据是有问题的,每个数据后面都有空格!!

 

所以我采取了在导入时,使用sqlldr自带的去空格的功能,代码如下:

LOAD DATA    
INFILE 'c:\sqlldr\newcsv.txt'     
REPLACE INTO TABLE T_TEST
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
(A "trim(:A)",B)

 

但是很可惜,不好用= =#,居然自带的trim功能不好用,我开始重新审视在数据库中的数据,到底为什么不好用呢?难道数据库里存的空格,根本就不是空格?!

 

答案是正确的,它确实不是空格(= =#大爷的)

我使用了如下的sql如查询这一行的数据到底是什么:

select dump(t.A) from t_test t;

结果如下:

Typ=1 Len=13: 48,48,49,53,48,56,51,54,51,56,56,50,9
Typ=1 Len=13: 48,48,49,53,48,56,52,54,51,56,57,54,9
Typ=1 Len=13: 48,48,49,53,48,56,53,54,51,56,51,51,9


但是我的数据只有12位,说明最后多出来的一位就是问题所在了。

又去网上查了下。。。发现这个多出来的9,根本就不是空格,引文如下:

 

chr(32)是空格;
chr(8、9、10 和 13)可以分别转换为退格符、制表符、换行符和回车符。这些字符都没有图形表示,但是对于不同的应用程序,这些字符可能会影响文本的显示效果。

 

哈哈,原来不是正常的空格,故无论是在oracle中,还是在sqlldr中的,所有的trim功能都是无效的。。。

 

使用如下语句,把这个多出来的9干掉就好了:

update t_test set A = replace(A, chr(9), '');


把多出来的9换成了空,以上问题就解决了。。。这个需求真累啊,折腾了一大圈,不过有点收获还是好的^_^!

 

以上,可能有错误的地方,欢迎大家批评指认,毕竟我都sqlldr和批处理都没接触过,写这篇文章希望可以帮助到和我一样没接触过的人。


另,由于本人没接触过批处理,没有使用修改批处理的方案来解决问题,请大家见谅。

 

 

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要将MySQL数据快速导入Oracle,可以采用以下步骤: 1. 在MySQL使用SELECT语句查询要导出的数据,并将其保存为CSV文件。 2. 在Oracle创建一个与MySQL数据表结构相同的表。 3. 使用OracleSQL Loader工具将CSV文件导入Oracle。 具体步骤如下: 1. 在MySQL使用SELECT语句查询要导出的数据,并将其保存为CSV文件。例如,使用以下命令将MySQL数据导出到CSV文件: SELECT * INTO OUTFILE '/path/to/file.csv' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' FROM mysql_table; 2. 在Oracle创建一个与MySQL数据表结构相同的表。例如,如果MySQL表名为mysql_table,可以使用以下SQL语句在Oracle创建一个相同结构的表: CREATE TABLE oracle_table ( column1 datatype, column2 datatype, ... ); 3. 使用OracleSQL Loader工具将CSV文件导入Oracle。例如,使用以下命令将CSV文件导入Oraclesqlldr username/password control=/path/to/controlfile.ctl 其,/path/to/controlfile.ctl是一个包含SQL Loader控制文件的路径。控制文件定义了如何将CSV文件数据映射到Oracle的列。例如,以下是一个控制文件的示例: LOAD DATA INFILE '/path/to/file.csv' INTO TABLE oracle_table FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS (column1, column2, ...) 注意,以上步骤可能需要根据具体情况进行调整,例如可能需要在MySQLOracle之间进行数据类型映射。同时,由于MySQLOracle的语法和功能存在差异,可能会出现一些数据转换或兼容性问题。因此,在实际操作需要进行适当的测试和验证,确保数据导入正确无误。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值