我可能在这里扭曲postgres,但从根本上说,我想做的是使用字符串变量并将其传递给sql命令(在本例中为COPY),仅使用psql。
所以这就是我想出来的。命令分为2个文件,因为我希望能够在其他情况下使用mydb_functions:
文件一:mydb_functions - 1.0.sql(在共享/扩展中,并且mydb_functions.control也按照手册中的描述进行设置。给定一个文件名,返回一个完整的文件路径。这只是为了在add_data中创建COPY语句.sql下面,neater。
CREATE OR REPLACE FUNCTION fpn(filename text) RETURNS TEXT as '
DECLARE
mypath text := ''/path/to/my/directory/'';
BEGIN
RETURN mypath || filename;
END
' LANGUAGE plpgsql;
文件二:add_data.sql。这仅用于在命令行使用psql将数据复制到现有的postgres表中。注意:由于CREATE EXTENSION命令,因此需要运行具有超级用户权限的psql。
CREATE EXTENSION IF NOT EXISTS mydb_functions;
-- haven't figured out how to create a function without arguments yet.
CREATE OR REPLACE FUNCTION test (dummyvar text) RETURNS text as '
DECLARE
filepath RECORD;
BEGIN
SELECT * INTO filepath from fpn(''mydatafile.data'');
COPY tablename (columnname) FROM filepath;
END
' LANGUAGE plpgsql;
我坚持的部分是如何从文件路径记录中提取文本以在COPY命令中使用。任何有关实现这一目标的简单方法的提示也是受欢迎的。我认为创建一个表来存储变量要比这容易得多。但我想完成最后一步。
答案 0 :(得分:0)
如果您的问题正在使用动态目标路径COPY
运行,请使用EXECUTE
运行format
SQL查询。
CREATE OR REPLACE FUNCTION test () RETURNS text as $$
DECLARE
filepath RECORD;
BEGIN
SELECT * INTO filepath from fpn('mydatafile.data');
EXECUTE format('COPY tablename (columnname) FROM %L', filepath);
END
$$ LANGUAGE plpgsql;
看,这失败了:
DO
$$
DECLARE
somevar text;
BEGIN
somevar := '/tmp/somepath.csv';
COPY tablename(columnname) FROM somevar;
END;
$$;
但这有效:
DO
$$
DECLARE
somevar text;
BEGIN
somevar := '/tmp/somepath.csv';
EXECUTE format('COPY tablename(columnname) FROM %L', somevar);
END;
$$;
请参阅:
format()
的{{1}}说明符会自动引用文字。 %L
对标识符也是如此。
如果按照我原先的想法,您正在讨论从外部将数据导入%I
,您可能会发现psql
变量和变量插值很有用:
psql
请注意冒号未加引号,然后引用变量名称。奇怪的语法,我知道。这仅适用于$ psql -v filepath=/path/to/my/directory/mydatafile.data regress
regress=> SELECT :'filepath';
?column?
---------------------------------------
/path/to/my/directory/mydatafile.data
(1 row)
;它不适用于(例如)PgAdmin-III。
或者,你可以使用here-document(特定于unix的shell,在Windows psql
中不起作用)来进行引用文本插值:
cmd.exe
这两个都展示了如何将shell级别的变量插入$ FILEPATH=/path/to/my/directory/mydatafile.data
$ psql regress <<__END__
SELECT '$FILEPATH';
__END__
?column?
---------------------------------------
/path/to/my/directory/mydatafile.data
(1 row)
。从那里开始,就是在你的功能中使用它。就像这样,用psql
:
-v filename=myfilename.csv
或仅使用CREATE OR REPLACE FUNCTION test() RETURNS text as $$
DECLARE
filepath RECORD;
BEGIN
SELECT * INTO filepath from fpn(:'filename');
COPY tablename (columnname) FROM filepath;
END
$$ LANGUAGE plpgsql;
:
-v filepath=/full/path/to/myfilename.csv