前言
由于最近做一个项目 , 需要将 .log格式的文本文件导入到 oracle当中 。其中遇到过很多的问题 , 网上有许多的例子 ,但是对于一个没有学过 oracle 的小白来说还是有一些晦涩。
所以我特意将我找的一些相关资料进行总结一下 。
首先导入 oracle 的方法有很多 , 对于不同需求有不同的导入方式 , 我在这里就说一下 sqlldr 的方法 。 使用sqlldr 将文本文件导入 oracle中确切说只需要两步 。
第一步: 写一个 ctl 格式的控制文件
CTL 控制文件的内容 : (我会写一个模板和一个样例)
模板 :
load data -- 1. 控制文件标识
infile 'xxx.txt' -- 2. 要导入的数据文件名
insert into table test -- 3. 将文件插入到数据库的 test 表中
fields terminated by X'09' -- 4. 用于分割一行中各个属性值的符号(例如每个属性值用逗号 分割 , 那么就把 X'09' 改为 ‘ ,’)
(id , username ,passwprd ,......) -- 5. test表中对应的属性名
这五个内容是一个基本的步骤 , 注意是基本 , 基本 基本 。(重要的事情说三遍) , 导入文件的时候根据不同的需求会在不同的地方在添加一些内容 , 下面举一个我这次项目所导入的内容 。
样例:
load data
infile 'E:/user_data_one_week/zhejiang_user_data.log' -- (我的文件格式是 .log 之前上网查.log文件导入oracle的方法都没有人遇到过 , 结果我试着用文本文件的方法没想到可以导入进去)
insert into table day_data -- (我的数据库的表名为 day_data , 其中除了 insert into table 还有其他的写法 , 根据需求来 , 下面会详细写)
fields terminated by '|' --(我的数据文件每个字段也就是属性是按照 | 来分割的)
trailing nullcols (这行就是我根据需求新加入的 , 因为我的数据中某些属性可能是 null 值 , 如果不加入这行导入到数据库的时候就会自动跳过null值的列, 这样数据插入后就会属性和值对应不上)
(time, user_id, type, longitude, latitude, height, content char(10000)) (注意 : 我这里的 content 运用的类型是 clob , 但是为什么后面加了 char(10000) 下面会详细讲 , 也是一些新手会遇到的问题)
上面的样例就是我这次项目中缩写的 ctl 控制文件 。
CTL 控制文件大概已经说好了 , 但是补充几点 .
1 . 我在第三步中运用了 insert into table 还有以下几个值
- insert 为缺省方式 , 插入表中时要求表为空 , 不然会报错 (我就是总忘记在插入前清空表 , 每次都是报错提醒我我才过去删除内容的 ,吼吼)
- append , 在表中追加新纪录 , 所以表不为空插入的时候也不会报错
- replace , 删除旧记录 , 替换成新装载的记录 (明明我应该用这种方法 , 但是我对 insert情有独钟 ,好吧,我是导入完才看到有这个的)
- reuncate 同上 (也同上没用过 )
2 . 也就是我表中属性 content 的问题 -- CLOB 类型插入问题
这个问题也困扰了我好久 , 在网上找了好久才解决的 。 下面我来分享给也受这个问题困扰的小伙伴 , 如果没有需求 ,自动略过进入下一个环节。
由于数据长度比较大 , 所以表中 content 这个属性类型我用了 clob , 但是导入数据库时总报错。(错误可以在自动生成的 log.log文件中查看,下面会讲到)说我数据长度超过了定义类型的最大长度 , 这时我就纳闷了 , 我已经把类型定义为 clob了,为什么还会超过最大长度。
当使用sqlldr加载很长的字符串(超过4000)到表中的clob类型中时,老是报错: 数据文件的字段超出最大长度.查找相关资料后得知,sqlldr每次读入文件中数据流的数据类型默认为CHAR ,长度为 255。所以只要超过255字符的段都会报这个错。
解决方法很简单,在控制文件中字段后添加上char(1000000),例如:
LOAD DATA INFILE * INTO TABLE DEMO TRUNCATE FIELDS TERMINATED BY ',' (d1 , d2 char(1000000) )
其中表demo的列d2是clob类型,当然1000000只是随便用的一个大数字,只要保证加载的长度不超这个数字就成
我按照这样一改问题就解决了。
第二步 : 在 cmd 命令窗口中写入导入语句
模板:
-> sqlldr userid = 用户名 / 密码 @ 数据库名 control = 之前写的ctl控制文件的地址 bad = E:/ bad.bad log = E:/log.log
实例 :
-> sqlldr userid = everyday/123456@orcl control = E:/data.ctl bad=E:/bad.bad log = E:/ log.log
实例解释 :
由于本人还是学生 , 还没有上到 oracle , 只是学过 mysql 。 所以oracle的一些基本概念没有搞清(自己就随便借了本书简单的看了一下,理清了大小关系 : 创建用户 -- 数据库 -- 表空间 -- 表 ) , 之前在想 , 我创建用户后只对表空间进行的设置 , 并没有创建数据库啊 ,之后才知道当创建用户之后会自动生成一个数据库 , 数据库名就是 orcl 。
bad = E:/bad.bad --- 当导入文件出错时就会在 E盘生成.bad 的文件 , 里面会记录你出错误没有导入的数据
log = E:/log.log -- 当导入文件 , 会记录你导入文件详细的内容 , 包括出错的信息 (我之前导入失败 , 原因就是从这里找的)
总结一下 : oracle sqlldr导入文件只需要两步
1. 写 CTL 控制文件
2 .在 cmd 命令窗口中写入导入语句
每一步上面都有讲 , 如果没有看仔细请往上翻重新看一遍。 这里只是我导入时遇到的问题进行了全面的讲解 , 可能还会有一些不足 。 毕竟这是我第一篇文章,毕竟我还是一名学生 , 所以可能会有许多的问题没有考虑到 , 如果各位亲看到我的文章有错误也可以只出 ,我进行修改 。 写这篇文章只为分享给大家并且方面我日后查阅。希望大家共同进步