如果是txt文件的数据导入oracle中,数据量大的话用pl/sql会卡死,那么就要用到sqlload命令。

前两天在做一个不算任务的任务,用shell脚本将数据库中的数据导出到文件,在万能的百度上找了一些资料,自己亲手实践了一番,脚本语言又有长进。从数据库导出数据到TXT文件,完全OK,那么从TXT文本导入到数据库又怎样操作呢?于是又上万能的度娘,又亲手实践了一上午,发现网上的不少例子很好,但是不尽详细,还是要靠自己理解,因此将学习的经验和结果记录如下。

1.Oracle导出到TXT文本

从Oracle导出数据到TXT文本,是很容易的,这里用到spool,通过spool 命令,可以将select 数据库的内容写到文件中,通过在sqlplus设置一些参数,使得按指定方式写到文件中。

常规使用spool方法,将set的一些命令和spool,select等放入.sql脚本中,然后再sqlplus中运行该脚本。

例如以下设置就是常用的模式,只要将文件名和SQL替换成你自己的就可以正常使用。

set line 1000         --设置行的长度
set pagesize 0        --输出不换页
set feedback off      --默认的当一条sql发出的时候,oracle会给一个反馈,比如说创建表的时候,如果成功命令行会返回类似:Table created的反馈,off后不显示反馈
set heading off       --不显示表头信息
set trimspool on      --如果trimspool设置为on,将移除spool文件中的尾部空
set trims on          --去掉空字符
set echo off;       --显示start启动的脚本中的每个sql命令,缺省为on
set colsep ','         --设置分隔符
--set termout off        --不在屏幕上显示结果
spool db1.txt          --记录数据到db1.txt
select * from UCR_PARAM.STUDENT2_TEMP;  --导出数据语句
spool off              --收集完毕
exit

使用表student2来做测试,student2的表结构如下:

SQL> desc student2;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 SID                                       NOT NULL NUMBER(10)
 SNAME                                     NOT NULL VARCHAR2(20)
 SAGE                                      NOT NULL NUMBER
 SSEX                                      NOT NULL CHAR(2)
 SADDRESS                                  NOT NULL VARCHAR2(20)
 SBIRTH                                             DATE
 REMARK                                             VARCHAR2(200)
 GRADUATION_DATE                                    DATE

表内的数据:REMARK和GRADUATION_DATE字段为null

下面将使用标准shell脚本连接数据库并将数据导出到TXT,通常的步骤是:

1.在shell脚本设置好对应的TXT文件路径及文件名,SQL语句,log路径等。

2.sqlplus连接数据库,这里使用-s简单模式,连接上以后不输出任何内容,这样可以直接使用spool导出结果到文件

3.设置导出的格式,字段,空格等

注意,以下脚本set部分虽然有去空格,但是空格任然存在,最好在结束使用命令将所有空白字符去除

#去除文件开头的空格及中间的空白字符

#去除文件开头的空格及中间的空白字符
sed -i 's/ //g' ${work_path}/stu_${file_date}.txt

完整的 dbout.sh,前面为注释和举例,核心功能从 sqlplus开始

