postgresql – 错误:缺少表“new”的FROM子句条目

我有一个父表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>‘使用<变量列表&gt ;;使用表格:

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;

相关文章

文章浏览阅读601次。Oracle的数据导入导出是一项基本的技能,...
文章浏览阅读553次。开头还是介绍一下群,如果感兴趣polardb...
文章浏览阅读3.5k次,点赞3次,收藏7次。折腾了两个小时多才...
文章浏览阅读2.7k次。JSON 代表 JavaScript Object Notation...
文章浏览阅读2.9k次,点赞2次,收藏6次。navicat 连接postgr...
文章浏览阅读1.4k次。postgre进阶sql,包含分组排序、JSON解...