shell通过spool方式将oracle数据进行数据入湖

830 阅读3分钟

背景

业务表需要根据数据湖要求将数据库表中的数据按照指定格式导出到文件中,在基础数据平台维护好表的相关信息,主要介绍导出到文本中的实现方案思路

名词解释

数据文件格式:数据要求数据导出以|+|进行字段分隔,|+|/n进行行换行,每条记录是一行,最终以.dat命名

实现思路

数据库导出常见的基本是varchar、date、timestamp、number、int、float,特殊类型有clob、blob、long类型

oracle导出比较快速的基本就是sqlplus登入,数据导入用sqldr,导出数据基本就是spool

方案一

直接通过spool导出到dat中,设置导出分隔符为|+|即可

方案二

导出sql语句直接将字段拼接好,直接导出,sql语句直接设置好分隔符

方案对比

方案一导出字段之间可能会有空格,导出效率一般,同时导出后需要针对字段之间的空格做处理,同时spool有单行导出32767的长度限制,所以建议是方案二,方案二主要是字段处理可以直接在导出sql进行定制化导出,灵活方便。

导出语句:

image.png

注意事项

1.linesize默认是80长,超过会被截取,最大可以设置32767,值越大,导出速度越慢,长度1000,每秒可以导出30000条数据;

2.要把控制台输出显示关闭,同时设置导出参数都好用,我的怎么操作就行不行,干脆 >/dev/null 2>&1

 

看着似乎没啥问题,但是数据库clob字段怎么处理,一种方式是dbms包转化下,但是有个问题是超过4000长度会报错,这是这个包的问题,但是应该如何处理呢?这个需要好好思考下,可以换个思路,先把数据导出看看是什么格式嘛,于是导出看了下,不论什么字段和clob字段一拼接都变成了clob类型了,也就是会出现一行数据在多行中,既然文本能导出来,那就好办了了,中间遇到的就不细说了,综合来看就是结合sql和shell共同处理,彼此只做最擅长的,也可能是鄙人shell全靠百度哈,大神可以自行处理。

针对clob字段的思路就是

1.sql导出最后是以|CLOB|结束

2.shell读取导出的内容到临时文件中,读取到CLOB作为单条记录结束标记

3.将clob再替换成要求的+符号

注意

第二步,简单的方式可以直接将换行全部去掉,这样数据就一行了,然后通过sed再将clob替换成换行,想想其实也没问题,但是正好遇到导出的文件有16M,这个可以百度查询一下,sed是以行为基础进行替换,一行16M,这个效率显而易见了。至此整体思路已经完成了。

文本读取判断的时候注意if判断的时候要先将当前行和原有内容拼接后判断是否存在clob,因为导出的CLOB字段有可能被截断成两行

导出语句:

image.png

总结一下

1.虽然是导出数据库的内容,但是有时候第一步先把数据导出,其他再用shell思维方式处理

2.各自做擅长的,相信所有的方式都是最简单的方式,如果复杂了,那一定是思路要转换一下了