您可以像这样从您的 SQL 脚本中create a function:
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 批处理可以使用language SQL。
如您所见,我对您的脚本进行了一些修改,以使其更快、更清晰、更安全。
要点
要临时将数据读入空表,请使用temporary table。节省大量磁盘写入,速度更快。
为了简化流程,我使用您现有的表 totalprotein 作为创建(空)临时表的模板。
如果要删除表的所有行,请使用 TRUNCATE 而不是 DELETE FROM。快多了。在这种特殊情况下,您都不需要。临时表会自动删除。见函数中的 cmets。
您更新anagrafica.pt 的方式将列设置为NULL,如果在此过程中任何事情 出错(date 未找到,错误date,@ 987654334@ 未找到...)。我重写 UPDATE 的方式,只有在找到匹配的数据时才会发生。我想这就是你真正想要的。
然后在您的 shell 脚本中请求用户输入并以日期作为参数调用该函数。这就是它在 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 执行一条 SQL 命令然后退出。我昨天在psql and its command line options 上写了很多相关的答案。
创建相应的 Windows 批处理文件仍然是您的练习。
Windows下调用
错误信息告诉你:
函数 tpimport(unknown) 不存在
注意小写字母:tpimport。我怀疑您使用混合大小写字母来创建函数。所以现在每次使用函数名时都必须用双引号括起来。
试试这个(编辑过的引号!):
C:\Progra~1\PostgreSQL\8.3\bin\psql -d Total -h localhost -p 5432 -U postgres
-c "SELECT ""TPImport""('%dateimport%')"
请注意我在这里如何使用单引号和双引号。我猜这可以在 Windows 下工作。见here。
当您选择在 PostgreSQL 中使用 混合大小写标识符 时,您自己很难受 - 这是我从不厌倦警告的愚蠢行为。现在你必须在每次使用函数名"TPImport" 时将其双引号。虽然完全合法,但我永远不会这样做。我使用小写字母作为标识符。总是。这样我就不会混淆小写/大写,也不必使用双引号。
最终修复是用小写名称重新创建函数(只需去掉双引号,它将自动折叠为小写)。然后函数名称将无需任何引用即可正常工作。
阅读basics about identifiers here。
另外,考虑升级到更新版本的 PostgreSQL 8.3 现在有点生疏了。