赞
踩
遇到的问题:需要跨服务器将数据处理到另一台数据库,数据为百万级,凭借代码获取导入时间过慢
处理方法:利用oracle提供的官方数据sqlldr
下载好以后解压,会得到一个命名为instantclient_19_17的文件夹,打开里面会有sqlldr.exe的文件
#此处我输入时提示【无法启动此程序,因为计算机中丢失VCRUNTIME140.dll】,于是还要下载Windows插件:vs_redist_x64下载地址
安装完成会显示如下图数据
1、 首先编辑执行脚本文件,文件名:load_csv_data.ctl
- options(skip=1)
- load data
- CHARACTERSET UTF8
- infile 'D:\dir1\dir2\20221205\part-001.csv'
- append into table "table_name"
- WHEN status = 'used'
- fields terminated by '|'
- TRAILING NULLCOLS
- (id,name,age,address,col01,col02)
释义
options(skip=1) #跳过第一行(一般用于文件首行为表头的情况)
load data
CHARACTERSET UTF8 #设置编码格式(当导入数据库数据出现中文乱码时设置此行)
infile 'D:\dir1\dir2\20221205\part-001.csv' #导入文件的路径
infile 'D:\dir1\dir2\20221205\part-002.csv' #可多行
append into table "table_name" #对应的数据库表名
WHEN status = 'used' #过滤数据条件
fields terminated by '' #导入文件数据分隔符,看文件内容更换
TRAILING NULLCOLS #遇到空值也作插入,没有此行大概率会报错
(id,name,age,col01,col02) #对应的表中字段名,与导入文件数据列顺序需一一对应
part-001.csv(或part-002.csv)文件内样式为:
2、 使用命令行执行脚本
sqlldr userid=test/1234@127.0.0.1:3363/dbname control=D:\脚本\load_csv_data.ctl log=log\load_csv_data.log
释义:
sqlldr userid=数据库登录用户名/登录密码@数据库服务器ip:端口/数据库名 control=ctl文件存放文职 log=日志打印位置
在sqlldr.exe存放路径下执行上述命令就可以了~~~
- 记录 28616836: 被拒绝 - 表 "TABLE_NAME" 的列 ADDRESS 出现错误。
- 数据文件的字段超出最大长度
上述报错是指ADDRESS这个字段对应的导入数据内容超过缓存默认长度
因此需要指定该字段默认大小
- options(skip=1)
- load data
- CHARACTERSET UTF8
- infile 'D:\dir1\dir2\20221205\part-001.csv'
- append into table "table_name"
- WHEN status = 'used'
- fields terminated by '|'
- TRAILING NULLCOLS
- (id,name,age,address CHAR(1024),col01,col02)
动态更改导入文件路径,脚本执行自动获取文件并导入至oracle数据库中,使用bat脚本以及
1、 按照oracle表中字段以及引入文件数据对应位置,编写模板脚本,其中入参为可变项,即infile,自定义参数名,用于注入替换文本。
load_data_temp.ctl
- options(skip=1)
- load data
- CHARACTERSET UTF8
- infile 'datafilename'
- append into table "table_name"
- WHEN status = 'used'
- fields terminated by '|'
- TRAILING NULLCOLS
- (id,name,age,address CHAR(1024),col01,col02)
2、 (此步骤非必要,看自己对文件位置要求)设置执行脚本文件存放位置,即在你想要放执行文件的位置新建文件夹,此处我新建为tableName文件夹底下的tableNameCTLs文件夹存放生成的执行脚本,此路径在稍后的bat脚本编写时会用到,不设置则会在bat脚本执行文件夹下。
3、 编写执行脚本
getCSV&InsertDB.bat
- setlocal enabledelayedexpansion
- ::下列步骤为生成yyyyMMdd格式字符串,根据实际情况是需要与否
- ::获取年
- set yyyy=%date:~0,4%
- ::获取月
- set mm=%date:~5,2%
- ::获取日
- set dd=%date:~8,2%
- ::若天数为个位数数字,去掉前面的0,转换为数字进行后续的计算
- if "%dd:~,1%"=="0" set dd=%dd:~1%
- ::将天数强转为数字计算,此处减一为获取当前天数前一天的日期
- set /a od=!dd!-1
- ::如果减一到最后变成0,则从头开始
- if !od!==0 call :dd0
- if !mm!==0 call :mm0
- ::如果生成的数字小于10为个位数数字则前面拼接一个0,拼接为正确格式
- if !od! lss 10 (set od=0!od!)
- if !mm! lss 10 (set mm=0!mm!)
- ::CURRENT_DATE_STRING为生成的符合要求格式的字符串
- set CURRENT_DATE_STRING=!yyyy!!mm!!od!
- ::拼凑指定路径,按需拼凑
- set DestPath=D:\dir1\dir2\%CURRENT_DATE_STRING%
- ::指定路径下文件格式
- set DestExt=*.csv
- ::清空生成文件内容,防止拼接进垃圾字符串
- type nul > D:\bats\tableName\tableNameCTLs\load_data_%CURRENT_DATE_STRING%.ctl
- ::指定初始位置,为指定循环次数位置进行操作做准备
- set num=1
- ::开始按行循环模板文件,逐行拼接,并在指定行替换上述拼凑的链接
- for /f "usebackq delims=" %%k in ("D:\bats\tableName\load_data_temp.ctl") do (
- ::获取当前行,进行相应的处理后写入生成的新的执行文件中
- set "line=%%k"
- ::要替换的文本位置在模板文件第四行,因此写死为第四行执行以下步骤
- if !num! == 4 (
- ::,根据sqlldr文件性质,infile文件可以多行去执行多个文件的写入,所以打开存放需要导入至数据库的文件的路径,循环底下指定格式文件,并拼接写入生成的执行文件中
- for /f "usebackq delims=" %%i in (`dir /b/a-d/s "%DestPath%\%DestExt%"`) do (
- ::重新获取需要替换的行,避免下一个循环需要替换的自定义字段已经被替换掉了
- set "line=%%k"
- ::获取该行中自定义的datafilename字段并替换为此循环获取的文件下载链接位置
- set "line=!line:datafilename=%DestPath%\%%~nxi!"
- ::遍历写进生成的新执行文件中
- echo !line!>>"D:\bats\tableName\tableNameCTLs\load_data_%CURRENT_DATE_STRING%.ctl"
- )
- ) else (echo !line!>>"D:\bats\tableName\tableNameCTLs\load_data_%CURRENT_DATE_STRING%.ctl")
- ::行数加一执行下一行
- set /a num+=1
- )
- ::执行文件生成结束后,执行该命令写入数据库中,并在指定的log位置生成日志,注意:log位置文件夹需先设置
- sqlldr userid=test/1234@127.0.0.1:3363/dbname control=D:\bats\tableName\tableNameCTLs\load_data_%CURRENT_DATE_STRING%.ctl log=log\tableName\load_csv_data_%CURRENT_DATE_STRING%.log
将该文件放在sqlldr.exe文件下,进行后续定时任务
4、 定时任务设置(win10系统)
此路径下找到
打开点击创建基本任务进行细节的定时任务设置操作
按需填写即可,注意两个地方
1) 操作步骤的起始于,需要填写路径为当前脚本存放路径,因为此路径默认为c盘的system路径
2)为防机器登录用户不同导致脚本执行中断,设置定时任务时,记得勾选最高权限执行。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。