我有一个父表layer_1_和一些子表layer_1_points,layer_1_linestrings等,其中包含一些几何数据.每个子表都有自己的几何约束.因此,例如,layer_1_points具有以下约束:
CONSTRAINT enforce_geotype_geom_geom CHECK (geometrytype(geom) = 'POINT'::text)
而layer_1_linestrings表具有以下约束:
CONSTRAINT enforce_geotype_geom_geom CHECK (geometrytype(geom) = 'LINESTRING'::text)
许多其他图层表具有相似的名称:layer_2_,layer_3_,…,layer_N_.他们都有自己的子桌.我想要实现的是当用户插入父表(layer_N_)时,应该将此insert语句转发到特定的子表(layer_N_points等).所以,当我这样做时:
INSERT INTO layer_1_ (geom) VALUES(ST_GeomFromText('POINT(0 0)',3857))
我应该插入到layer_1_points,因为geom类型是POINT.为了实现这一切,我创建了这个触发器功能和触发器本身:
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_','_multipoints')); ELSIF var_geomtype = 'LINESTRING' THEN table_name := (SELECT concat ('layer_','_linestrings')); ELSIF var_geomtype = 'MULTILINESTRING' THEN table_name := (SELECT concat ('layer_','_multilinestrings')); ELSIF var_geomtype = 'POLYGON' THEN table_name := (SELECT concat ('layer_','_polygons')); ELSIF var_geomtype = 'MULTIPOLYGON' THEN table_name := (SELECT concat ('layer_','_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);
但是,当我做实际插入时:
INSERT INTO layer_1_ (geom) VALUES(ST_GeomFromText('POINT(0 0)',3857))
我收到一条错误消息:
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
那么,SELECT NEW.*有什么问题?我该如何解决?谢谢!
编辑
我也试过这个:
EXECUTE ' INSERT INTO ' || table_name || ' SELECT * FROM (SELECT NEW.*) AS t ' USING NEW;
但它没有效果.
解决方法
当您使用PLPGSQL语句EXECUTE执行某些操作时,它会在不同的上下文中运行,因此局部变量在那里不可见.传递变量’EXECUTE’< SQL script>‘使用<变量列表> ;;使用表格:
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;