Board logo

标题: [其他] 批处理如何实现 oracle 数据批量入库? [打印本页]

作者: winbat    时间: 2014-12-28 18:56     标题: 批处理如何实现 oracle 数据批量入库?

1. 废话少说,先上代码
  1. @echo off
  2. @echo  菜鸟的菜
  3. :importdb
  4. imp user/passwd@orcl_192.168.0.1 file=E:\oracle数据入库\46v5e4.dmp fromuser=user touser=user buffer=4096000 recordlength=65535 commit=n ignore=y ignore=y feedback=100000
  5. imp user/passwd@orcl_192.168.0.1 file=E:\oracle数据入库\4545e4.dmp fromuser=user touser=user buffer=4096000 recordlength=65535 commit=n ignore=y ignore=y feedback=100000
  6. imp user/passwd@orcl_192.168.0.1 file=E:\oracle数据入库\478e4.dmp fromuser=user touser=user buffer=4096000 recordlength=65535 commit=n ignore=y ignore=y feedback=100000
  7. imp user/passwd@orcl_192.168.0.1 file=E:\oracle数据入库\467984.dmp fromuser=user touser=user buffer=4096000 recordlength=65535 commit=n ignore=y ignore=y feedback=100000
  8. ......
  9. @echo >>1.txt
  10. pause
  11. exit
复制代码
此种方法利是单线程数据包挨个读取上传减压负载,弊是每次上传数据包入库每次都要改写数据包文件名及路径麻烦且效率太慢
问:批处理能否自动读取某盘某路径文件夹下的所有dmp数据包[每个dmp名者不同]自动上传入库,然后读显记录输出 txt
也就是说 oracle 语句格式是固定的就是dmp数据包名不同(如上),就是把批处理放在某dmp数据文件夹内运行,批处理就自动读取dmp数据上传,或指定文件夹内读取数据自动上传。

2.
  1. @echo off
  2. @echo  菜鸟的菜
  3. :importdb
  4. start imp user/passwd@orcl_192.168.0.1 file=E:\oracle数据入库\46v545e4.dmp fromuser=user touser=user buffer=4096000 recordlength=65535 commit=n ignore=y ignore=y feedback=100000
  5. start imp user/passwd@orcl_192.168.0.1 file=E:\oracle数据入库\46454v5e4.dmp fromuser=user touser=user buffer=4096000 recordlength=65535 commit=n ignore=y ignore=y feedback=100000
  6. start imp user/passwd@orcl_192.168.0.1 file=E:\oracle数据入库\46v5454e4.dmp fromuser=user touser=user buffer=4096000 recordlength=65535 commit=n ignore=y ignore=y feedback=100000
  7. start imp user/passwd@orcl_192.168.0.1 file=E:\oracle数据入库\46v554e4.dmp fromuser=user touser=user buffer=4096000 recordlength=65535 commit=n ignore=y ignore=y feedback=100000
  8. ......
  9. @echo >>2.txt
  10. pause
  11. exit
