我想在 Oracle DB 上从 shell 脚本执行使用 sql*plus 命令编写的 .sql
文件。
下面是一个 .sql
文件的示例:
SET DEFINE OFF;
-- Changeset om-core/om-core.sys.db-changelog.xml::om-core-createUser.24.0.0::mlo
-- Creating om-dashboard schema/user
CREATE USER omcore27 IDENTIFIED BY omcore;
GRANT CONNECT TO omcore27;
GRANT CREATE TABLE TO omcore27;
GRANT CREATE SEQUENCE TO omcore27;
GRANT CREATE ANY INDEX, SELECT ANY TABLE TO omcore27;
GRANT CREATE TRIGGER TO omcore27;
GRANT CREATE PROCEDURE TO omcore27;
GRANT UNLIMITED TABLESPACE TO omcore27;
GRANT EXECUTE ON SYS.DBMS_AQADM to omcore27;
GRANT EXECUTE ON SYS.DBMS_AQ to omcore27;
ALTER USER omcore27 QUOTA UNLIMITED ON SYSTEM;
GRANT SELECT ON SYS.DBA_RECYCLEBIN TO omcore27;
GRANT EXECUTE ON DBMS_AQIN to omcore27;
GRANT select on v_$sysmetric to omcore27;
GRANT select on dba_hist_sysmetric_summary TO omcore27;
GRANT create job TO omcore27;
GRANT create external job TO omcore27;
-- Changeset om-core/om-core.sys.db-changelog.xml::om-core-grantAQ.24.0.0::mlo
begin
DBMS_AQADM.GRANT_SYSTEM_PRIVILEGE (privilege => 'ENQUEUE_ANY', grantee => 'omcore27', admin_option => FALSE);
DBMS_AQADM.GRANT_SYSTEM_PRIVILEGE (privilege => 'DEQUEUE_ANY', grantee => 'omcore27', admin_option => FALSE);
DBMS_AQADM.GRANT_SYSTEM_PRIVILEGE (privilege => 'MANAGE_ANY', grantee => 'omcore27', admin_option => FALSE);
end;/
所以我需要一个 shell 命令来在 oracleDB 上执行上面的 .sql
文件。
我已经尝试使用 java 程序执行此操作,然后从 shell 脚本运行该程序 .jar
,但出现错误:
Line: SET DEFINE OFF;
*** Error : java.sql.SQLSyntaxErrorException: ORA-00922: missing or invalid option
这是我的 DBScriptRunner 类的源代码:
public class DBScriptRunner {
public static void main(String[] args) {
try {
String pathname = args[0];
System.out.println("path name: " +pathname);
executeScript(pathname);
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
static void executeScript(String scriptFilePath) throws IOException, SQLException {
// initialize script path
// String scriptFilePath = "e:/script.sql";
BufferedReader reader = null;
Connection con = null;
Statement statement = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
// create connection
con = DriverManager.getConnection("jdbc:oracle:thin:@//hostname:1521/romdb", "user",
"pwd");
statement = con.createStatement();
// initialize file reader
reader = new BufferedReader(new FileReader(scriptFilePath));
String line = null;
// read script line by line
while ((line = reader.readLine()) != null) {
// execute query
if (line.startsWith("--")|| line.isEmpty()) {
System.out.println("comment line or empty line: " + line);
} else {
System.out.println("Line: " + line);
statement.execute(line);
}
}
} catch (Exception e) {
System.out.println("*** Error : "+e.toString());
System.out.println("*** ");
System.out.println("*** Error : ");
e.printStackTrace();
} finally {
// close file reader
if (reader != null) {
reader.close();
}
// close db connection
if (con != null) {
con.commit();
con.close();
}
}
}
}
你有什么想法吗?
最佳答案
您的脚本只需要调用 SQL*Plus 本身。假设与 Oracle 相关的环境变量已在您要从中调用的 shell 中设置,基本格式为:
sqlplus -l -s user/pwd@hostname:1521/romdb @your_script.sql
或者如果您的脚本末尾没有退出
,则使用重定向:
sqlplus -l -s user/pwd@hostname:1521/romdb < your_script.sql
如果提供的凭据因任何原因无法工作,-l
标志可防止它重新提示输入凭据,这在无人值守运行脚本时特别有用。 -s
标志会抑制 SQL*Plus 横幅并在命令运行时回显命令。
然后您可以通过多种方式对其进行调整和扩展,例如在脚本中设置环境,将输出捕获添加到日志文件中,或者隐藏命令行中的登录凭据,以便它们对 ps
不可见,等等。后者可能看起来像:
sqlplus -s /nolog <<EOF
connect user/pwd@hostname:1521/romdb
@your_script.sql
EOF
关于java - 在 shell 脚本中在 oracle DB 上执行.sql 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52420294/