从Oracle导出数据到TXT文件从TXT文件导入数据到Oracle

article/2025/10/20 2:10:44

如果是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)
)

 


http://chatgpt.dhexx.cn/article/Dp4votPm.shtml

相关文章

oracle导出到hive,从Oracle导出数据并导入到Hive

1、配置源和目标的数据连接 源(oracle)&#xff1a; 目标(Hive 2.1.1)&#xff0c;需要事先将hive的驱动程序导入HHDI的lib目录中。 Hive2.1.1需要的jar包如下&#xff1a;可根据自身情况更换hadoop和hive的jar包。 hadoop-common-2.6.0.jar hive-common-2.1.0.jar hive-jdbc-2…

Oracle导出数据字典

由于项目是不断迭代更新&#xff0c;数据库表也是根据需求不断更改&#xff0c;导致现在数据库50多张表数据字典都没有整理&#xff0c;现在领导突然需要数据字典&#xff0c;一时很难弄出来&#xff0c;于是就想通过一个快捷的办法生成数据字典&#xff0c;具体的步骤如下&…

Oracle数据表导入导出_数据迁移用

0.背景&#xff1a;突然接到居家办公的通知&#xff0c;工作用数据全部在内网&#xff0c;需要全部拷出带走&#xff0c;最大的单个表3.7G左右。根据往常经验将Oracle库中表导出为xlsx&#xff08;方便与同事沟通使用&#xff09;&#xff0c;发现效率太低&#xff0c;且受制于…

php设置中国时区方法

当我们输出&#xff1a;echo date(Y-m-d H:i:s,strtotime(now)); 发现输出的时间和当前系统的时间不一致的时候&#xff0c;我们需要改php.ini配置文件&#xff0c;使得输出的时间和当前系统时间一致 方法一&#xff1a;php.ini配置文件中设置中国时区&#xff0c;代码如下 da…

nginx php 设置时区,laravel5.8(二十)解决时区设置差8个小时解决办法

在使用laravel日志的时候&#xff0c;发现了一个问题&#xff0c;laravel日志记录的时候&#xff0c;总是要比我当前的时间差8个小时。 在服务器端输出格式化时间&#xff0c;也是当前的时间&#xff0c;这个就有点奇怪。百度了一下。 原来从php5.1.0开始&#xff0c;php.ini里…

php配置设置时区,php如何设置时区

php设置时区的方法&#xff1a;可以使用函数ini_set(date.timezone,Asia/Shanghai)来设置时区。还可以使用函数date_default_timezone_set(‘Asia/Shanghai)来设置。 在程序PHP 5以上版本的程序代码中使用函数date_default_timezone_set(‘Asia/Shanghai);来设置时区&#xff0…

php中的时间函数(如何设置时区有4种方法)------与时间相关的函数 (time、date、m‘ktime、microtime(true)、strtotime)

1.如何设置时区:服务器默认的时间都是国家统一时间格林威治&#xff0c;所以在使用服务器前需要设置当前服务器的时区位于用于指定的时区。 设置时区&#xff1a; 1、找到php.ini文件&#xff0c;找到date.zonetime。 &#xff08;1&#xff09;date.zonetime 大洲/城市 …

php:php时区的三种设置方式

格林威治标准时间和我们的时间&#xff08;北京时间&#xff09;差了正好8个小时。如果不设置时区&#xff0c;php时间默认使用格林威治标准时间。 方法一(推荐) 在php.ini里加上找到date.timezone项&#xff0c;设置date.timezone “Asia/Shanghai”&#xff0c;重启环境就…

Telnet的简单使用

当我们在cmd客户端输入telnet ip的时候&#xff0c;会提示telnet 不是内部或外部命令的错误&#xff0c;这是因为我们的Windows系统的Telnet客户端程序没有开启。例如&#xff1a; 1. 开启Windows系统的Telnet客户端 1&#xff09; 打开控制面板&#xff0c;点击程序功能&…

