[英]PostgreSQL - batch + script + variable
我不是程序員,為此我有點掙扎。
我有一個批處理文件連接到我的PostgreSQL服務器,然后打開一個sql腳本。 一切正常。 我的問題是如何將變量(如果可能)從一個傳遞到另一個。
這是我的批處理文件:
set PGPASSWORD=xxxx
cls
@echo off
C:\Progra~1\PostgreSQL\8.3\bin\psql -d Total -h localhost -p 5432 -U postgres -f C:\TotalProteinImport.sql
這是腳本:
copy totalprotein from 'c:/TP.csv' DELIMITERS ',' CSV HEADER;
update anagrafica
set pt=(select totalprotein.resultvalue from totalprotein where totalprotein.accessionnbr=anagrafica.id)
where data_analisi = '12/23/2011';
delete from totalprotein;
這很好用,現在的問題是如何傳遞一個帶有data_analisi
日期的data_analisi
? 像批處理文件中一樣,“請輸入日期”,然后將該值傳遞到sql腳本。
CREATE OR REPLACE FUNCTION f_myfunc(date)
RETURNS void AS
$BODY$
CREATE TEMP TABLE t_tmp ON COMMIT DROP AS
SELECT * FROM totalprotein LIMIT 0; -- copy table-structure from table
COPY t_tmp FROM 'c:/TP.csv' DELIMITERS ',' CSV HEADER;
UPDATE anagrafica a
SET pt = t.resultvalue
FROM t_tmp t
WHERE a.data_analisi = $1
AND t.accessionnbr = a.id;
-- Temp table is dropped automatically at end of session
-- In this case (ON COMMIT DROP) after the transaction
$BODY$
LANGUAGE sql;
您可以將語言SQL用於這種簡單的SQL批處理。
如您所見,我對腳本進行了一些修改,這些修改應該使其變得更快,更干凈和更安全。
要將數據臨時讀取到空表中,請使用臨時表 。 節省了大量的光盤寫操作,並且速度更快。
為了簡化過程,我使用您現有的表totalprotein
作為模板來創建(空)臨時表。
如果要刪除表的所有行,請使用TRUNCATE而不是DELETE FROM。 快多了。 在這種情況下,您不需要。 臨時表將自動刪除。 參見功能注釋。
您更新的方式anagrafica.pt
你會列設置為NULL
,如果有什么不順心的過程中( date
沒有發現,錯誤的date
, id
沒有找到......)。 我重寫UPDATE的方式,只有在找到匹配的數據時才會發生。 我認為那是您真正想要的。
然后在shell腳本中要求用戶輸入,並以date為參數調用該函數。 這就是它在Linux shell中的工作方式(以用戶postgres的身份,無需密碼即可訪問(使用pg_haba.conf
IDENT
方法):
#! /bin/sh
# Ask for date. 'YYYY-MM-DD' = ISO date-format, valid with any postgres locale.
echo -n "Enter date in the form YYYY-MM-DD and press [ENTER]: "
read date
# check validity of $date ...
psql db -p5432 -c "SELECT f_myfunc('$date')"
-c
使psql執行一個singe SQL命令,然后退出。 昨天,我在一個有點相關的答案中對psql及其命令行選項做了很多介紹。
相應的Windows批處理文件的創建仍然是您的練習。
錯誤消息告訴您:
函數tpimport(未知)不存在
請注意小寫字母: tpimport
。 我懷疑您使用混合大小寫字母來創建函數。 因此,現在您每次使用函數名稱時都必須用雙引號將其引起來。
試試這個(引號編輯!):
C:\Progra~1\PostgreSQL\8.3\bin\psql -d Total -h localhost -p 5432 -U postgres
-c "SELECT ""TPImport""('%dateimport%')"
注意在這里我如何使用單數和雙引號 。 我猜這可能在Windows下工作。 看這里 。
當您選擇在PostgreSQL中使用大小寫混合的標識符時,您自己很難做到這一點,我從不厭倦對此提出警告。 現在,每次使用時,都必須對函數名稱"TPImport"
加雙引號。 雖然合法,但我絕對不會這么做。 我使用小寫字母作為標識符。 總是。 這樣,我永遠不會混淆大小寫,也不必使用雙引號。
最終的解決方法是使用小寫名稱重新創建該函數(只需省略雙引號,它將自動折疊為小寫)。 然后,函數名稱將不加引號就可以使用。
psql
支持文本替換變量。 在psql
,可以使用\\set
它們,也可以使用:varname
來使用它們。
\set xyz 'abcdef'
select :'xyz';
?column?
----------
abcdef
也可以使用命令行參數來設置這些變量:
psql -v xyz=value
唯一的問題是,這些文本替換總是需要對引用進行一些修改,如第一個\\set
和select
。
在Postgres中創建函數后,必須在Postgres版本的bin目錄中創建.bat文件,例如C:\\Program Files\\PostgreSQL\\9.3\\bin
。 在這里寫:
@echo off
cd C:\Program Files\PostgreSQL\9.3\bin
psql -p 5432 -h localhost -d myDataBase -U postgres -c "select * from myFunction()"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.