我正在尝试编写一个函数来将 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;
当我尝试创建这个函数时,我得到:
syntax error at $1
这是怎么回事?
最佳答案
COPY
不允许变量替换。只有核心 DML 命令 SELECT
、INSERT
、UPDATE
和 DELETE
才有可能做到这一点。见:
您需要带有 EXECUTE
的动态 SQL:
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()
需要 PostgreSQL 9.1+。
传递没有附加(转义)单引号的文件名:
SELECT loaddata('/absolute/path/to/my/file.csv')
format()
和 %L
安全地引用文件名。如果没有它,将容易受到 SQL 注入(inject)的影响。
关于sql - COPY 动态文件名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16019508/