Ubuntu18.04系统如何安装和使用telnet工具

在ubuntu18.04中如何安装和使用telnet工具呢?本文给出详细说明。 1.更新软件列表 sudo apt update 2.安装telnet服务 sudo apt install openbsd-inetd telnetd 3.查看telnet运行状态 netstat -a | grep telnet 4.登录测试 telnet 127.0.0.1

【Windows篇】Telnet指令介绍以及telnet测试端口连接示例

演示环境 1.VMware Workstation16虚拟机 2.windows10企业版镜像 前言 Telnet是Internet远程登录服务的标准协议和主要方式&#xff0c;最初由ARPANET开发&#xff0c;现在主要用于Internet会话&#xff0c;它的基本功能是允许用户登录进入远程主机系统。telnet程序是基于TELN…

Telnet协议抓包-工具Wireshark

虚拟机与物理机都进行的操作&#xff0c;打开控制面板 --> 点开程序 --> 点开“打开或关闭Windows功能”&#xff0c;在虚拟机设置telnet服务端&#xff0c;在物理机设置telnet客户端。 在虚拟机进行如下操作&#xff1a;WindowsR --> 输入services --> 进入到服务…

Telnet介绍及其安装

Telnet是一种协议&#xff0c;其是TCP/IP协议族中的一员&#xff0c;是Internet远程登录服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的能力。 Windows 系统自带了基于Telnet协议的程序&#xff0c;包括服务端程序和客户端程序&#xff0c; 所以习…

win10环境下的telnet工具使用(客户端和服务端)

开启服务 默认情况下win10里telnet工具是不开启的 如何开启telnet工具&#xff0c;网上有诸多教程&#xff0c;但是win10环境下的telnet工具是被阉割过的&#xff0c;只有客户端程序&#xff0c;即能在本机通过telnet访问其他主机&#xff0c;但是没有服务端程序&#xff0c;即…

【高效开发工具系列】Windows 怎么使用 telnet

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…

推荐一款好用的telnet工具

常用telnet的人可能都知道secureCRT这款工具&#xff0c;支持多标签&#xff0c;密码保存等功能&#xff1b;可是它是共享软件&#xff1b;于是很多人就用putty来代替它&#xff1b; putty小巧好用&#xff0c;不过和secureCRT相比不支持密码记忆和多标签功能。今天我向大家推…

批量ping及telnet工具

批量ping及telnet工具 批量ping及telnet工具说明界面使用方法工具下载链接 批量ping及telnet工具说明 这款工具针对一个网段批量ping测试和对同一网段内指定端口的telnet测试。适合用于测试一个网段的机器有没有开放特定端口&#xff0c;防火墙策略检测&#xff0c;或是否打开…

电脑telnet工具如何开启

打开电脑Telnet 打开电脑----开始---控制面板----程序和功能----打开或关闭WINDOWS功能----TELNET 客户端勾选&#xff0c;并点击确定。 Telnet工具的使用 点击开始----运行----输入CMD&#xff08;打开命令窗口&#xff09;&#xff0c;直接输入telnet IP&#xff08;设备I…

Linux删除文件夹权限不够

第一种&#xff1a;文件夹有锁 使用命令 sudo chmod 777 test 给与这个test文件夹读写权限。 即可去点文件夹的锁&#xff0c;然后可以删除 第二种&#xff1a;文件夹没有锁&#xff0c;却还是不能删除&#xff0c;提示权限不够 这种情况&#xff0c;文件夹的属性-权限如下如…

linux给文件夹添加查看密码是什么,Linux如何给文件夹设置密码

电脑里经常会存储着重要文件,这些文件需要进行加密,有许多方法来实现。但是你知道在Linux里面怎么给文件夹加密码?下面跟着学习啦小编一起来了解一下吧。 Linux如何给文件夹设置密码 Cryptkeeper是一个Linux系统托盘小应用程序,可以管理经过加密的文件夹。在它下面的EncFS则…