[英]How to split sql queries using Java
我播下了這些查詢:查詢在同一行。
INSERT INTO data_location ( `latitude`, `updated`, `id`, `longitude`, `created`)
VALUES( '213.2000000', '2014-08-25 11:07:42+00:00', '1', '321.0000000',
'2014-08-25 11:07:42+00:00');
INSERT INTO data_location ( `latitude`, `updated`, `id`, `longitude`, `created`)
VALUES( '42.7191000', '2014-09-17 12:53:49+00:00', '2', '23.0834000',
'2014-09-17 12:53:49+00:00');
INSERT INTO data_news (`id`, `title`, `date`, `short_content`, `content`,
`created`, `updated`)
VALUES(10, 'fdsafsda.', 'fdsafafa>', '2014-09-26 08:10:55', '2014-09-26 08:10:55');
INSERT INTO data_news (`id`, `title`, `date`, `short_content`, `content`,
`created`, `updated`)
VALUES(11, 'fdsafdsafd „THE THROWAWAYS”', '2014-09-26 11:22:00',
'fdsafdsafdsafda(dsa);', '2014-09-26 09:05:09', '2014-09-26 09:05:09');
我想將它們分開。 在此階段,使用以下方法對其進行划分:
String[] parts = sql.split("(?<=\\);)");
db.beginTransaction();
for (String entry : parts) {
SQLiteStatement stmt = db.compileStatement(entry);
stmt.execute();
stmt.clearBindings();
}
db.setTransactionSuccessful();
db.endTransaction();
問題在於,在最后一個查詢中,數據具有以下...safda(dsa);...
它被接受並變為無效查詢。 有沒有辦法拆分聰明不接受這樣的問題?
如果所有查詢在您的示例中看起來都像這些查詢,那么您也可以將結尾與右括號匹配: ');
因此,拆分變為: sql.split("(?<='\\\\);)");
您按照以下方式創建SqlRunner
類並使用它; 有關詳細信息,請訪問http://allstarnix.blogspot.com.tr/2013/03/how-to-execute-sql-script-file-using.html ;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
public class SqlRunner {
public static final String DELIMITER_LINE_REGEX = "(?i)DELIMITER.+", DELIMITER_LINE_SPLIT_REGEX = "(?i)DELIMITER", DEFAULT_DELIMITER = ";";
private final boolean autoCommit, stopOnError;
private final Connection connection;
private String delimiter = SqlRunner.DEFAULT_DELIMITER;
private final PrintWriter out, err;
public SqlRunner(final Connection connection, final PrintWriter out, final PrintWriter err, final boolean autoCommit, final boolean stopOnError) {
if (connection == null) {
throw new RuntimeException("SqlRunner requires an SQL Connection");
}
if (err == null || out == null) {
throw new RuntimeException("SqlRunner requires both out and err PrintWriters");
}
this.connection = connection;
this.autoCommit = autoCommit;
this.stopOnError = stopOnError;
this.out = out;
this.err = err;
}
public void runScript(final Reader reader) throws SQLException {
final boolean originalAutoCommit = this.connection.getAutoCommit();
try {
if (originalAutoCommit != this.autoCommit) {
this.connection.setAutoCommit(this.autoCommit);
}
this.runScript(this.connection, reader);
} finally {
this.connection.setAutoCommit(originalAutoCommit);
}
}
private void runScript(final Connection conn, final Reader reader) {
StringBuffer command = null;
try {
final LineNumberReader lineReader = new LineNumberReader(reader);
String line = null;
while ((line = lineReader.readLine()) != null) {
if (command == null) {
command = new StringBuffer();
}
String trimmedLine = line.trim();
if (trimmedLine.startsWith("--") || trimmedLine.startsWith("//") || trimmedLine.startsWith("#")) {
// Line is a comment
out.println(trimmedLine);
out.flush();
} else if (trimmedLine.endsWith(this.delimiter)) {
// Line is end of statement
// Support new delimiter
final Pattern pattern = Pattern.compile(SqlRunner.DELIMITER_LINE_REGEX);
final Matcher matcher = pattern.matcher(trimmedLine);
if (matcher.matches()) {
delimiter = trimmedLine.split(SqlRunner.DELIMITER_LINE_SPLIT_REGEX)[1].trim();
// New delimiter is processed, continue on next
// statement
line = lineReader.readLine();
if (line == null) {
break;
}
trimmedLine = line.trim();
}
// Append
command.append(line.substring(0, line.lastIndexOf(this.delimiter)));
command.append(" ");
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conn.createStatement();
out.println();
out.println(command);
out.flush();
boolean hasResults = false;
if (this.stopOnError) {
hasResults = stmt.execute(command.toString());
} else {
try {
stmt.execute(command.toString());
} catch (final SQLException e) {
e.fillInStackTrace();
err.println("Error on command: " + command);
err.println(e);
err.flush();
}
}
if (this.autoCommit && !conn.getAutoCommit()) {
conn.commit();
}
rs = stmt.getResultSet();
if (hasResults && rs != null) {
// Print result column names
final ResultSetMetaData md = rs.getMetaData();
final int cols = md.getColumnCount();
for (int i = 0; i < cols; i++) {
final String name = md.getColumnLabel(i + 1);
out.print(name + "\t");
}
out.println("");
out.println(StringUtils.repeat("---------", md.getColumnCount()));
out.flush();
// Print result rows
while (rs.next()) {
for (int i = 1; i <= cols; i++) {
final String value = rs.getString(i);
out.print(value + "\t");
}
out.println("");
}
out.flush();
} else {
out.println("Updated: " + stmt.getUpdateCount());
out.flush();
}
command = null;
} finally {
if (rs != null)
try {
rs.close();
} catch (final Exception e) {
err.println("Failed to close result: " + e.getMessage());
err.flush();
}
if (stmt != null)
try {
stmt.close();
} catch (final Exception e) {
err.println("Failed to close statement: " + e.getMessage());
err.flush();
}
}
} else {
// Line is middle of a statement
// Support new delimiter
final Pattern pattern = Pattern.compile(SqlRunner.DELIMITER_LINE_REGEX);
final Matcher matcher = pattern.matcher(trimmedLine);
if (matcher.matches()) {
delimiter = trimmedLine.split(SqlRunner.DELIMITER_LINE_SPLIT_REGEX)[1].trim();
line = lineReader.readLine();
if (line == null) {
break;
}
trimmedLine = line.trim();
}
command.append(line);
command.append(" ");
}
}
if (!this.autoCommit) {
conn.commit();
}
} catch (final SQLException e) {
e.fillInStackTrace();
err.println("Error on command: " + command);
err.println(e);
err.flush();
} catch (final IOException e) {
e.fillInStackTrace();
err.println("Error on command: " + command);
err.println(e);
err.flush();
}
}
}
您可以使用“換行”符號將它們分開。
String[] parts = sql.split(System.lineSeparator());
如果樣本數據顯示了所有極端情況,那么您需要查找的全部是;
后面沒有'
。 這將與正則表達式;[^']
。 因此,split命令將是: String[] parts = sql.split(";[^']");
在我的測試中,這每行給出一個sql查詢。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.