2011-06-06 31 views
6

Tôi mới dùng Postgresql và đang cố gắng xây dựng một hàm để lặp qua hàng loạt tệp CSV và tải chúng. Tôi có thể làm cho COPY hoạt động tốt với một tệp duy nhất, nhưng tôi không thể nhận cú pháp FOR LOOP đúng. Tôi đang cố gắng để thay thế một số năm như ruồi của tôi được đặt tên /path/tmp.YEAR.out.csvplpgsql: nối biến vào mệnh đề FROM

Đây là những gì tôi đã bị hack lên:

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'; 

này ném một lỗi ở đầu tiên ||. Vì vậy, tôi nghi ngờ tôi đang quản lý concat của biến i không đúng cách. Có lời khuyên nào không?

+0

Chúng tôi có được phép thêm thẻ 'r' và giải quyết theo cách đó không? –

+0

Tôi chắc chắn đã nghĩ về điều đó ... nhưng tôi cần tải nhanh lệnh postgresql COPY ... Tôi có vài chục tệp ~ 500MB. –

+0

@dirk, nếu tôi đã cuộn chuỗi truy vấn trong R, tôi có thể gửi nó dưới dạng truy vấn không? Tôi đã nghĩ rằng tôi chỉ có thể làm điều đó với sql đơn giản, không phải là plpgsql, vì vậy tôi thậm chí không thử. –

Trả lời

6
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; 
+0

Cảm ơn Seth. Tôi đã chắc chắn điều này đã làm với việc nhận được những thứ phân tích cú pháp và đặt lại với nhau theo thứ tự đúng. Tôi chắc chắn sẽ không giải mã được điều này nếu không có sự giúp đỡ. –

5

Tôi không nghĩ mình sẽ sử dụng plpgsql cho điều đó. Một kịch bản shell có thể là nhiều hơn nữa thường hữu ích:

#!/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 

ví dụ sử dụng:

csv2psql "$(ls *.out.csv)" someschema.tablename 

Lưu ý: Bằng cách này bạn cũng tránh các vấn đề về đọc file với COPY mà yêu cầu người dùng postgres máy chủ để đã đọc quyền trên tệp.

+1

sử dụng lệnh psql \ copy Tôi có thể bọc nó bằng bất kỳ ngôn ngữ nào. Cách tiếp cận tiện lợi. Cảm ơn! –

Các vấn đề liên quan