我正在使用ibatis SCRIPRunner,它支持在oracle db上运行我的sql脚本的触发器和程序,但是有些创建语句失败,因为ivalid charcter可以帮助我将哪个字符作为无效字符
执行:
ALTER TABLE BFTB_BUSINESSDATELOG ADD CONSTRAINT PK_BUSINESSDTLOG PRIMARY KEY (BFBUSINESSDATEIDPK);
CREATE TABLE BFTB_CATEGORY
(
BFCATEGORYIDPK VARCHAR(30) NOT NULL,
BFCATEGORYTYPE VARCHAR(10),
BFDESCRIPTION VARCHAR(40),
VERSIONNUM INTEGER,
BFAPPLICATIONID VARCHAR(100)
)
错误:ORA-00911: invalid character
执行:
ALTER TABLE BFTB_CATEGORY ADD CONSTRAINT PK_CATEGORY PRIMARY KEY (BFCATEGORYIDPK);
CREATE TABLE BFTB_CTGARTEFACTLINK
(
BFLINKIDPK VARCHAR(20) NOT NULL,
BFARTEFACTNAME VARCHAR(256),
BFCATEGORYID VARCHAR(30),
VERSIONNUM INTEGER,
BFARTEFACTID VARCHAR(256),
BFAPPLICATIONID VARCHAR(100)
)
错误:ORA-00911: invalid character
package com.rj.installer.action;
public class ScriptRunner {
private static final String LINE_SEPARATOR = System.getProperty("line.separator","\n");
private static final String DEFAULT_DELIMITER = ";";
private FileOutputStream logFile ;
private BufferedWriter writer ;
private MyLogger logs ;
private static final String S_N = "(\\s|\\n)+";
private static final String IDENTIFIER = "(\\S+|\"[^\"]+\")";
private static final String BLOCK_START = "(^|" + S_N + ")" +
"create" + S_N +
"(or" + S_N + "replace" + S_N + ")?" +
"(function|library|package(" + S_N + "body)?|procedure|trigger|type)" + S_N +
IDENTIFIER + S_N +
".*";
private final Pattern blockStart = Pattern.compile(BLOCK_START, Pattern.CASE_INSENSITIVE);
private Connection connection;
private boolean stopOnError;
private boolean autoCommit;
private boolean sendFullScript;
private PrintWriter logWriter = new PrintWriter(System.out);
private PrintWriter errorLogWriter = new PrintWriter(System.err);
private String DatabaseProductName;
private String delimiter = DEFAULT_DELIMITER;
private boolean fullLineDelimiter = false;
public ScriptRunner(Connection connection) {
this.connection = connection;
logs = new MyLogger("logs/sql.log");
}
public void setStopOnError(boolean stopOnError) {
this.stopOnError = stopOnError;
}
public void setAutoCommit(boolean autoCommit) {
this.autoCommit = autoCommit;
}
public void setSendFullScript(boolean sendFullScript) {
this.sendFullScript = sendFullScript;
}
public void setLogWriter(PrintWriter logWriter) {
this.logWriter = logWriter;
}
public void setErrorLogWriter(PrintWriter errorLogWriter) {
this.errorLogWriter = errorLogWriter;
}
public void setDelimiter(String delimiter) {
this.delimiter = delimiter;
}
public void setFullLineDelimiter(boolean fullLineDelimiter) {
this.fullLineDelimiter = fullLineDelimiter;
}
public void runScript(Reader reader) {
try {
setAutoCommit();
DatabaseMetaData md = connection.getMetaData();
DatabaseProductName = md.getDatabaseProductName().toUpperCase().trim();
try {
if ("ORACLE".equals(DatabaseProductName)) {
executeOracleScript(reader);
} else {
if (sendFullScript) {
executeFullScript(reader);
} else {
executeLineByLine(reader);
}
}
} finally {
rollbackConnection();
}
} catch (SQLException e) {
String message = "\nError retrieving database metadata\nCause: " + e;
logs.writeFile(message);
throw new RuntimeException(message, e);
}
logs.closeFile();
}
private void executeFullScript(Reader reader) {
StringBuffer script = new StringBuffer();
try {
BufferedReader lineReader = new BufferedReader(reader);
String line;
while ((line = lineReader.readLine()) != null) {
script.append(line);
script.append(LINE_SEPARATOR);
}
executeStatement(script.toString());
commitConnection();
} catch (Exception e) {
String message = "\nError executing: \n" + script + "Cause: " + e;
logs.writeFile(message);
throw new RuntimeException(message, e);
}
}
private void executeLineByLine(Reader reader) {
StringBuffer command = new StringBuffer();
try {
BufferedReader lineReader = new BufferedReader(reader);
String line;
while ((line = lineReader.readLine()) != null) {
command = handleLine(command, line);
}
commitConnection();
checkForMissingLineTerminator(command);
} catch (Exception e) {
String message = "\nError executing: \n" + command + "Cause: " + e;
logs.writeFile(message);
throw new RuntimeException(message, e);
}
}
private void executeOracleScript(Reader reader) {
StringBuffer command = new StringBuffer();
try {
boolean plsqlMode = false;
BufferedReader lineReader = new BufferedReader(reader);
String line;
while ((line = lineReader.readLine()) != null) {
String trimmedLine = line.trim();
if (trimmedLine.length() == 0) {
continue;
}
if (trimmedLine.matches("[/.]")) {
/*
Terminate PL/SQL subprograms by entering a period (.) by itself on
a new line. You can also terminate and execute a PL/SQL subprogram
by entering a slash (/) by itself on a new line.
*/
System.out.println("Executing Oracle Script");
println(command);
logs.writeFile("Executing : " +command.toString());
String cm = command.toString();
executeStatement(cm.trim());
plsqlMode = false;
command.setLength(0);
} else if (!plsqlMode &&
(blockStart.matcher(command).find() ||
"begin".equalsIgnoreCase(line) ||
"declare".equalsIgnoreCase(line)
)
) {
plsqlMode = true;
command.append(line);
command.append(LINE_SEPARATOR);
} else if (!plsqlMode &&
( ("exit" + delimiter).equalsIgnoreCase(line) ||
"exit".equalsIgnoreCase(line)
)
) {
return;
} else if (!plsqlMode && line.endsWith(delimiter)) {
command.append(line.substring(0, line.lastIndexOf(delimiter)));
println(command);
logs.writeFile("Executing : " +command.toString());
executeStatement(command.toString().trim());
command.setLength(0);
} else {
command.append(line);
command.append(LINE_SEPARATOR);
}
}
// Check to see if we have an unexecuted statement in command.
if (command.length() > 0) {
println(command);
logs.writeFile("Executing : " +command.toString());
executeStatement(command.toString().trim());
}
commitConnection();
checkForMissingLineTerminator(command);
} catch (Exception e) {
String message = "\nError executing: \n" + command + "Cause: " + e;
logs.writeFile(message);
throw new RuntimeException(message, e);
}
}
public void run(String sql) throws SQLException {
Statement stmt = connection.createStatement();
try {
stmt.execute(sql);
} finally {
try {
stmt.close();
} catch (SQLException e) {
//ignore
}
}
}
public void closeConnection() {
try {
connection.close();
} catch (Exception e) {
// ignore
}
}
private void setAutoCommit() {
try {
if (autoCommit != connection.getAutoCommit()) {
connection.setAutoCommit(autoCommit);
}
} catch (Throwable t) {
throw new RuntimeException("Could not set AutoCommit to " + autoCommit + ". Cause: " + t, t);
}
}
private void commitConnection() {
try {
if (!connection.getAutoCommit()) {
connection.commit();
}
} catch (Throwable t) {
throw new RuntimeException("Could not commit transaction. Cause: " + t, t);
}
}
private void rollbackConnection() {
try {
if (!connection.getAutoCommit()) {
connection.rollback();
}
} catch (Throwable t) {
// ignore
}
}
private void checkForMissingLineTerminator(StringBuffer command) {
if (command != null && command.toString().trim().length() > 0) {
logs.writeFile("Line missing end-of-line terminator (" + delimiter + ") => " + command);
throw new RuntimeException("Line missing end-of-line terminator (" + delimiter + ") => " + command);
}
}
private StringBuffer handleLine(StringBuffer command, String line) throws SQLException, UnsupportedEncodingException {
String trimmedLine = line.trim();
if (commandReadyToExecute(trimmedLine)) {
command.append(line.substring(0, line.lastIndexOf(delimiter)));
command.append(LINE_SEPARATOR);
logs.writeFile("Executing : " +command.toString());
println(command);
executeStatement(command.toString());
command.setLength(0);
} else if (trimmedLine.length() > 0) {
command.append(line);
command.append(LINE_SEPARATOR);
}
return command;
}
private boolean commandReadyToExecute(String trimmedLine) {
return !fullLineDelimiter && trimmedLine.endsWith(delimiter)
|| fullLineDelimiter && trimmedLine.equals(delimiter);
}
private void executeStatement(String command) throws SQLException, UnsupportedEncodingException {
boolean hasResults = false;
Statement statement = connection.createStatement();
if (stopOnError) {
hasResults = statement.execute(command);
} else {
try {
hasResults = statement.execute(command);
} catch (SQLException e) {
logs.writeFile("Error : " + e.getMessage());
}
}
printResults(statement, hasResults);
try {
statement.close();
} catch (Exception e) {
// Ignore to workaround a bug in some connection pools
}
}
private void printResults(Statement statement, boolean hasResults) {
try {
if (hasResults) {
ResultSet rs = statement.getResultSet();
if (rs != null) {
ResultSetMetaData md = rs.getMetaData();
int cols = md.getColumnCount();
for (int i = 0; i < cols; i++) {
String name = md.getColumnLabel(i + 1);
print(name + "\t");
}
println("");
while (rs.next()) {
for (int i = 0; i < cols; i++) {
String value = rs.getString(i + 1);
print(value + "\t");
}
println("");
}
}
}
} catch (SQLException e) {
logs.writeFile("Error : " + e.getMessage());
printlnError("Error printing results: " + e.getMessage());
}
}
private void print(Object o) {
if (logWriter != null) {
logWriter.print(o);
logWriter.flush();
}
}
private void println(Object o) {
if (logWriter != null) {
logWriter.println(o);
logWriter.flush();
}
}
private void printlnError(Object o) {
if (errorLogWriter != null) {
errorLogWriter.println(o);
errorLogWriter.flush();
}
}
}
答案 0 :(得分:0)
试试。
ScriptRunner逐行发送给DB。当脚本具有分隔符($$,&amp;&amp;,||)时,该行将自动执行。要解决此问题,您需要使用最新版本的ScriptRunner并设置为发送完整脚本(runner.setSendFullScript(true))。