2017-05-03 61 views
0

我試圖從我的Java應用程序中運行SQL腳本。這是我的代碼:使用提供的密碼在PostgreSQL上運行SQL腳本

Runtime rt = Runtime.getRuntime(); 
rt.exec("setx PGPASSWORD \"" + password + "\""); 
String command = String.format("psql -d %s -h %s -p %s -U %s -w -f %s", 
     database, host, port, user, "create_tables.sql"); 
System.out.println("Executing command " + command); 
Process p = rt.exec(String.format(command)); 
p.waitFor(); 

這將打印

psql -d routes -h localhost -p 5432 -U postgres -w -f create_tables.sql 

預期。

但是在我的數據庫登錄我看到以下內容:

PSQL:fe_sendauth:沒有密碼提供

如何提供密碼,以psql調用它的過程是什麼時候?

+0

@Peter Mortensen您的編輯引起了一些混淆,因爲'psql'和Postgres不是一回事。 Psql只是postgres提供的shell。 – HimBromBeere

回答

0

您的環境變量應設置在與執行psql相同的過程中。當您執行兩個不同的進程時,這不會發生在您的代碼中。

問題是,環境變量對進程上下文是本地的。

新進程獲取父級環境的副本,但每個副本都是獨立的。 在你的情況下,Java進程創建子進程,修改PGPASSWORDsetx命令 - 到目前爲止這麼好。

但是,這並不影響Java過程。您的第二個子進程沒有運行在shell中,因此它忽略了PGPASSWORD變量,因爲該進程是使用OS服務創建的。這些服務考慮到Java進程的舊上下文,它不知道PGPASSWORD,除非在啓動原始(父級)Java進程之前更改shell中的環境。

因此,要解決您的問題,您必須設置環境變量,然後將該子項作爲shell命令運行(cmd /c)。 要設置環境變量,我們可以按照@Little Santi的建議。

因此,代碼看起來像下面

Runtime rt = Runtime.getRuntime(); 
String setCommand="PGPASSWORD=" + password; 

String command = String.format("psql -d %s -h %s -p %s -U %s -w -f %s", 
     database, host, port, user, "create_tables.sql"); 

String finalCommand = "cmd /c \" " + command +"\""; 
System.out.println("Executing command " + finalCommand); 

Process p = rt.exec(finalCommand ,new String[]{setCommand}); 
p.waitFor(); 

編輯2:

+0

我仍然收到相同的錯誤。我添加了一個手錶,以'multiCommands'雖然並被supprised:'cmd/c「啓動setx PGPASSWORD = xxx && psql -d路由-h本地主機-p 5432 -U postgres -w -f create_tables.sql」' – HimBromBeere

+0

@HimBromBeere我看你有沒有厭倦手動執行上述操作(dos提示符 - 命令行)是否可以工作呢?還有爲什麼在你的'setx'命令中有'='符號?這不是一個錯誤的語法? – Plirkee

+0

@HimBromBeere我編輯了我的答案 - 請嘗試一下 - 還告訴我,你現在可能是什麼'multiCommands'看起來像... – Plirkee

相關問題