java - 如何在 Java 的 Windows 的一个命令中执行多个命令和 psql 查询?

标签 java windows postgresql

我正在用 Java 编写一些代码来自动从云端恢复备份。为此,我需要在 Windows 的 (CMD) 命令行工具中用一个命令打开 psql、终止连接、退出 psql 和删除数据库,以便 Java 可以一次性执行。这些分别是单独的步骤(我认为);

psql -h localhost -p 5433 -U postgres -w OC_A -c '
SELECT 
    pg_terminate_backend(pid) 
FROM 
    pg_stat_activity 
WHERE 
pid <> pg_backend_pid();
/q postgres-# \q ;'
dropdb -h localhost -p 5433 -U postgres -w OC_A

我已将这些步骤放入一个单独的 cmd 命令中;



// 2 - terminate db connections, delete based on config db's
String terminateSQLconnecitons= "\npsql -h "+ postgresHost + " -p " + postgresPort + " -U " + postgresUsername + " -w " + postgresDbname + " -c "+
"\'\nSELECT pg_terminate_backend(pid)  FROM pg_stat_activity  WHERE  pid <> pg_backend_pid();\n/q postgres-# \\q ;'" ;
int terminateSQLconnecitonsResult = cmdExe(terminateSQLconnecitons);
if (terminateSQLconnecitonsResult == 0) {
    System.out.println("Connections terminated");
} else {
    System.out.println("CONNECTIONS NOT TERMINATED");
}

public static int cmdExe(String cmd) {
    ProcessBuilder processBuilder = new ProcessBuilder();
    processBuilder.redirectErrorStream(true);
    processBuilder.command("cmd.exe", "/c", cmd);
    System.out.println(cmd);
    int exitCode = -1;

    try {
        Process process = processBuilder.start();
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
        exitCode = process.waitFor();
        System.out.println("Result :" + exitCode);

    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return exitCode;
}

要在 Java 的一个命令中执行这些步骤,我需要在哪里/更改什么?

编辑 1;我现在已经有了单独的步骤,但似乎没有用。我不明白为什么。

                    // 2 - terminate db connections, delete based on config db's
                    String terminateSQLconnecitons= "\npsql -h "+ postgresHost + " -p " + postgresPort + " -U " + postgresUsername + " -w " + postgresDbname + " -c "+
                    "\'\nSELECT pg_terminate_backend(pid)  FROM pg_stat_activity  WHERE  pid <> pg_backend_pid();\n/q postgres-# \\q ;'" ;
                     int terminateSQLconnecitonsResult = cmdExe(terminateSQLconnecitons);
                     if (terminateSQLconnecitonsResult == 0) {
                        System.out.println("Connections terminated");
                    } else {
                        System.out.println("CONNECTIONS NOT TERMINATED");
                    }

                    String DeleteCMD= "\ndropdb -h "+ postgresHost + " -p " + postgresPort + " -U " + postgresUsername + " -w " + postgresDbname;
                    int cmdResult = cmdExe(DeleteCMD);
                    if (cmdResult == 0) {
                            System.out.println("Database " + postgresDbname + " deleted");
                        } else {
                            System.out.println("Database " + postgresDbname + " NOT deleted");
                        }

最佳答案

通过将所有内容放入单个 SQL 脚本中,您可以大大简化这一切。要运行脚本,请连接到一个不同的数据库,例如template1 .

-- prevent new connections between the moment you killed everything 
-- and the moment where the database is dropped    
alter database your_db_name allow_connections false;

select pg_terminate_backend(pid)
from pg_stat_activity
where datname = 'your_db_name'
  and pid <> pg_backend_pid();

drop database your_db_name;

and pid <> ...并不是真的需要,因为该脚本没有连接到要删除的数据库,因此目标数据库上的 where 子句已经删除了您的“自己的” session 。

然后你只需要运行psql一次(没有其他命令行工具)传递该脚本,方法是将上述内容写入临时文件并使用 -f参数或使用 -c 将所有内容作为单个命令传递

psql -c "alter database your_db_name allow_connections false; select ... where ...; drop database your_db_name"

但是我认为通过 JDBC 使用 Statement.execute() 来做到这一点是一个好得多的解决方案,试图对抗 ProcessBuilder(它的代码少得多,问题少得多,而且更容易控制)。

关于java - 如何在 Java 的 Windows 的一个命令中执行多个命令和 psql 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57393569/

相关文章:

c - LoadImage 的工作方式因获胜颜色设置而异

postgresql - SqlAlchemy:使用 `get or create` 模式锁定表

postgresql - 将 SETOF 转换为字符串

java - @qualifier 不能与 @Component 一起使用

java - 如何将所有字节发送到单个数组中,然后在字节之间进行异或?

windows - 在 Program Files 与 Appdata 中安装

windows - 批量在网络文件夹中创建文件夹

postgresql - 如何更改 Postgres 中的日期格式?

java - 旋转光标或光标图像 Java

java - 如何添加没有Jar的库