复制代码
就加了个 start 挨个读取单个执行此种方法利是多个弹窗挨个读取数据包上传效率快,弊是每次上传数据包入库每次都要改写数据包文件名及路径麻烦且弹窗太多(如50个dmp数据包得弹50个cmd
问:批处理能否自动读取某盘某路径文件夹下的所有dmp数据包[每个dmp名者不同]  挨个读取单个执行数据包自动上传入库,然后读显记录输出 txt
也就是说 oracle 语句格式是固定的就是dmp数据包名不同(如上),就是把批处理放在某dmp数据文件夹内运行,或指定文件夹内读取数据自动上传,批处理就自动读取每一个dmp数据类start上传只显示在一个cmd中,入完后读显记录输出 txt 。

小小小菜鸟一个,望各位大神大侠指点个解决的 BAT ,小生不胜感激。
作者: Batcher    时间: 2014-12-28 19:30

1.bat
  1. @echo off
  2. >1.txt type nul
  3. for %%i in ("E:\oracle数据入库\*.dmp") do (
  4.     >>1.txt echo 正在处理文件 %%i
  5.     imp user/passwd@orcl_192.168.0.1 file=%%i fromuser=user touser=user buffer=4096000 recordlength=65535 commit=n ignore=y ignore=y feedback=100000
  6. )
复制代码

作者: winbat    时间: 2014-12-28 19:49

回复 2# Batcher


    单线程执行 ??谢谢, 明上班整整看,
作者: Batcher    时间: 2014-12-28 21:15

回复 3# winbat


    你不是已经知道在 imp 前面加 start 了吗
作者: winbat    时间: 2014-12-29 19:49

回复 4# Batcher

txt 输出是只显示:正在处理文件 E:\oracle数据入库\xxxx.dmp 没打印完整的输出结果。
如50个dmp ,start 得 50 个cmd 汗。包太多了,入的太慢还没入完,今天试了几个得以上结果。

可惜结果没整个输出,但还是要感谢 Batcher 大大
作者: Batcher    时间: 2014-12-30 10:46

回复 5# winbat


@echo off
>1.txt type nul
for %%i in ("E:\oracle数据入库\*.dmp") do (
    >>1.txt echo 正在处理文件 %%i
    >>1.txt imp user/passwd@orcl_192.168.0.1 file=%%i fromuser=user touser=user buffer=4096000 recordlength=65535 commit=n ignore=y ignore=y feedback=100000
)
你是想把imp的结果也输出?试试这样
作者: winbat    时间: 2015-1-1 20:16

回复 6# Batcher

>>1.txt imp user/passwd@orcl_192.168.0.1 file=%%i fromuser=user touser=user buffer=4096000 recordlength=65535 commit=n ignore=y ignore=y feedback=100000
还是不能保存记录屏幕内容

我只能添加 pause ,但数据多的话,屏幕缓冲区调大也总是不如保存txt记录屏幕内容,这样也方便于后期统计。
下面这张是数据导入成功回显图,能记录导出txt每个数据包导入成功回显数据就ok了,为了就是方便于后期导入数据统计。有大侠能指点个下么,感激不尽。
作者: Batcher    时间: 2015-1-2 09:13

回复 7# winbat


给你的 imp 命令加个参数试试
log=C:\imp.log
作者: winbat    时间: 2015-1-6 19:43

回复 8# Batcher
  1. @echo off
  2. for %%i in ("%cd%\*.dmp") do (
  3. echo 正在处理文件 %%i
  4. start imp user/pwd@orcl_192.168.0.1 file=%%i log=%%i.log fromuser=user touser=user buffer=40960 recordlength=65535 commit=n ignore=y ignore=y feedback=1000
  5. )
复制代码
start 执行解决了。把批处理放在想入库的 dmp 数据目录下运行,dmp数据导入完后会在目录下生成以dmp数据名命名的.log文件
  1. @echo off
  2. for %%i in ("%cd%\*.dmp") do (
  3. echo 正在处理文件 %%i
  4. imp user/pwd@orcl_192.168.0.1 file=%%i log=test.log fromuser=user touser=user buffer=40960 recordlength=65535 commit=n ignore=y ignore=y feedback=1000
  5. )
复制代码
多数据单线程不能同写在一个test.log文体里 ,唉!留给大牛解决吧。
再次感谢 @Batcher 牛的帮助,结帖吧 虽然不完美但也算完成了
作者: Batcher    时间: 2015-1-6 20:44

回复 9# winbat


    不能有多个进程同时写一个日志文件(类似数据库里面的写锁)。你可以每个进程写各自的日志,最后把多个日志合并成一个。
作者: winbat    时间: 2015-1-7 21:04

本帖最后由 winbat 于 2015-1-7 21:10 编辑

回复 10# Batcher

thank you, I think this is a good idea.
  1. @echo off
  2. for %%i in ("%cd%\*.dmp") do (
  3. echo 正在处理文件 %%i
  4. start imp user/pwd@orcl_192.168.0.1 file=%%i log=%%i.log fromuser=user touser=user buffer=40960 recordlength=65535 commit=n ignore=y ignore=y feedback=1000
  5. )
  6. for /r %%i in (*dmp.log) do copy "test.log"/a+"%%i"/a "test.log"
  7. del %cd%\*dmp.log
  8. echo 合并完成.
复制代码
菜鸟东拼西凑的代码,如能实现下面的效果该如何写呢:
  1. for /r %%i in (%leixing%) do copy /y %%i %goalfile% &&set num+=1
  2. set /a set /a str=!num!*2
  3. echo 共将!str!个文件,合并成!num!个文件
  4. echo 合并完成.
复制代码

作者: Batcher    时间: 2015-1-7 22:10

回复 11# winbat

在for循环内部加个计数:

@echo off
for %%i in ("%cd%\*.dmp") do (
echo 正在处理文件 %%i
start imp user/pwd@orcl_192.168.0.1 file=%%i log=%%i.log fromuser=user touser=user buffer=40960 recordlength=65535 commit=n ignore=y ignore=y feedback=1000
)
for /r %%i in (*dmp.log) do (
    copy "test.log"/a+"%%i"/a "test.log"
    set /a n+=1
)
echo 合并的文件个数:%n%
del %cd%\*dmp.log
echo 合并完成.
作者: winbat    时间: 2015-1-8 21:54

回复 12# Batcher

最后一组数据合并重复了:

消微改了一下,您看这样可以么
  1. @echo off
  2. for %%i in ("%cd%\*.dmp") do (
  3. echo 正在处理文件 %%i
  4. start imp user/pwd@orcl_192.168.0.1 file=%%i log=%%i.log fromuser=user touser=user buffer=40960 recordlength=65535 commit=n ignore=y ignore=y feedback=1000
  5. )
  6. for /r %%i in ("%cd%") do (
  7.     copy "*.dmp.log"/a+"%%i"/a "test.log"
  8.     set /a n+=1
  9. )
  10. echo 合并的文件个数:%n%
  11. del %cd%\*dmp.log
  12. pause
复制代码
sorry 但问题又来了,我们该如何在文件合并后自动统计入库数据数量呢?如上图入库数量 182340 行 + 237330 行,文件合并后自动统计为:419670 行 ; 当然我也知道打开手工计算,这样不是有驳批处理的理念么。
可以这样理解么:批处理,批量自动处理!
感谢 @Batcher 大大
作者: Batcher    时间: 2015-1-8 22:50

回复 13# winbat


    你把最后生成的test.log压缩一下,传上来,我告诉你如何计算。
作者: winbat    时间: 2015-1-9 19:14

回复 14# Batcher

今天试了下,改过后的代码,发现我们忽略了一个问题,那就是 start 执行完 oracle imp 入库命令 dmp 数据入库到完成是要一定时间的,而批处理命令执行完上一条命令会接着执行下一条所以 *dmp.log 生成时还没写入 oracle dmp 数据,文本是空的且被占用等待写入数据,而批处理命令接着执行空文本合并,会提示合并命令失败文件被占用。而之前测试的是早已生成后的文本所以未提示。
所以得加个判断条件等待 oracle dmp 数据入完库信息写入文本命令结束后才能接着执行文件合并命令。
作者: Batcher    时间: 2015-1-9 20:50

回复 15# winbat
  1. set TotalLine=0
  2. for /f "tokens=2" %%i in ('findstr "导入了" test.log') do (
  3.     set /a TotalLine+=%%i
  4. )
  5. echo 导入总行数:%TotalLine%
复制代码

作者: Batcher    时间: 2015-1-9 20:54

那就是 start 执行完 oracle imp 入库命令 dmp 数据入库到完成是要一定时间的

可以看看imp的时候是不是有对应的进程,根据进程判断imp是否执行完毕,类似于这个:
http://bbs.bathome.net/thread-33711-1-1.html
作者: winbat    时间: 2015-1-9 21:14

本帖最后由 winbat 于 2015-1-9 21:18 编辑

回复 16# Batcher

Batcher 您测试过了么,我怎么测试了没成功。能贴个完整的代码让我学习学习。我是菜鸟太菜了
作者: Batcher    时间: 2015-1-9 21:30

回复 18# winbat


    把你测试的代码和测试的结果发出来我看看
作者: winbat    时间: 2015-1-9 21:35

回复 19# Batcher
  1. @echo off
  2. for %%i in ("%cd%\*.dmp") do (
  3. echo 正在处理文件 %%i
  4. start imp user/pwd@orcl_192.168.0.1 file=%%i log=%%i.log fromuser=user touser=user buffer=40960 recordlength=6535 commit=n ignore=y feedback=1000
  5. )
  6. for /r %%i in ("%cd%") do (
  7.     copy "*.dmp.log"/a+"%%i"/a "test.log"
  8.     set /a n+=1
  9. echo 合并的文件个数:%n%
  10. pause
  11. )
  12. set TotalLine=0
  13. for /f "tokens=2" %%i in ('findstr "导入了" test.log') do (
  14.     set /a TotalLine+=%%i
  15. )
  16. exit
复制代码

作者: Batcher    时间: 2015-1-9 22:03

回复 20# winbat


第9行为什么使用中文括号?
第12行的括号是什么目的?
echo 导入总行数:%TotalLine% 为什么被你删掉了?

你直接把16楼的代码放到13楼代码的后面,不要乱改。
作者: winbat    时间: 2015-1-9 22:37

回复 21# Batcher
  1. @echo off
  2. for %%i in ("%cd%\*.dmp") do (
  3. echo 正在处理文件 %%i
  4. start imp user/pwd@orcl_192.168.0.1 file=%%i log=%%i.log fromuser=user touser=user buffer=40960 recordlength=65535 commit=n ignore=y ignore=y feedback=1000
  5. )
  6. for /r %%i in ("%cd%") do (
  7.     copy "*.dmp.log"/a+"%%i"/a "test.log"
  8.     set /a n+=1
  9. )
  10. echo 合并的文件个数:%n%
  11. del %cd%\*dmp.log
  12. pause
  13. set TotalLine=0
  14. for /f "tokens=2" %%i in ('findstr "导入了" test.log') do (
  15.     set /a TotalLine+=%%i
  16. )
  17. echo 导入总行数:%TotalLine%
  18. pause
复制代码
第9行为什么使用中文括号? 确实是中文输入,好意思打的太快输入法没切换。
第12行的括号是什么目的? 编辑器自动添加了 T T
echo 导入总行数:%TotalLine% 为什么被你删掉了?
sorry ,我粗心大意了。测试时一直没成功修改时不小心给删到了,当也没加 pause 也没想到结果回显在屏幕,还以为结果会写到 test.log 里所以一直改不成功,抱歉 @Batcher 是我疏忽了,现在 ok 了

下星期上班在看下能否解决,延迟执行命令问题!非常感谢 @Batcher 周末愉快!
作者: Batcher    时间: 2015-1-10 09:01

回复 22# winbat


    我不是已经告诉你了吗,看看进程。17楼你再看看
作者: winbat    时间: 2015-1-13 22:27

回复 23# Batcher

意思是明白了,添加了个 oracle imp.exe 命令进程判断 tasklist|find /i "imp.exe" 还是没效果,不知道这样是写对么?
  1. @echo off
  2. for %%i in ("%cd%\*.dmp") do (
  3. echo 正在处理文件 %%i
  4. start imp user/pwd@orcl_192.168.0.1 file=%%i log=%%i.log fromuser=user touser=user buffer=40960 recordlength=65535 commit=n ignore=y ignore=y feedback=1000
  5. )
  6. tasklist|find /i "imp.exe"
  7. for /r %%i in ("%cd%") do (
  8.     copy "*.dmp.log"/a+"%%i"/a "test.log"
  9.     set /a n+=1
  10. )
  11. echo 合并的文件个数:%n%
  12. del %cd%\*dmp.log
  13. pause
  14. set TotalLine=0
  15. for /f "tokens=2" %%i in ('findstr "导入了" test.log') do (
  16.     set /a TotalLine+=%%i
  17. )
  18. echo 导入总行数:%TotalLine%>>test.log
  19. pause
复制代码
还是要加个 for 判断呢,搞不定只能指望老大你了。
  1. for /f "skip=1"%%i in ("imp.exe") do if not exist %%i start
复制代码

作者: Batcher    时间: 2015-1-14 09:08

@echo off
for %%i in ("%cd%\*.dmp") do (
echo 正在处理文件 %%i
start imp user/pwd@orcl_192.168.0.1 file=%%i log=%%i.log fromuser=user touser=user buffer=40960 recordlength=65535 commit=n ignore=y ignore=y feedback=1000
)
:loop
ping -n 5 127.1 >nul
echo 正在判断 imp.exe 进程
tasklist | findstr /i "imp.exe" > nul && goto :loop
echo 正在合并日志文件

for /r %%i in ("%cd%") do (
    copy "*.dmp.log"/a+"%%i"/a "test.log"
    set /a n+=1
)
echo 合并的文件个数:%n%
del %cd%\*dmp.log
pause
set TotalLine=0
for /f "tokens=2" %%i in ('findstr "导入了" test.log') do (
    set /a TotalLine+=%%i
)
echo 导入总行数:%TotalLine%>>test.log
pause
作者: winbat    时间: 2015-1-15 20:43

回复 25# Batcher
  1. @echo off
  2. color 0A
  3. echo            \\\ATA///     %date%
  4. echo           \\ - - //        %time:~0,8%
  5. echo            ( @ @ )
  6. echo     ┏━━━oOOo━━(_)━━oOOo━━━━┓
  7. echo     ╀                                 ╀
  8. echo    A◎      ID: @Batcher ; @winbat     ◎A
  9. echo    A◎      Forum: www.bathome.net     ◎A
  10. echo    A◎     非常感觉 @Batcher 的帮助    ◎A
  11. echo    A◎                                 ◎A
  12. echo     ╁                         Oooo    ╁
  13. echo     ┗━━━━━━━━oooO━━(   )━━┛
  14. echo                       (   )    ) /
  15. echo                        \ (    (_/
  16. echo                         \_)
  17. echo  
  18. echo  
  19. for %%i in ("%cd%\*.dmp") do (
  20. echo 正在处理文件 %%i
  21. start imp user/pwd@orcl_192.168.0.1 file=%%i log=%%i.log fromuser=user touser=user buffer=xxxxx recordlength=xxxxx commit=n ignore=y ignore=y feedback=xxx
  22. )
  23. :loop
  24. ping -n 5 127.1 >nul
  25. echo 正在判断 imp.exe 进程
  26. tasklist | findstr /i "imp.exe" > nul && goto :loop
  27. echo 正在合并日志文件
  28. for /r %%i in ("%cd%") do (
  29.     copy "*.dmp.log"/a+"%%i"/a "数据入库统计.log"
  30.     set /a n+=1
  31. )
  32. echo 合并的文件个数:%n%
  33. del %cd%\*.dmp.log
  34. set TotalLine=0
  35. for /f "tokens=2" %%i in ('findstr "导入了" 数据入库统计.log') do (
  36.     set /a TotalLine+=%%i
  37. )
  38. echo                 %date:~0,4%年%date:~5,2%月%date:~8,2%日%time:~0,8%    数据入库统计:%TotalLine% 枚>>数据入库统计.log
  39. exit
复制代码
sorry , 这两天一直在忙,问题解决了 perfect 。可以结帖了,非常感谢 @Batcher 的热心忙助让我少走了很多弯路也学到了很多,这里是个能学到东西的地方。
放上整理过的完整代码,分享给有用的人!
感谢 @Batcher www.bathome.net




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2