在 Microsoft SQL Server 2017 上执行长 SQL 脚本
Executing a long SQL script on Microsoft SQL Server 2017
我需要通过 Java 应用程序在 Microsoft SQL Server 2017 的新实例上使用 DDL 和 DML 命令执行 SQL 脚本(~5000 行),已经部署和配置了连接池和数据源。
寻找解决方案我找到的唯一方法是将脚本加载到缓冲区,读取它,并将每一行分成一个语句,然后将这些语句中的每一个单独发送到数据库实例,如 this example。
有没有更优雅或更简单的方法来做到这一点?
在研究解决方案后,我得出结论,我的第一种方法最适合这种特定情况。基本上,我实现了一个工厂 class,它为正在使用的数据库实例化了一个解析器 class。
此解析器从 SQL 脚本中读取每一行并将其加载到缓冲区中,评估它是注释行还是正确行,将其添加到列表中,清除空行,然后最终构建每个命令在两个 GO
语句之间,通过附加行并将它们传递到将在最后返回的另一个列表。
package parsing;
import java.io.*
import java.util.*
public class ScriptParser implements Parser {
private static ArrayList<String> listOfQueries = null;
@Override
public ArrayList<String> createQueries(String path) {
String queryLine = new String();
StringBuilder sBuffer = new StringBuilder();
listOfQueries = new ArrayList<>();
List<String> dirtyQueries = new ArrayList<>();
try {
FileReader fr = new FileReader(new File(path));
BufferedReader br = new BufferedReader(fr);
while ((queryLine = br.readLine()) != null) {
if (queryLine.contains("--") || queryLine.contains("/*")) {
queryLine = "";
dirtyQueries.add(queryLine);
} else {
dirtyQueries.add(queryLine + " ");
}
}
br.close();
for (Iterator<String> iter = dirtyQueries.listIterator(); iter.hasNext();) {
//TODO
String str = iter.next();
if (str.isEmpty() || str.trim().isEmpty()) {
iter.remove();
} else {
//DO NOTHING
}
}
StringBuilder queryStatement = new StringBuilder();
for (int i = 0; i < dirtyQueries.size(); i++) {
//TODO
if (!dirtyQueries.get(i).contains("GO") || !dirtyQueries.get(i).contains("GO ")) {
queryStatement.append(dirtyQueries.get(i)).append(" ");
} else {
listOfQueries.add(queryStatement.toString());
queryStatement = new StringBuilder();
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println(sBuffer.toString());
}
return listOfQueries;
}
}
然后,循环列表中的每个条目并传递给 Statement
并单独执行。
我需要通过 Java 应用程序在 Microsoft SQL Server 2017 的新实例上使用 DDL 和 DML 命令执行 SQL 脚本(~5000 行),已经部署和配置了连接池和数据源。
寻找解决方案我找到的唯一方法是将脚本加载到缓冲区,读取它,并将每一行分成一个语句,然后将这些语句中的每一个单独发送到数据库实例,如 this example。
有没有更优雅或更简单的方法来做到这一点?
在研究解决方案后,我得出结论,我的第一种方法最适合这种特定情况。基本上,我实现了一个工厂 class,它为正在使用的数据库实例化了一个解析器 class。
此解析器从 SQL 脚本中读取每一行并将其加载到缓冲区中,评估它是注释行还是正确行,将其添加到列表中,清除空行,然后最终构建每个命令在两个 GO
语句之间,通过附加行并将它们传递到将在最后返回的另一个列表。
package parsing;
import java.io.*
import java.util.*
public class ScriptParser implements Parser {
private static ArrayList<String> listOfQueries = null;
@Override
public ArrayList<String> createQueries(String path) {
String queryLine = new String();
StringBuilder sBuffer = new StringBuilder();
listOfQueries = new ArrayList<>();
List<String> dirtyQueries = new ArrayList<>();
try {
FileReader fr = new FileReader(new File(path));
BufferedReader br = new BufferedReader(fr);
while ((queryLine = br.readLine()) != null) {
if (queryLine.contains("--") || queryLine.contains("/*")) {
queryLine = "";
dirtyQueries.add(queryLine);
} else {
dirtyQueries.add(queryLine + " ");
}
}
br.close();
for (Iterator<String> iter = dirtyQueries.listIterator(); iter.hasNext();) {
//TODO
String str = iter.next();
if (str.isEmpty() || str.trim().isEmpty()) {
iter.remove();
} else {
//DO NOTHING
}
}
StringBuilder queryStatement = new StringBuilder();
for (int i = 0; i < dirtyQueries.size(); i++) {
//TODO
if (!dirtyQueries.get(i).contains("GO") || !dirtyQueries.get(i).contains("GO ")) {
queryStatement.append(dirtyQueries.get(i)).append(" ");
} else {
listOfQueries.add(queryStatement.toString());
queryStatement = new StringBuilder();
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println(sBuffer.toString());
}
return listOfQueries;
}
}
然后,循环列表中的每个条目并传递给 Statement
并单独执行。