I use the copy function in postgresql often and I thought I'd create a function to make use of it. So let's say i have the following table
create table users
(
userid serial primary key,
prefix varchar(10) not null,
firstname varchar(255) not null,
lastname varchar(255) not null,
email varchar(500) not null,
password varchar(255) not null,
created timestamp not null,
modified timestamp not null
);
and the following function
create function getUsersCSV( )
RETURNS void AS
$BODY$
BEGIN
COPY (select * from users)
TO 'c:\temp\users.csv'
WITH HEADER
CSV QUOTE '"' DELIMITER ',';
END
$BODY$
LANGUAGE PLPGSQL;
function works but if I change the function to
create function getUsersCSV( filepath varchar )
RETURNS void AS
$BODY$
BEGIN
COPY (select * from users)
TO filepath
WITH HEADER
CSV QUOTE '"' DELIMITER ',';
END
$BODY$
LANGUAGE PLPGSQL;
it throws the following syntax error ERROR: syntax error at or near "filepath" SQL state: 42601
Is there anyway to parameterize the destination value of the copy command?
You could do it with execute
:
create function get_users_csv(filepath text) returns void as $$
declare
cp_cmd text;
begin
cp_cmd := 'copy (select * from users) to '
|| quote_literal(filepath)
|| ' with header csv quote ''"'' delimiter '',''';
execute cp_cmd;
end;
$$ language plpgsql;
Don't forget to use quote_literal
on your filepath
just in case. You could also use dollar-quoting if you don't like all the doubled single quotes:
create function get_users_csv(filepath text) returns void as $$
declare
cp_cmd text;
begin
cp_cmd := $q$copy (select * from users) to $q$
|| quote_literal(filepath)
|| $q$ with header csv quote '"' delimiter ','$q$;
execute cp_cmd;
end;
$$ language plpgsql;
But I find dollar quoting to be rather ugly for anything other than blocks of text.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.