sql – 具有动态文件名的COPY

我正在尝试编写一个函数来将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 VOLATILE
  COST 100;
ALTER FUNCTION public.filltmaxa(character varying)
  OWNER TO postgres;

当我尝试创建此功能时,我得到了

Syntax error at $1

它出什么问题了?

解决方法

首先,您的函数名称不匹配:
CREATE OR REPLACE FUNCTION public.loaddata(filepathname varchar)
...
ALTER FUNCTION public.filltmaxa(character varying)

但这是一个额外的问题.

回答

你需要动态sql

CREATE OR REPLACE FUNCTION loaddata(filepathname text)
  RETURNS void AS
$func$
BEGIN

EXECUTE format ('
copY climatedata(
      climatestationid,tminsflag)
FROM %L
(FORMAT CSV,HEADER)',$1);  -- current Syntax
--- WITH CSV HEADER',$1);   -- tolerated legacy Syntax

END
$func$LANGUAGE plpgsql;

format()需要Postgresql 9.1.
这样,我们可以提供文件名而无需额外的一组(转义)单引号.呼叫:

SELECT loaddata('/absolute/path/to/my/file.csv')

这非常容易受到sql注入的影响.为了防止它,我使用%L的format()来清理文件名.这也包括必要的封闭单引号.

相关文章

SELECT a.*,b.dp_name,c.pa_name,fm_name=(CASE WHEN a.fm_n...
if not exists(select name from syscolumns where name=&am...
select a.*,pano=a.pa_no,b.pa_name,f.dp_name,e.fw_state_n...
要在 SQL Server 2019 中设置定时自动重启,可以使用 Window...
您收到的错误消息表明数据库 'EastRiver' 的...
首先我需要查询出需要使用SQL Server Profiler跟踪的数据库标...