簡體   English   中英

在psql中執行.sql文件,從Excel單元格值傳遞參數

[英]Execute .sql file in psql, passing parameters from Excel cell values

我試圖在psql中執行一個.sql文件(通過.bat腳本),將test.xlsm工作簿的單元格B1B2中包含的值作為參數傳遞。 我一直在尋找一種可能的解決方案,但我不明白如何在.sql文件中引用這些值(Excel中的單元格B1和B2)。

到目前為止,這是我一直在努力的工作。

download_from_postgresql.bat文件包含以下腳本,以便建立連接並通過psql.exe運行上述的download_view.sql文件:

@echo off
setlocal
set PGPASSWORD=mypassword
"D:\PostgreSQL\10\bin\psql.exe" -h myserver.com -U myuser -d mydb -f C:/QA_nepal/download_view.sql
endlocal

download_view.sql文件包含以下腳本,以便導出直接在我連接到的PostgreSQL服務器上創建的特定視圖的.csv文件:

\copy (SELECT * FROM public_qa_stfc_india."join_tables_date_filter=custom_user_filter=none") to 'C:\\QA_nepal\\test.csv' with CSV HEADER;
\q

我所指的join_tables_date_filter = custom_user_filter = none視圖是直接在PostgreSQL服務器上創建的,看起來像這樣:

SELECT * FROM public_qa_stfc_india.step_3_joined_tables
WHERE "left"(step_3_joined_tables._0_general_start, 10) >= '2018-05-03'::text
AND "left"(step_3_joined_tables._0_general_start, 10) <= '2018-05-04'::text;

我想要做的是編輯上面包含的視圖定義,以便具有以下內容:

SELECT * FROM public_qa_stfc_india.step_3_joined_tables
WHERE "left"(step_3_joined_tables._0_general_start, 10) >= 'date_par_1'::text
AND "left"(step_3_joined_tables._0_general_start, 10) <= 'date_par_2'::text;

並將單元格B1的值傳遞給date_par_1,並將B2的值傳遞給date_par_2。 我要引用的Excel工作簿位於C:\\ QA_nepal \\ excel \\ test.xlsm中。

在這一點上,我不確定如何繼續。 我應該指示psql從Excel讀取這些值嗎? 還要在download_from_postgresql.bat中添加說明嗎? 還是應該以某種方式直接在download_view.sql文件中引用Excel中的值?

在此先感謝您的幫助,Stefano

更新2018/06/19

我設法在VB中編寫了一個宏,該宏能夠將單元格B1和B2中的值(分別為2018-01-01和2015-02-07)傳遞到.bat文件:

Sub batch()
Dim wsh As Object
Dim data_1 As String
Dim data_2 As String
Set wsh = VBA.CreateObject("WScript.Shell")
Dim waitOnReturn As Boolean: waitOnReturn = True
Dim windowStyle As Integer: windowStyle = 1

data_1 = ThisWorkbook.Sheets("Foglio1").Range("B1").Value
data_2 = ThisWorkbook.Sheets("Foglio1").Range("B2").Value

wsh.Run "C:\QA_nepal\download_from_postgresql.bat " & data_1 & " " & data_2, windowStyle, waitOnReturn

End Sub

現在,我的download_from_postgresql.bat文件如下所示:

@echo off
SET data_1=%1%
SET data_2=%2%
ECHO %data_1% 'test if the value in B1 is passed to the .bat file correctly
ECHO %data_2% 'test if the value in B2 is passed to the .bat file correctly
setlocal
set PGPASSWORD=mypassword
"D:\PostgreSQL\10\bin\psql.exe" -h myserver.com -U myuser -d mydb -v v1=%data_1% -v v2=%data_2% -f C:/QA_nepal/download_view.sql
endlocal

此時,我不確定如何在download_view.sql中引用變量v1v2

\copy (SELECT * FROM public_qa_stfc_india."join_tables_date_filter=custom_user_filter=none") to 'C:\\QA_nepal\\test.csv' with CSV HEADER;
\q

考慮到我的join_tables_date_filter = custom_user_filter = none視圖看起來像這樣:

SELECT * FROM public_qa_stfc_india.step_3_joined_tables
WHERE "left"(step_3_joined_tables._0_general_start, 10) >= '2018-05-03'::text
AND "left"(step_3_joined_tables._0_general_start, 10) <= '2018-05-04'::text;

我知道我必須用2個變量(比如說var1和var2)替換上面視圖中的日期(“ 2018-05-03”和“ 2018-05-04”),然后我必須“連接”這些變量(var1和var2)以及.bat文件(v1和v2)中的變量,我以不同的方式嘗試過,例如具有以下內容:

\copy (SELECT * FROM public_qa_stfc_india."join_tables_date_filter=custom_user_filter=none" WHERE var1 = (:v1) AND var2 = (:v2)) to 'C:\\QA_nepal\\test.csv' with CSV HEADER;
\q

和:

SELECT * FROM public_qa_stfc_india.step_3_joined_tables
WHERE "left"(step_3_joined_tables._0_general_start, 10) >= '$var1'::text
AND "left"(step_3_joined_tables._0_general_start, 10) <= '$var2'::text;

但沒有成功。 一般來說,我實際上對SQL還是很陌生,所以我可能走錯了路。 有什么建議么?

在此先感謝,Stefano

考慮使用功能來接收參數並以字符串格式運行COPY命令的功能來替換存儲的視圖,這些視圖的硬編碼日期和不接收參數。 然后讓psql調用該函數。

CREATE OR REPLACE FUNCTION my_date_filter_func(start_dt TEXT, end_dt TEXT, csv_file TEXT)
    RETURNS void AS 
$func$
  BEGIN
    EXECUTE format('COPY (SELECT * FROM public_qa_stfc_india.step_3_joined_tables s
                          WHERE LEFT(s._0_general_start, 10) >= %L
                            AND LEFT(s._0_general_start, 10) <= %L) TO %L with CSV HEADER;', 
                   start_dt, end_dt, csv_file);
  END
$func$ LANGUAGE plpgsql;

通過VBA Shell調用psql命令

...
path = "C:/QA_nepal/test.csv"
cmd_str = "psql ... -c ""SELECT my_date_filter_func('" & data_1 & "', '" & data_2 & "', '" & path & "')"""

wsh.Run cmd_str, windowStyle, waitOnReturn

最后,目前還不清楚為什么要使用LEFT()將日期字段視為文本,因為您可以直接在WHERE子句中使用日期文字,並且將其時間戳隱式定義為午夜: 00:00:00 : 00:00:00 : 00:00:00

SELECT * 
FROM public_qa_stfc_india.step_3_joined_tables s
WHERE s._0_general_start >= '2018-05-03'
  AND s._0_general_start <= '2018-05-04';

暫無
暫無

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

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