java - 在 shell 脚本中在 oracle DB 上执行.sql 文件

标签 java oracle docker sqlplus

我想在 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/

相关文章:

java - 使用可执行 jar 时将配置文件加载到类路径中

java - 为什么不使用更具大小确定性的类型来实现 BitSet?

java - 从java如何调用存储过程传递oracle游标作为参数

oracle - 您能否在同时连接不同元素的 listagg 函数中插入回车符?

docker - Docker 镜像会保存内存状态吗?

java - 将 Java POJO 转换为 PactDslJsonBody

java - 将每个以相同字符开头的键映射到单词列表

sql - 更新多个表的查询

docker - 自定义Docker桥接网络

docker - 从Docker在主机上生成的文件