2016-03-18 9 views
0

У меня есть (довольно длинный) select query, который мне нужно запустить на таблицах неизвестных имен, чтобы вернуть другую таблицу. Есть ли способ сделать это, используя dynamic commands?Имя таблицы как параметр PostgreSQL - синтаксическая ошибка с использованием% I

я получаю ошибку синтаксиса на %I:

Функция:

CREATE OR REPLACE FUNCTION angles(table_name TEXT) 
    RETURNS TABLE (id int, name varchar, polygon_num int, point_order int) AS 
$BODY$ 
BEGIN 
    RETURN QUERY EXECUTE 'select id, 
     name, 
     polygon_num, 
     point_order as vertex, 
     -- 
     case when point_order = 1 
     then last_value(ST_Astext(ST_Makeline(sp,ep))) over (partition by id, polygon_num) 
     else lag(ST_Astext(ST_Makeline(sp,ep)),1) over (partition by id, polygon_num order by point_order) 
     end ||' - '||ST_Astext(ST_Makeline(sp,ep)) as lines, 
     -- 
     abs(abs(
     case when point_order = 1 
     then last_value(degrees(ST_Azimuth(sp,ep))) over (partition by id, polygon_num) 
     else lag(degrees(ST_Azimuth(sp,ep)),1) over (partition by id, polygon_num order by point_order) 
     end - degrees(ST_Azimuth(sp,ep))) -180) as ang 
from (-- 2.- extract the endpoints for every 2-point line segment for each linestring 
     --  Group polygons from multipolygon 
     select id, 
      name, 
      coalesce(path[1],0) as polygon_num, 
      generate_series(1, ST_Npoints(geom)-1) as point_order, 
      ST_Pointn(geom, generate_series(1, ST_Npoints(geom)-1)) as sp, 
      ST_Pointn(geom, generate_series(2, ST_Npoints(geom) )) as ep 
     from (-- 1.- Extract the individual linestrings and the Polygon number for later identification 
      select id, 
        name, 
        (ST_Dump(ST_Boundary(the_geom))).geom as geom, 
        (ST_Dump(ST_Boundary(the_geom))).path as path -- To identify the polygon 
       from %I) as pointlist) as segments'; 


END; 
$BODY$ 
LANGUAGE plpgsql; 

Запрос:

SELECT angles('poly_and_multipoly'); 

ответ

2

Вы пренебрегая функцию format для форматирования строки.

% Я являюсь аргументом функции format, здесь вы просто пытаетесь выполнить литеральную строку, которая имеет в ней% I.

EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname) 
    USING newvalue, keyvalue; 

Здесь вы можете увидеть colname является аргументом функции format, а newvalue и keyvalue аргументы в запросе результата SQL.

Итак, заверните свою строку в функцию format с правильными аргументами, и вам должно быть хорошо идти.

+0

Спасибо! гектометр Глядя на [http://www.postgresql.org/docs/current/static/functions-string.html#FUNCTIONS-STRING-FORMAT], я не уверен, что мне не хватает. Я добавил: 'из формата ('% I ', table_name) и получил ** ОШИБКУ: тип «I» не существует ** – user14696

+0

Вам нужно обернуть весь оператор, а не только его часть. EXECUTE работает только с простой строкой. Функция формата выполняет фактическую подстановку, приводящую к простой строке, которая затем может быть использована EXECUTE. Обратите внимание, что в моем примере у меня есть весь оператор, передаваемый в формат. –

+0

Формат() кажется красивым ... но разочарование догнало меня. Я закончил тем, что передал регулярную конкатенированную строку ** из '|| $ 1 || ') как pointlist) ** ... но я буду продолжать работать с ним. Благодаря! – user14696