Java 通过JDBC执行长insert语句
我有一个结构为INSERT语句的备份文件。我的方法是编写一个方法,从文件中加载这些语句,并使用JDBC模板执行它们Java 通过JDBC执行长insert语句,java,sql,oracle,jdbc,Java,Sql,Oracle,Jdbc,我有一个结构为INSERT语句的备份文件。我的方法是编写一个方法,从文件中加载这些语句,并使用JDBC模板执行它们 public void restoreFile(File f) throws Exception { LineIterator it = FileUtils.lineIterator(f, "UTF-8"); try { while (it.hasNext()) { String insertStatement = it.ne
public void restoreFile(File f) throws Exception {
LineIterator it = FileUtils.lineIterator(f, "UTF-8");
try {
while (it.hasNext()) {
String insertStatement = it.nextLine();
if (!insertStatement.startsWith("--") && !insertStatement.isEmpty()) {
insertStatement = insertStatement.replace(";", "");
executeSqlStatement(insertStatement);
}
}
} finally {
it.close();
}
}
public void executeSqlStatement(String sqlStatement) throws Exception {
PreparedStatementCreator statement = new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement statement = connection.prepareStatement(sqlStatement);
return statement;
}
};
getJdbcTemplate().update(statement);
}
在少数情况下,这似乎效果不错。然而,我插入的一些值是巨大的XML字符串(一些XML超过10K个字符)
运行update函数时,我在几个文件中遇到以下错误:
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: ORA-01704: string literal too long
另一方面,如果在SQLDeveloper中运行相同的脚本,则不会发生此错误
我知道我应该在bind vars中使用prepared语句,但是由于需求将文件存储为insert,所以我宁愿不解析整个文件。我只想按原样执行每一行
有解决办法吗
编辑:另外,SQL Developer如何处理这些长字符串文字?下面是hackatron:
public void executeSqlStatement(String sqlStatement) throws Exception {
PreparedStatementCreator statement = new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection connection)
throws SQLException {
List<String> params = new ArrayList<>();
if (sqlStatement.length() >= 4000) {
Pattern pattern = Pattern.compile("'(([^'\n]|'')+)'");
Matcher m = pattern.matcher(sqlStatement);
StringBuffer sb = new StringBuffer();
while (m.find()) {
params.add(m.group(1).replace("''", "'"));
m.appendReplacement(sb, "?");
}
m.appendTail(sb);
sqlStatement = sb.toString();
}
PreparedStatement statement = connection.prepareStatement(sqlStatement);
for (int i = 0; i < params.size(); ++i) {
statement.setString(1 + i, params[i]);
}
return statement;
}
};
getJdbcTemplate().update(statement);
}
public void executeSqlStatement(字符串sqlStatement)引发异常{
PreparedStatementCreator语句=新的PreparedStatementCreator(){
@凌驾
公共PreparedStatement createPreparedStatement(连接)
抛出SQLException{
List params=new ArrayList();
if(sqlStatement.length()>=4000){
Pattern=Pattern.compile(“([^'\n]|”“)+)”;
Matcher m=pattern.Matcher(sqlStatement);
StringBuffer sb=新的StringBuffer();
while(m.find()){
参数添加(m.group(1).替换(“,”);
m、 (sb,“?”);
}
m、 (某人);
sqlStatement=sb.toString();
}
PreparedStatement=connection.prepareStatement(sqlStatement);
对于(int i=0;i
如您所见:它试图通过提取字符串文本来收缩较大的SQL。下面是hackatron:
public void executeSqlStatement(String sqlStatement) throws Exception {
PreparedStatementCreator statement = new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection connection)
throws SQLException {
List<String> params = new ArrayList<>();
if (sqlStatement.length() >= 4000) {
Pattern pattern = Pattern.compile("'(([^'\n]|'')+)'");
Matcher m = pattern.matcher(sqlStatement);
StringBuffer sb = new StringBuffer();
while (m.find()) {
params.add(m.group(1).replace("''", "'"));
m.appendReplacement(sb, "?");
}
m.appendTail(sb);
sqlStatement = sb.toString();
}
PreparedStatement statement = connection.prepareStatement(sqlStatement);
for (int i = 0; i < params.size(); ++i) {
statement.setString(1 + i, params[i]);
}
return statement;
}
};
getJdbcTemplate().update(statement);
}
public void executeSqlStatement(字符串sqlStatement)引发异常{
PreparedStatementCreator语句=新的PreparedStatementCreator(){
@凌驾
公共PreparedStatement createPreparedStatement(连接)
抛出SQLException{
List params=new ArrayList();
if(sqlStatement.length()>=4000){
Pattern=Pattern.compile(“([^'\n]|”“)+)”;
Matcher m=pattern.Matcher(sqlStatement);
StringBuffer sb=新的StringBuffer();
while(m.find()){
参数添加(m.group(1).替换(“,”);
m、 (sb,“?”);
}
m、 (某人);
sqlStatement=sb.toString();
}
PreparedStatement=connection.prepareStatement(sqlStatement);
对于(int i=0;i
如您所见:它试图通过提取字符串文本来收缩较大的SQL。您使用什么库来执行SQL?看到PreparedStatementCreator这样的东西很奇怪。我怀疑你可能没有你认为你有的问题。错误消息特别指字符串文字太长。我认为您应该打印您试图执行的sql并手动运行它。需要记住的是,批量更新可以大大加快插入时间。无论您是使用jdbc批处理还是仅仅连接插入字符串。如果是数据加载,这不是一个糟糕的计划,“长”是多长?您需要精确。您不能使用超过4000个字符的字符串,否则您必须在准备好的语句中绑定变量。@Deadron我使用的是org.springframework.jdbc.core,但我不明白它为什么奇怪(您可能会发现它不寻常,但这绝对不是问题所在)。打印SQL并手动运行它是什么意思?如前所述,我确实尝试使用SQLDeveloper执行该脚本,它运行良好,这给我的印象是JDBC可能有Oracle的SQLIDE中不存在的限制。我不认为这是个问题,因为Oracle是这里提到的所有东西的开发者,人们可能期望这些系统之间有一个良好的集成。@Lucas,至少看起来是这样。自由派可能会在幕后使用预先准备好的语句。您使用什么库来执行SQL?看到PreparedStatementCreator这样的东西很奇怪。我怀疑你可能没有你认为你有的问题。错误消息特别指字符串文字太长。我认为您应该打印您试图执行的sql并手动运行它。需要记住的是,批量更新可以大大加快插入时间。无论您是使用jdbc批处理还是仅仅连接插入字符串。如果是数据加载,这不是一个糟糕的计划,“长”是多长?您需要精确。您不能使用超过4000个字符的字符串,否则您必须在准备好的语句中绑定变量。@Deadron我使用的是org.springframework.jdbc.core,但我不明白它为什么奇怪(您可能会发现它不寻常,但这绝对不是问题所在)。打印SQL并手动运行它是什么意思?如前所述,我确实尝试使用SQLDeveloper执行该脚本,它运行良好,这给我的印象是JDBC可能有Oracle的SQLIDE中不存在的限制。我不认为这会是个问题,因为Oracle是这里提到的所有东西的开发者,所以人们可能会期待一个像样的amon集成