问题:运用bat 导数据库数据?
步骤(1)
连接数据库,导出表,运行java程序,分隔文件,运行bat文件多线程导入数据。
1、java程序
package splitsql;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class SplitFiles {
private final static String str1 = "sc_xxx";
private final static String str2 = "SC_XXX";
private final static int num = 10000;
public static void main(String[] args) {
SplitFiles s = new SplitFiles();
File file = new File("D:\\zhuanyi\\sqlfile");
File[] files;
if(file.exists()) {
files = file.listFiles();
for (File file1:files) {
if(file1.getAbsolutePath().contains(".sql")) {
System.out.println(file1.getAbsolutePath());
s.splitDataToSaveFile(num, file1.getAbsolutePath(), "D:\\zhuanyi\\split");
}
}
}
// s.splitDataToSaveFile(10000, "D:\\zhuanyi\\sc_verify_049_3y.sql", "D:\\zhuanyi\\split");
}
/**
* 按行分割文件
* @param rows 为多少行一个文件
* @param sourceFilePath 为源文件路径
* @param targetDirectoryPath 文件分割后存放的目标目录
*/
public void splitDataToSaveFile(int rows, String sourceFilePath,
String targetDirectoryPath) {
long start1 = System.currentTimeMillis();
File sourceFile = new File(sourceFilePath);
File targetFile = new File(targetDirectoryPath);
if (!sourceFile.exists() || rows <= 0 || sourceFile.isDirectory()) {
return;
}
if (targetFile.exists()) {
if (!targetFile.isDirectory()) {
return;
}
} else {
targetFile.mkdirs();
}
try {
InputStreamReader in = new InputStreamReader(new FileInputStream(sourceFilePath),"GBK");
BufferedReader br=new BufferedReader(in);
BufferedWriter bw = null;
StringBuilder str = new StringBuilder("");
String tempData = br.readLine();
int i = 1, s = 0;
long start2 = System.currentTimeMillis();
//str.append("DECLARE").append("\r\n").append("begin").append("\r\n");
while (tempData != null) {
str.append(tempData).append("\r\n");
if (i % rows == 0) {
Thread.sleep(1);
/*bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(
targetFile.getAbsolutePath() + "/" + sourceFile.getName() +"_" + (s+1) +".sql"), "GBK"),1024);*/
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(
targetFile.getAbsolutePath() + "/" + System.currentTimeMillis() +".sql"), "GBK"),1024);
//str += "commit;" + "\r\n" + "end;";
//str.append("commit;").append("\r\n").append("end;");
str.append("commit;");
String string = str.toString().replaceAll(str1, str2);
bw.write(string);
bw.close();
str = new StringBuilder("");
//str.append("DECLARE").append("\r\n").append("begin").append("\r\n");
start2 = System.currentTimeMillis();
s += 1;
}
i++;
tempData = br.readLine();
}
if ((i - 1) % rows != 0) {
/* bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(
targetFile.getAbsolutePath() + "/" + sourceFile.getName() +"_" + (s+1) +".sql"), "GBK"),1024);*/
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(
targetFile.getAbsolutePath() + "/" + System.currentTimeMillis() +".sql"), "GBK"),1024);
str.append("commit;");
String string = str.toString().replaceAll(str1, str2);
bw.write(string);
bw.close();
br.close();
s += 1;
}
in.close();
} catch (Exception e) {
}
}
}
·
2. testParent.bat文件
@echo off
setlocal enabledelayedexpansion
for /r "D:\zhuanyi\split" %%i in (*) do (
::echo "%%~nxi"
set v=%%~nxi
start /min testsub.bat !v!
echo 正在执行!v!...
)
pause
·
3. testsub.bat 文件
@echo off
echo "i am testsub.bat" %1
sqlplus 用户名/密码@IP:端口号/服务名称(或数据库名称) @D:\zhuanyi\split\%1
exit
·
4.说明
example:
@echo off
set a=4
set a=5&echo %a%
pause
结果:4
解说:为什么是4而不是5呢?在echo之前明明已经把变量a的值改成5了?先了解一下批处理运行命令的机制:批处理读取命令时是按行读取的(另外例如for命令等,其后用一对圆括号闭合的所有语句也当作一行),在处理之前要完成必要的预处理工作,这其中就包括对该行命令中的变量赋值。我们现在分析一下例1,批处理在运行到这句“set a=5&echo %a%”之前,先把这一句整句读取并做了预处理——对变量a赋了值,那么%a%当然就是4了!而为了能够感知环境变量的动态变化,批处理设计了变量延迟。简单来说,在读取了一条完整的语句之后,不立即对该行的变量赋值,而会在某个单条语句执行之前再进行赋值,也就是说“延迟”了对变量的赋值
例2:
@echo off
setlocal enabledelayedexpansion
for /l %%i in (1,1,5) do ( set a=%%i echo !a! )
pause
结果:12345
解说:本例开启了变量延迟并用“!!”将变量扩起来,因此得到我们预期的结果。如果不用变量延迟会出现什么结果呢?结果是这样的:ECHO 处于关闭状态。ECHO 处于关闭状态。ECHO 处于关闭状态。ECHO 处于关闭状态。ECHO 处于关闭状态。即没有感知到for语句中的动态变化。
setlocal enabledelayedexpansion就是扩展本地环境变量延迟
1.%~nxI - 仅将 %I 扩充到一个文件名和扩展名
2.start 命令
调用外部程序,所有的 DOS命令 和 命令行程序 都可以由 start命令 来调用。
入侵常用参数:
MIN 开始时窗口最小化
SEPARATE 在分开的空间内开始 16 位 Windows 程序
HIGH 在 HIGH 优先级类别开始应用程序
REALTIME 在 REALTIME 优先级类别开始应用程序
WAIT 启动应用程序并等候它结束
parameters 这些为传送到命令/程序的参数
0.for 命令
for 命令是一个比较复杂的命令,主要用于参数在指定的范围内循环执行命令。
1) for {%variable | %%variable} in (set) do command [command-parameters]
%variable 指定一个单一字母可替换的参数。变量名称是区分大小写的,所以 %i 不同于 %I
在批处理文件中使用 FOR 命令时,指定变量建议用 %%variable而不要用 %variable。
(set) 指定一个或一组文件。可以使用通配符。
command 指定对每个文件执行的命令。
command-parameters 为特定命令指定参数或命令行开关。
2) 如果命令扩展名被启用,下列额外的 FOR 命令格式会受到支持:
a.FOR /D %variable IN (set) DO command [command-parameters]
如果集里面包含通配符,则指定与目录名匹配,而不与文件名匹配。
b.FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]
检查以 [drive:]path 为根的目录树,指向每个目录中的FOR 语句。
如果在 /R 后没有指定目录,则使用当前目录。如果集仅为一个单点(.)字符,则枚举该目录树。
c.FOR /L %variable IN (start,step,end) DO command [command-parameters]
该集表示以增量形式从开始到结束的一个数字序列。
如:(1,1,5) 将产生序列 1 2 3 4 5; 而(5,-1,1) 将产生序列 (5 4 3 2 1)。
d.有或者没有 usebackq 选项:
FOR /F [“options”] %variable IN (file-set) DO command
FOR /F [“options”] %variable IN (“string”) DO command
FOR /F [“options”] %variable IN (command) DO command
参数”options”为:
eol=c - 指一个行注释字符的结尾(就一个,如“;”)
skip=n - 指在文件开始时忽略的行数。
delims=xxx - 指分隔符集。这个替换了空格和跳格键的默认分隔符集。
tokens=x,y,m-n - 指每行的哪一个符号被传递到每个迭代的 for 本身。这会导致额外变量名称的分配。
m-n格式为一个范围。通过 nth 符号指定 mth。
如果符号字符串中的最后一个字符星号,那么额外的变量将在最后一个符号解析之后分配并接受行的保留文本。
usebackq - 指定新语法已在下类情况中使用:
在作为命令执行一个后引号的字符串并且一个单引号字符为文字字符串命令并允许在 filenameset中使用双引号扩起文件名称。
3) Sample:
1. 如下命令行会显示当前目录下所有以bat或者txt为扩展名的文件名。
for %%c in (.bat .txt) do (echo %%c)
a. 如下命令行会显示当前目录下所有包含有 e 或者 i 的目录名。
for /D %%a in (e i) do echo %%a
b. 如下命令行会显示 E盘test目录 下所有以bat或者txt为扩展名的文件名。
for /R E:\test %%b in (.txt .bat) do echo %%b
for /r %%c in (*) do (echo %%c) :: 遍历当前目录下所有文件
c. 如下命令行将产生序列 1 2 3 4 5
for /L %%c in (1,1,5) do echo %%c
d. 以下两句,显示当前的年月日和时间
For /f “tokens=1-3 delims=-/. ” %%j In (‘Date /T’) do echo %%j年%%k月%%l日
For /f “tokens=1,2 delims=: ” %%j In (‘TIME /T’) do echo %%j时%%k分
e. 把记事本中的内容每一行前面去掉8个字符
setlocal enabledelayedexpansion
for /f %%i in (zhidian.txt) do (
set atmp=%%i
set atmp=!atmp:~8!
if {!atmp!}=={} ( echo.) else echo !atmp!
)
:: 读取记事本里的内容(使用 delims 是为了把一行显示全,否则会以空格为分隔符)
for /f “delims=” %%a in (zhidian.txt) do echo.%%a
4) continue 和 break
利用 goto 实现程序中常用的 continue 和 break 命令, 其实非常简单
continue: 在 for 循环的最后一行写上一个标签,跳转到这位置即可
break: 在 for 循环的外面的下一句写上一个标签,跳转到这位置即可
Sample: (伪代码)
for /F [“options”] %variable IN (command) DO (
… do command …
if … goto continue
if … goto break
… do command …
:continue
)
:break
. exit 命令
结束程序。即时是被调用的程序,结束后也不会返回原程序