2017-04-08 73 views
0

我已經在Postgres中獲得了PostGIS的PostGIS數據庫中的點數據,並且我想將幾個地理上不同區域中的點提取爲CSV文件,每個區域一個文件。如何在PostgreSQL中複製多個CSV文件?

我已成立了一個area表面積的多邊形,而且面積冠軍,我想有效地通過該表圈,使用類似的PostGIS' st_intersects()選擇數據在每個CSV文件中去,並得到文件名用於區域表中標題的CSV文件。

我對做交叉碼和設置CSV輸出的細節感到滿意 - 我不知道如何爲每個區域做到這一點。有沒有可能通過某種連接來做這樣的事情?或者我需要使用存儲過程來完成,並在plpgsql中使用循環結構?

+0

實際表定義和你的Postgres版本將有助於使這一問題清晰。 –

回答

0

你也可以遍歷您所在地區的行plpgsql中的表。但要小心,以獲得標識符和值正確的引用:

假設這個設置:

CREATE TABLE area (
    title text PRIMARY KEY 
, area_polygon geometry 
); 

CREATE TABLE points(
    point_id serial PRIMARY KEY 
, the_geom geometry); 

您可以使用此PLPGSQL塊:與%L

DO 
$do$ 
DECLARE 
    _title text; 
BEGIN 
    FOR _title IN 
     SELECT title FROM area 
    LOOP 
     EXECUTE format('COPY (SELECT p.* 
          FROM area a 
          JOIN points p ON ST_INTERSECTS(p.the_geom, a.area_polygon) 
          WHERE a.title = %L) TO %L (FORMAT csv)' 
        , _title 
        , '/path/to/' || _title || '.csv'); 
    END LOOP; 
END 
$do$; 

使用的格式(字符串l iteral)得到正確引用的字符串以避免語法錯誤並且可能的SQL注入。你仍然需要在area.title,對於文件名工作使用的字符串。)

還細心的引用文件名整體,不只是它的標題的一部分。

注意的「實用程序命令」 COPY不允許變量替換像在DML與INSERTUPDATEDELETE命令。您必須連接整個命令爲字符串

這就是爲什麼我不在循環中讀出area.area_polygon。我們必須將其轉換爲text以將其連接到查詢字符串中,其中文本表示將被轉換回geometry(或任何您的實際未公開的數據類型)。這很容易出錯。

而是我只讀area.title來唯一標識該行並在內部處理查詢中的其餘部分。

0

您可以使用PLPGSQL函數或內聯做(如果你只需要做一次,你不希望存儲的功能。)

do $body$ 
    DECLARE i int; 
    BEGIN FOR i IN SELECT DISTINCT city FROM table 
    LOOP RAISE 
     NOTICE 'foo'; 
     EXECUTE format($$COPY (SELECT * FROM foo WHERE x='%s') TO /tmp/%s$$, i, i); 
    END LOOP; 
    RETURN; 
    END; 
$body$ LANGUAGE plpgsql;