簡體   English   中英

如何用Java在Windows中的一個命令中執行多個命令和psql查詢?

[英]How can I execute multiple commands and psql queries in one command for Windows in Java?

我正在用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子句將已經刪除了“自己的”會話。

然后,您需要運行一次傳遞該腳本的psql (並且沒有其他命令行工具),方法是將以上內容寫入臨時文件並使用-f參數,或者使用-c將所有內容作為單個命令傳遞

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

但是,我認為通過JDBC與Statement.execute()來實現一點比嘗試與ProcessBuilder對抗是一個更好的解決方案(它的代碼少得多,問題少得多,而且控制起來也更容易)。

您想要的是不可能的; 顯然,您想要“一個命令”的原因是您希望此操作是瞬時的; 在強制殺死所有打開的PSQL連接和運行dropdb之間沒有時間。 那不是它的工作原理,shell只是一個接一個地執行這些命令。

所以..做同樣的事情:首先運行一個命令(使正在運行的進程構建器並運行該命令;然后既不需要cmd.exe / c,也可以運行),然后等待該命令完成,然后制作另一個processbuilder並運行dropdb命令。

另外,對於第一個命令,您實際上根本不需要processbuilder。 您也可以使用JDBC發送該查詢。 您還可以使用JDBC發送DROP DATABASE查詢,這是dropdb命令在后台執行的操作。 然后,就不再需要processbuilder。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM