3

Basically, what I want to achieve is something like this:

mypath:= '~/Desktop/' || my_variable || '.csv'
COPY (SELECT * FROM my_table) TO mypath CSV DELIMITER ',' HEADER;

Where the value of my_variable will change dynamically.

Can someone help me on this problem?

2 Answers 2

2

Here and here you can find two different options (either via a bash script or a sql script with variables) to solve your problem.

Since you are using windows the only viable solution is the one with the variable in the sql file. With Windows you should also be able to use the psql command line utility to execute your sqlfile and pass the path as a parameter like this:

-- Example sql file content:
COPY (SELECT * FROM my_table) TO :path CSV DELIMITER ',' HEADER;

Command line example

psql -f /tmp/file.sql -v path='~/Desktop/' || my_variable || '.csv'

Another option i just found would be to output the content of the csv to stdout and forwarding that to file on the windows cmd level. Example code (based on this answer Linux Example code):

psql -c "COPY (SELECT * FROM my_table) TO STDOUT CSV DELIMITER ',' HEADER;" > '~/Desktop/' || my_variable || '.csv'

EDIT1 based on the new requirement that the variable comes out of the postgresql database:

I quickly built a For loop which can loop over the result of a separate query and then execute a sql query for each of the values in the result:

Example code:

DO $$
  declare
    result record;
BEGIN
    FOR result IN Select * FROM (VALUES ('one'), ('two'), ('three')) AS t (path) LOOP 
        RAISE NOTICE 'path: ~/Desktop/%.csv', test.path;
    END LOOP;
END; $$;

This produces the following output:
NOTICE:  path: ~/Desktop/one.csv
NOTICE:  path: ~/Desktop/two.csv
NOTICE:  path: ~/Desktop/three.csv

You can substitue the Select * FROM (VALUES ('one'), ('two'), ('three')) AS t (path) with any query which produces the table result which contains one path per row.

Second you can substitue the RAISE NOTICE 'path: ~/Desktop/%.csv', test.path; with your copy query

Sign up to request clarification or add additional context in comments.

5 Comments

I understand your ideas, and I think they are good, but in reality I want to do this inside my postgres script. I don't want to run this script by command line or passing arguments. I want that field my_variable, changes the value by the data that exiss on database e.g if I have a table that has two values: one, two The postgres script should iterate for the table and copy first to the '~/Desktop/one.csv' and after to the '~/Desktop/two.csv', but this must be automatically without any type of user input
@francisco: Ah makes sense if the variable comes from within postgresql. Well postgresql has very powerful Control structures (for loop, if else, etc) as well. You could build a for loop based on your query result. I base my answer on Section "40.6.4. Looping Through Query Results" here.
I already have done with ifs and elses, but I want to avoid that code, because I have more that 10 ifs on this moment and on the future the number of ifs will increase, so I want to do this on a clever way, but I don't find yet a way to do that
@franciso: I provided an example sql for loop now in the answer which you can use to adjust it to your needs.
Doesn't work for me: ``` syntax error at or near "/"``` the generated command is missing the encosing single quotes for the destination path.
0

You can use EXECUTE command. A working example is:

sql_copy_command= ' COPY abc_schema_name.xyz_table_name FROM ''' || masterFilePath ||''' DELIMITER '';'' CSV HEADER ' ;

RAISE NOTICE 'sql_copy_command: % ', sql_copy_command; EXECUTE sql_copy_command;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.