2016-06-30 20 views
2

親テーブルlayer_1_といくつかのジオメトリデータを含む子テーブルlayer_1_pointslayer_1_linestringsなどがあります。各子テーブルには独自のジオメトリ制約があります。したがって、たとえば、layer_1_pointsは、この制約があります。エラー:テーブル "new"のFROM句のエントリがありません

CONSTRAINT enforce_geotype_geom_geom CHECK (geometrytype(geom) = 'POINT'::text) 

layer_1_linestringsの表は、この制約を持っているのに対し:layer_2_layer_3_、...、layer_N_

CONSTRAINT enforce_geotype_geom_geom CHECK (geometrytype(geom) = 'LINESTRING'::text) 

他の多くの層のテーブルには、似た名前を持ちます。そしてそれらのすべてには独自の子テーブルがあります。私が達成したいのは、ユーザーが親テーブル(layer_N_)に挿入すると、このinsertステートメントを特定の子テーブル(layer_N_pointsなど)に転送する必要があるということです。私が行うときに、例えば、:

INSERT INTO layer_1_ (geom) VALUES(ST_GeomFromText('POINT(0 0)', 3857)) 

geomタイプがPOINTあるので、私は実際に、layer_1_pointsに挿入する必要があります。このすべてをachiveするために、私はこのトリガ機能とトリガ自体作成:、しかし

CREATE OR REPLACE FUNCTION trigger_layer_insert() 
    RETURNS trigger AS 
$$ 
DECLARE 
    var_geomtype text; 
    table_name text; 
    layer_id text := (TG_ARGV[0])::text; 
BEGIN 
    var_geomtype := geometrytype(NEW.geom);  
    IF var_geomtype = 'POINT' THEN 
     table_name := (SELECT concat ('layer_', layer_id, '_points')); 
    ELSIF var_geomtype = 'MULTIPOINT' THEN 
     table_name := (SELECT concat ('layer_', layer_id, '_multipoints'));  
    ELSIF var_geomtype = 'LINESTRING' THEN 
     table_name := (SELECT concat ('layer_', layer_id, '_linestrings')); 
    ELSIF var_geomtype = 'MULTILINESTRING' THEN 
     table_name := (SELECT concat ('layer_', layer_id, '_multilinestrings')); 
    ELSIF var_geomtype = 'POLYGON' THEN 
     table_name := (SELECT concat ('layer_', layer_id, '_polygons')); 
    ELSIF var_geomtype = 'MULTIPOLYGON' THEN 
     table_name := (SELECT concat ('layer_', layer_id, '_multipolygons')); 
    END IF; 

    EXECUTE ' 
     INSERT INTO ' || table_name || ' 
     SELECT * FROM (SELECT NEW.*) AS t 
    '; 

    RETURN NULL; 
END; 
$$ 
LANGUAGE 'plpgsql' VOLATILE; 

CREATE TRIGGER trigger_layer_1_ BEFORE INSERT 
ON layer_1_ FOR EACH ROW 
EXECUTE PROCEDURE trigger_layer_insert(1); 

を私が行うときのように、実際の挿入:

ERROR: missing FROM-clause entry for table "new" 
LINE 3:   SELECT * FROM (SELECT NEW.*) AS t 
           ^
QUERY: 
    INSERT INTO layer_1_points 
    SELECT * FROM (SELECT NEW.*) AS t 

:私は、エラーメッセージが表示されます

INSERT INTO layer_1_ (geom) VALUES(ST_GeomFromText('POINT(0 0)', 3857)) 

だから、SELECT NEW.*の何が問題なのですか?どうすれば修正できますか?ありがとう!

EDIT

は私もこの試みた:

EXECUTE ' 
    INSERT INTO ' || table_name || ' 
    SELECT * FROM (SELECT NEW.*) AS t 
' USING NEW; 

をしかし、それは効果がありません。

+0

は '文字列の' $ 1 'によってNEW'置き換え: 'EXECUTE 'INSERT INTOを' | | table_name || 'SELECT * FROM SELECT $ 1。*)AST NEW USING';をパラメーターとみなします。 – Abelisto

+0

うん、それは動作します!あなたはあなたのコメントから完全な答えを出すかもしれません。ありがとう! – Jacobian

答えて

4

PLPGSQL文EXECUTEを使用して何かを実行すると、別のコンテキストで実行されるため、ローカル変数がそこに表示されません。変数(複数可)を渡すにはEXECUTE '<SQL script>' USING <variables list>;形式が使用されます。

EXECUTE 'insert into table(field1, field2) values ($1, $2)' USING var1, var2; 

だから、文は次のようになります。

EXECUTE 
    'INSERT INTO ' || table_name || ' SELECT * FROM SELECT $1.*) AS t' 
    USING NEW; 
関連する問題