#!/usr/bin/bash#多行注释
:<<BLOCK
set line 1000         --设置行的长度
set pagesize 0        --输出不换页
set feedback off      --默认的当一条sql发出的时候,oracle会给一个反馈,比如说创建表的时候,如果成功命令行会返回类似:Table created的反馈,off后不显示反馈
set heading off       --不显示表头信息
set trimspool on      --如果trimspool设置为on,将移除spool文件中的尾部空
set trims on          --去掉空字符
set echo off;       --显示start启动的脚本中的每个sql命令,缺省为on
set colsep '|'         --设置分隔符
--set termout off        --不在屏幕上显示结果
spool $filename          --记录数据到db1.txt
$sqlinfo2;  --导出数据语句
spool off              --收集完毕
exit
BLOCK
#可以在这里拼接语句,用|或;,但是逗号,拼接','不行
#逗号拼接可以在后面的sqlplus中设置列分隔符:set colsep ','
sqlinfo="select  B.ORDER_ID||';'||B.PEER_ORDER_ID||';'||B.BUSI_CODE||';'||B.ACCOUNT_CODE||';'||A.TRADE_FEE||';'||A.RECEIPT_FEE||';'||A.RATE_FEE||';'||A.BUSI_CODE||';'||A.PAY_STATUS||';'||to_char(A.CHECK_DATE, 'yyyy-mm-dd') from ucr_cen.UPG_ORDER_PAY_DETAIL A,ucr_cen.I_UPG_ORDER_TMP BWHERE B.MERCHANT_ID = '510915'AND B.PEER_ORDER_ID != '-1'AND A.CHECK_STATUS IN ('0','2','3')AND A.STATE = 'U'AND A.PAY_STATUS = '1'AND A.CHECK_DATE BETWEEN TRUNC(SYSDATE-1) AND TRUNC(SYSDATE)-1/86400 AND A.ORDER_ID = B.ORDER_ID;"#以上为举例和注释,核心功能从这里开始
sqlinfo2="select SID,SNAME,SAGE,to_char(GRADUATION_DATE,'yyyy-mm-dd'),SSEX,SADDRESS,REMARK,to_char(SBIRTH,'yyyy-mm-dd') from UCR_PARAM.STUDENT2;"
#sqlinfo2="select SID,SNAME,SAGE,to_char(GRADUATION_DATE,'yyyy-mm-dd'),SSEX,SADDRESS,to_char(SBIRTH,'yyyy-mm-dd'),REMARK from UCR_PARAM.STUDENT2;"
#不设置拼接时,使用逗号分隔符 set colsep ',' ,当该列为空时会返回占位的空白字符,一般此种情况用于后续将TXT文本直接导入数据库方便
start_time=`date +%Y%m%d%H%M%S`
work_path=/home/billing/user/zhf/test
DbCon=用户名/密码@所属组
file_date=`date +%Y%m%d`
filename=${work_path}/stu_${file_date}.txt;echo "----------------  start to exec job   $start_time "
echo "----------------  sqlinfo = $sqlinfo2 "
#echo "----------------  start to exec job   $start_time ">>${work_path}/$start_time.log
#echo "----------------  sqlinfo = $sqlinfo2 ">>${work_path}/$start_time.log
echo "----------------  connect to $DbCon and try to exec sql..."
#echo "----------------  connect to $DbCon and try to exec sql...">>${work_path}/$start_time.logsqlplus -S $DbCon<< EndSql
set line 1000
set pagesize 0
set feedback off
set heading off
set trimspool on
set trims on
set echo off
set colsep ','
--set termout off
spool $filename
$sqlinfo2
spool off
exit
EndSql
#去除文件开头的空格及中间的空白字符
sed -i 's/ //g' ${work_path}/stu_${file_date}.txt
end_time=`date +%Y%m%d%H%M%S`
echo "----------------  cmd end , please check te result $end_time"
#echo "----------------  cmd end , please check te result $end_time">>${work_path}/$start_time.log

导出的结果,注意,两个逗号,,分隔的字段没有内容即为null值 ,此处该两个null字段在中间,不在结尾,后面将看另一种情况:即null字段在结尾的情况下

生成文件暂命名为:stu_20190810.txt

1,lily,24,,M,Shanxi,,1993-01-14
2,kity,17,,WM,Shanxi,,2001-01-14
3,bobo,27,,WM,Shanxi,,1991-01-14
4,anna,29,,WM,Shanxi,,1989-01-14

2.从TXT文本导入Oracle数据表

从TXT文本文件导入数据库其实也简单,格式依然是固定sqlldr的控制文件

我们先新建一张表student3

create table UCR_PARAM.STUDENT3 as select * from UCR_PARAM.STUDENT2 where 1=2;

--将字段GRADUATION_DATE修改为varchar类型,因为该字段为null,在插入时,date转换不接受null,因此用varchar来接收

alter table UCR_PARAM.STUDENT3 modify GRADUATION_DATE varchar2(14);

student3表结构如下:

打开一个.ctl文件,插入以下内容

vi tb_sqlldr.ctl

load data
infile 'stu_20190810.txt' --数据来源文本
APPEND into table ucr_param.STUDENT3-- 原先的表有数据 就加在后面
--INSERT into table ucr_param.STUDENT3-- 装载空表 如果原先的表有数据 sqlloader会停止 默认值
--REPLACE into table ucr_param.STUDENT3-- 原先的表有数据 原先的数据会全部删除
--TRUNCATE into table ucr_param.STUDENT3-- 指定的内容和replace的相同 会用truncate语句删除现存数据
fields terminated by "," --4、字段终止于X'09',是一个制表符(tab) (id,name) --定义对应的字段名称,注意顺序
TRAILING NULLCOLS --如要导入源文件此列内容为空,在导入到数据库表中,此列内容就是null
--读取的TXT字段对应数据库中的字段,注意顺序要与TXT字段顺序一直
(SID    "to_number(:SID)" ,
SNAME   ,
SAGE    "to_number(:SAGE)" ,
GRADUATION_DATE "NVL(:GRADUATION_DATE, '未知')",--"NVL(to_date(:GRADUATION_DATE, 'yyyy-mm-dd'),'NULL')", date为null时插入行不通,date函数不接受null值,因此修改表结构
SSEX    ,
--NULLIF (expr1, expr2),若expr1和expr2相等,返回NULL;不相等,等返回expr1
SADDRESS "NULLIF(:SADDRESS,'NULL')",
--NVL(expr1,expr2),若expr1为null, 返回expr2; 不为null,返回expr1。  注意:两者类型要一致
REMARK "NVL(:REMARK,'NULL')",
SBIRTH  date"yyyy-mm-dd" ) -- coulmun

