将转换类型参数传递给具有执行格式的过程

Pass cast type arguments to procedure with execute format

我需要在地理空间数据上创建多个视图,每个视图都显式转换为正确的几何形状,我想创建一个辅助程序来执行此操作:

CREATE PROCEDURE create_view_events(
  view_name TEXT, event_type TEXT, geo_type TEXT
) LANGUAGE plpgsql AS $$
BEGIN
  EXECUTE FORMAT('
     CREATE VIEW %I AS
     SELECT
       id,
       geom::%I AS geom   -- casting required, but how?
     FROM events
     WHERE type = %L
  ', view_name, geo_type, event_type);
END $$;
CALL create_view_events('events_viewX', 'X', GEOMETRY(POINT, 3347));

手动 运行 将转换替换为 geom::GEOMETRY(POINT, 3347) AS geomCREATE VIEW 语句有效 & 运行 没有转换的过程也有效。但是,按原样调用该过程会产生此错误,我不知道发生了什么。

ERROR: missing FROM-clause entry for table "GEOMETRY(POINT, 3347)"
  Where: PL/pgSQL function create_view_events(text,text,text) line 7 at EXECUTE

您很可能错过了 format() 的正确标记。使用 %s 而不是 %I:

CREATE PROCEDURE create_view_events(
  view_name TEXT, event_type TEXT, geo_type TEXT) 
LANGUAGE plpgsql AS $$
BEGIN
  EXECUTE FORMAT('
     CREATE VIEW %I AS
     SELECT
       id,
       geom::%s AS geom   
     FROM events
     WHERE type = %L
  ', view_name, geo_type, event_type);
END $$;

CALL create_view_events('events_viewX', 'X', 'GEOMETRY(POINT, 3347)');

但是,如果 geom 的基础 SRS 与函数参数中提供的不同,则此查询很可能会失败。如果它们确实不同,请考虑使用 ST_Transform,否则只需使用 ST_SetSRID

演示:db<>fiddle

CREATE OR REPLACE PROCEDURE create_view_events(
  view_name TEXT, event_type TEXT, geo_type TEXT) 
LANGUAGE plpgsql AS $$
BEGIN
  EXECUTE FORMAT('
     CREATE OR REPLACE VIEW %I AS
     SELECT
       id,
       ST_SetSRID(geom,%s) AS geom  
     FROM events
     WHERE type = %L
  ', view_name, geo_type, event_type);
END $$;

CALL create_view_events('events_viewX', 'X', '3347');