Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用动态文件名将sql函数的输出保存到csv文件(副本)_Sql_Postgresql_Export To Csv_Sql Function - Fatal编程技术网

使用动态文件名将sql函数的输出保存到csv文件(副本)

使用动态文件名将sql函数的输出保存到csv文件(副本),sql,postgresql,export-to-csv,sql-function,Sql,Postgresql,Export To Csv,Sql Function,我正在MacOSX上运行Postgres 9.3。我试图在函数中添加一个COPY语句,以实现自动保存到文件的过程 我对任何类型的sql编码都是新手,所以这就是我目前所拥有的 CREATE FUNCTION retrieve_info(input_method TEXT, input_species TEXT) RETURNS SETOF retrieve_info_tbl AS $$ SELECT tblA.id, tblA.method, tblA.species, tblA.lo

我正在MacOSX上运行Postgres 9.3。我试图在函数中添加一个COPY语句,以实现自动保存到文件的过程

我对任何类型的sql编码都是新手,所以这就是我目前所拥有的

CREATE FUNCTION retrieve_info(input_method TEXT, input_species TEXT) RETURNS SETOF   
retrieve_info_tbl AS $$
   SELECT tblA.id, tblA.method, tblA.species, tblA.location
   FROM tblA
   WHERE method=input_method AND species=input_species
   GROUP BY id, method, species
   ORDER BY location
   COPY (SELECT * FROM retrieve_info_tbl) TO 'myfilepath/filename.csv' WITH CSV;
$$ LANGUAGE 'sql';
该函数的作用是从一个较大的表中查询一个方法和一个物种,在本例中,tblA使用多个物种、方法,并将其与其位置数据一起检索。不起作用的是
COPY
语句。因此,我想添加一条语句,在执行函数时将输出保存到.csv文件中。此外,是否可以根据输入方法和输入种类添加动态文件名.csv

虚拟数据

tblA(已填写)

检索信息tbl(空)

输出 (当COPY语句未添加到函数时)

…并希望将其保存到“/myfilepath/mtd1\u sp3.csv(动态文件名)

非常感谢,


更新:我很乐意在sql函数中使用save to语句

这是一个使用
PLPGSQL
而不是
sql
快速拼凑起来的示例

警告:必须创建为超级用户

将函数中的查询等替换为您需要的任何内容,您可以向函数中添加更多的输入参数,以根据输入参数的不同创建查询或输出文件

CREATE OR REPLACE FUNCTION copy_out_example ( p_path TEXT, p_filename_prefix TEXT, OUT file_and_path TEXT )
RETURNS TEXT AS
$func$
DECLARE
    qry TEXT;
BEGIN
    file_and_path := RTRIM(p_path,'/') || '/' || p_filename_prefix || '_' || ceil(random() * 1000000)::TEXT || '.csv';

    qry := FORMAT('COPY (select * from pg_catalog.pg_class) TO %L CSV HEADER',file_and_path);
    EXECUTE qry;
END;
$func$ LANGUAGE plpgsql STRICT SECURITY DEFINER;

SELECT copy_out_example('/path/to/the/file','some_test_file');

结果生成了一个类似于
'/path/to/the/file/some_test_file_994216.csv'

的文件,使用
格式(…)
%I
标识符格式说明符比使用
引用文字
IMO要好得多。否则,
执行
就是这样做的方法。谢谢你的回复。所以您不建议在sql中执行此操作?我发现语法更容易理解。我已经发布了一个使用
格式
函数()的修订版本@CraigRinger,稍微更正一下标识符格式说明符,我认为它应该是
%L
,因为COPY语句中的文件路径是字符串而不是SQL标识符。不管怎样,谢谢你提醒我改进它。@jO。并不是说我不建议在SQL中使用它,而是因为您需要动态文件名,所以不能在普通SQL中使用它。@bma:谢谢。所以,我想澄清一下。这不是我的sql函数的替代品,而是一个单独的“复制”函数?在这种情况下,我是否仍然需要在sql函数中添加“copy out”语句,因为函数的输入是一个文件路径。。?
create table retrieve_info_tbl (id varchar(5) PRIMARY KEY, method text, ind varchar(10),  
location text);
retrieve_info(mtd1, sp3)

id | method | ind | location
----------------------------
1a | mtd1   | sp3 | locA
1d | mtd1   | sp3 | locB
CREATE OR REPLACE FUNCTION copy_out_example ( p_path TEXT, p_filename_prefix TEXT, OUT file_and_path TEXT )
RETURNS TEXT AS
$func$
DECLARE
    qry TEXT;
BEGIN
    file_and_path := RTRIM(p_path,'/') || '/' || p_filename_prefix || '_' || ceil(random() * 1000000)::TEXT || '.csv';

    qry := FORMAT('COPY (select * from pg_catalog.pg_class) TO %L CSV HEADER',file_and_path);
    EXECUTE qry;
END;
$func$ LANGUAGE plpgsql STRICT SECURITY DEFINER;

SELECT copy_out_example('/path/to/the/file','some_test_file');