我正在尝试编写一个函数来将 csv 数据加载到表中。我希望输入参数是文件的路径。
CREATE OR REPLACE FUNCTION public.loaddata(filepathname varchar)
RETURNS void AS
$BODY$
BEGIN
COPY climatedata(
climatestationid,
date,
prcp,
prcpqflag,
prcpmflag,
prcpsflag,
tmax,
tmaxqflag,
tmaxmflag,
tmaxsflag,
tmin,
tminqflag,
tminmflag,
tminsflag)
FROM $1
WITH csv header;
END;
$BODY$
LANGUAGE plpgsql;
当我尝试创建这个函数时,我得到:
$1 处有语法错误
它出什么问题了?
COPY
不允许变量替换。这只能通过核心 DML 命令实现SELECT
, INSERT
, UPDATE
, and DELETE
. See:
- 使用 plpgsql 变量设置 n_distinct 时出错 https://stackoverflow.com/questions/36025308/error-when-setting-n-distinct-using-a-plpgsql-variable/36025963#36025963
你需要动态SQL with EXECUTE
:
CREATE OR REPLACE FUNCTION loaddata(filepathname text)
RETURNS void
LANGUAGE plpgsql AS
$func$
BEGIN
EXECUTE format ('
COPY climatedata(climatestationid, date, ..., tminsflag) -- more columns
FROM %L (FORMAT CSV, HEADER)' -- modern syntax
-- WITH CSV HEADER' -- tolerated legacy syntax
, $1); -- pass 1st function parameter (filepathname) to format()
END
$func$;
format() https://www.postgresql.org/docs/current/functions-string.html#FUNCTIONS-STRING-OTHER需要 PostgreSQL 9.1+。
传递文件名而不使用额外的(转义的)单引号:
SELECT loaddata('/absolute/path/to/my/file.csv')
format()
with %L
安全地引用文件名。会容易受到SQL注入没有它。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)