注意,此处GRADUATION_DATE和REMARK字段为null,那么这一句就很重要 ,否则sql loader 读取到null值,插入时会报错

TRAILING NULLCOLS --如要导入源文件此列内容为空,在导入到数据库表中,此列内容就是null

date类型的数据插入时可以使用两种方式插入:

SBIRTH    date"yyyy-mm-dd" 或 SBIRTH    "to_date(:SBIRTH, 'yyyy-mm-dd')"

注意,读取的字段内容为空的,加入该字段判断:

--NVL(expr1,expr2),若expr1为null, 返回expr2; 不为null,返回expr1。  注意:两者类型要一致
REMARK "NVL(:REMARK,'NULL')"

新建一个shell脚本调用该控制文件,dao.sh

#!/bin/ksh
#注意,顶行是固定格式
sqlldr userid=数据库名/密码@所属库 control=tb_sqlldr.ctl

调用:dao.sh

结果验证:

另一种情况,导出的TXT文件null字段刚好在行尾

放开dbout.sh的另一种sqlinfo2的情况

生成的TXT文件结果:行尾有逗号

1,lily,24,,M,Shanxi,1993-01-14,
2,kity,17,,WM,Shanxi,2001-01-14,
3,bobo,27,,WM,Shanxi,1991-01-14,
4,anna,29,,WM,Shanxi,1989-01-14,

调整ctl控制文件的字段顺序,也可以导入:

load data
infile 'stu_20190810.txt' --数据来源文本
APPEND into table ucr_param.STUDENT3-- 原先的表有数据 就加在后面
--INSERT into table ucr_param.STUDENT3-- 装载空表 如果原先的表有数据 sqlloader会停止 默认值
--REPLACE into table ucr_param.STUDENT3-- 原先的表有数据 原先的数据会全部删除
--TRUNCATE into table ucr_param.STUDENT3-- 指定的内容和replace的相同 会用truncate语句删除现存数据
fields terminated by "," --4、字段终止于X'09',是一个制表符(tab) (id,name) --定义对应的字段名称,注意顺序
TRAILING NULLCOLS --如要导入源文件此列内容为空,在导入到数据库表中,此列内容就是null
(SID    "to_number(:SID)" ,
SNAME   ,
SAGE    "to_number(:SAGE)" ,
GRADUATION_DATE "NVL(:GRADUATION_DATE, '未知')",--"NVL(to_date(:GRADUATION_DATE, 'yyyy-mm-dd'),'NULL')",
SSEX    ,
--NULLIF (expr1, expr2),若expr1和expr2相等,返回NULL;不相等,等返回expr1
SADDRESS "NULLIF(:SADDRESS,'NULL')",
SBIRTH  "to_date(:SBIRTH, 'yyyy-mm-dd')" ,
--NVL(expr1,expr2),若expr1为null, 返回expr2; 不为null,返回expr1。  注意:两者类型要一致
REMARK "NVL(:REMARK,'NULL')") -- coulmun

注意,如果表字段数据类型数长字符串,大于255时,在导入的时候需要指定导入字段的最大长度,否则会因为导入字段超过255时超长失败。导入的字段指定长度如下,且要使用char定长类型

(COLL_HOST char(32),
WARN_INFO       char(2000),
UPDATE_TIME     char(32)
)

