作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个备份文件,其结构为 INSERT 语句。我的方法是编写一个方法来从文件中加载这些语句并使用 JDBC 模板来执行它们。
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 个字符)。
当我运行更新功能时,多个文件出现以下错误:
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: ORA-01704: string literal too long
另一方面,如果我在 SQL Developer 中运行相同的脚本,则不会发生此错误。
我知道我应该使用带有绑定(bind)变量的准备好的语句,但由于需求是将文件存储为插入,所以我宁愿不必解析整个文件。我想简单地按原样执行每一行。
有解决办法吗?
编辑:另外,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.get(i));
}
return statement;
}
};
getJdbcTemplate().update(statement);
}
如您所见:它尝试通过提取字符串文字来缩小较大的 SQL。
关于java - 通过 JDBC 执行长插入语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49458197/
我是一名优秀的程序员,十分优秀!