I'm new to Postgresql and struggling to build a function for looping over a series of CSV files and loading them. I can make the COPY work just fine with a single file, but I'm unable to get the FOR LOOP syntax correct. I'm trying to substitute a year number as my flies are named /path/tmp.YEAR.out.csv
This is what I've hacked up:
CREATE OR REPLACE FUNCTION test() RETURNS void as $$
BEGIN
FOR i IN 1982..1983 LOOP
COPY myTable
FROM '/path/tmp.' || i::VARCHAR || '.out.csv'
delimiters ','
END LOOP;
END;
$$ LANGUAGE 'plpgsql';
This throws an error at the first ||. So I suspect I'm managing the concat of the variable i
improperly. Any tips?
:= is the assignment operator in PL/pgSQL. The expression searchsql:= searchsql || ' WHERE 1=1 ' ; appends the string ' WHERE 1=1 ' to the current value of the variable searchsql.
The PostgreSQL concatenate operator ( || ) is used to concatenate two or more strings and non strings.
PostgreSQL allows you to directly concatenate strings, columns and int values using || operator. Here is the SQL query to concatenate columns first_name and last_name using || operator. You can even concatenate string with int using || operator.
CREATE OR REPLACE FUNCTION test() RETURNS void as $$
BEGIN
FOR i IN 1982..1983 LOOP
EXECUTE 'COPY myTable FROM ''/path/tmp.' || i::text
|| '.out.csv'' DELIMITERS '',''; ';
END LOOP;
END;
$$ language plpgsql;
I don't think I'd use plpgsql for that. A shell script could be much more generally useful:
#!/bin/sh
DBHOST=mydbhost
DBNAME=mydbname
files=$1
target=$2
for file in ${files}; do
psql -h ${DBHOST} ${DBNAME} -c "\copy ${target} FROM '${file}' delimiters ','"
done
example usage:
csv2psql "$(ls *.out.csv)" someschema.tablename
Note: This way you also sidestep the problem of reading files with COPY which requires the postgres server user to have read permissions on the file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With