从Oracle导出数据到TXT文件从TXT文件导入数据到Oracle相关推荐

  1. 把json数据导入linux,使用json文件给es中导入数据

    使用json文件可以给es中导入数据,10万条左右的数据可以一次导入,数量太大时导入就会报错.大数量的到导入还是需要用bulk方式. accounts.json文件格式如下: {"index ...

  2. 图解SSIS监视文件夹并自动导入数据

    放假的第三天,也是最后一天.今天去活动了一下,打了一下羽毛球.好久没运动拉,感觉和前几年不一样. 今天没有什么看技术文章,不过有个疑问就是男女之间的感情和婚姻是同一件事吗?我不知道,也不太想去知道. ...

  3. 《项目经验》--简单三层使用DataTable向数据库表批量导入数据---向SqlServer多张张表中导入数据

    前面已经介绍过如何向数据库的一张表中批量导入数据,详情见博客<项目经验---简单三层使用DataTable向数据库表批量导入数据---向SqlServer一张表中导入数据>:本文主要介绍如 ...

  4. Java导出Excel模板,导出数据到指定模板,通过模板导入数据(一)

    本文章主要是介绍阿里巴巴的easyexcel的使用 1. 首先需要我们导入easyexcel的依赖包 <!-- alibaba/easyexcel 使用高版本,低版本string接收数字丢小数位 ...

  5. oracle导出用户下单表或者多表,导入到别的服务器用户下

    导出 exp 用户名/密码 file=存放dmp的名称的目录 statistics=none tables =(表名,表名,表名) exp creditfw/credit file=d:\test.d ...

  6. django通过openpyxl操作excel文件,实现批量导入数据到数据库。

    1.在一些场景中经常需要管理员批量导入数据,先将数据写到excel表格中,再上传到系统上,最后将excel中的数据批量导入到系统的数据库中. 1.1.test.xlsx文件数据格式 首行的名字:必须是 ...

  7. dump导入oracle需要提前建表吗_Oracle使用dump导入数据

    导入前准备 建立导入用户 CREATE USER YYBS_IMPIDENTIFIED BY YYBS_IMPDEFAULT TABLESPACE USERSTEMPORARY TABLESPACE ...

  8. mysql导入数据提前修改字段_复习MySQL③导入数据、检查及修改

    导入数据: 用insert into语句为表插入数据: - insert into 表名(字段1,字段2,-) values -- 导入外部文本文件: - 导入外部txt文件(导入CSV文件分隔符为' ...

  9. c datatable导入mysql_《项目经验》–简单三层使用DataTable向数据库表批量导入数据—向SqlServer一张表中导入数据 | 学步园...

    向数据库的一张表中添加数据,可以采用单个添加,即一条数据.一条数据的添加:也可以采用批量导入,依次将好些条数据写入数据库的一张表中.文本借助实例<添加系列信息>讲解一种向数据库批量导入数据 ...

  10. MySQL导入数据,存在外键约束不能导入数据的处理方式

    我们通常导入数据脚本的时候会遇到如下错误: 1451 -Cannot delete or update a parent row: a foreign key constraint fails (.. ...

最新文章

  1. 解决:geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic
  2. python3 字符串、十六进制字符串、数字、字节之间的转换
  3. HDU 4323 Magic Number(编辑距离DP)
  4. 使用Installshield制作asp,asp.net应用的安装程序
  5. 10 门必修的机器学习名校公开课,旨在完善你的 AI 学习路线!
  6. 关于node-sass和sass-loader安装上去的时候的时候报错的问题
  7. 动态列排序_Excel表格利用函数制作排序器(可依据不同字段、升降序排序)
  8. 面向Linux的10款最佳剪贴板管理器
  9. java for(o t :object) 获取顺序号_JAVA泛型通配符T,E,K,V区别 瞬间豁然开朗
  10. 使用linux_使用 AppImage 进行 Linux 软件包管理 | Linux 中国
  11. Python 字典(dict)操作(update)、翻转字典
  12. 9.企业应用架构模式 --- 领域逻辑模式
  13. AllenNLP之入门解读代码
  14. 基于华为路由器实现NAT
  15. esp8266 python 74hc595_十九 ,ESP32 74HC595 的使用
  16. C++:实现量化基础互换利率basis swap rate helpers测试实例
  17. 研究方向之智慧仓储与物流及相关算法
  18. 外企就很舒服?聊聊我在外企的工作体验
  19. mysql时间分钟比较_MySql中时间比较方法 周 小时 分钟
  20. Err: HLS C Simulation Run 按钮变为灰色

热门文章

  1. python人机交互界面设计_python_GUI页面开发
  2. 怎么用Microsoft Toolkit激活Office/win7/win8
  3. QQ显IP显隐身制作原理介绍转)
  4. date js 减去_如何从Javascript中减去10天的日期
  5. Django学习笔记(二):MTV架构学习及使用步骤
  6. 用Tera Term取代Windows上的超级终端
  7. enq: TX - index contention
  8. 【C/C++】题解:从三子棋到多子棋
  9. QT 实现功能菜单的隐藏和显示
  10. Android 外卖订餐APP开发