簡體   English   中英

PostgreSQL-批處理+腳本+變量

[英]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腳本。

您可以使用 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沒有發現,錯誤的dateid沒有找到......)。 我重寫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批處理文件的創建仍然是您的練習。


在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"加雙引號。 雖然合法,但我絕對不會這么做。 我使用小寫字母作為標識符。 總是。 這樣,我永遠不會混淆大小寫,也不必使用雙引號。

最終的解決方法是使用小寫名稱重新創建該函數(只需省略雙引號,它將自動折疊為小寫)。 然后,函數名稱將不加引號就可以使用。

此處閱讀有關標識符基礎知識
另外,考慮到現在升級到較新版本的PostgreSQL 8.3有點生銹。

psql支持文本替換變量。 psql ,可以使用\\set它們,也可以使用:varname來使用它們。

\set xyz 'abcdef'
select :'xyz';
 ?column? 
----------
abcdef

也可以使用命令行參數來設置這些變量:

psql -v xyz=value

唯一的問題是,這些文本替換總是需要對引用進行一些修改,如第一個\\setselect

在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.

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