Проблемы с функцией перепроектирования SQL пространственных данных - PullRequest
0 голосов
/ 08 ноября 2011

Здравствуйте. Я только изучаю postGIS и, следовательно, postgresql (9.1) и пытаюсь сэкономить время, копируя один и тот же код снова и снова, создав функцию sql для перепроектирования некоторых пространственных данных.

Create Function reproject_shapefile(text,text,numeric) returns void as $$

    -- Reprojects shapefiles given that they follow the pattern "gid * the_geom"

    CREATE TABLE $2 AS
        SELECT *, ST_Transform(the_geom,$3) AS the_geom2
        FROM $1;
    Alter table $2 add Primary Key (gid);
    Alter table $2 drop column the_geom;
    Alter table $2 rename column the_geom2 to the_geom;
$$ Language SQL;

Я перечитал документы, в которых указано, как это сделать, но каждый раз, когда я пытаюсь создать функцию из редактора sql в pgAdmin, я получаю следующую ошибку:

ERROR:  syntax error at or near "$2"
LINE 5:     CREATE TABLE $2 AS
                     ^

********** Error **********

ERROR: syntax error at or near "$2"
SQL state: 42601
Character: 175

В отличие от сообщений об ошибках в python, это абсолютно ничего не говорит мне о пользе, поэтому я надеюсь, что кто-то может указать мне правильное направление, как исправить эту ошибку.

Если есть какой-то способ выполнить ту же функцию с использованием python, не стесняйтесь публиковать его как решение вместо этого, а также, поскольку синтаксис python для меня гораздо проще понять, чем древний SQL.

Любая помощь будет принята с благодарностью!

1 Ответ

4 голосов
/ 08 ноября 2011

Вы не можете писать динамический SQL в этой форме.Параметры могут передавать только значения , а не идентификаторы .Нечто подобное невозможно в функции SQL:

CREATE TABLE $2 AS

Для этого нужно написать функцию plpgsql и использовать EXECUTE.Может выглядеть так:

CREATE OR REPLACE FUNCTION reproject_shapefile(text, text, numeric)
  RETURNS void as $$
BEGIN

EXECUTE '
   CREATE TABLE ' || quote_ident($2) || ' AS
   SELECT *, ST_Transform(the_geom,$1) AS the_geom2
   FROM  ' || quote_ident($1)
USING $3;

EXECUTE 'ALTER TABLE ' || quote_ident($2) || ' ADD PRIMARY KEY (gid)';
EXECUTE 'ALTER TABLE ' || quote_ident($2) || ' DROP COLUMN the_geom';
EXECUTE 'ALTER TABLE ' || quote_ident($2) || ' RENAME column the_geom2 TO the_geom';

END;
$$ Language plpgsql;

Основные точки

  • plpgsql функция, а не sql
  • EXECUTE любаязапрос с динамическими идентификаторами
  • использовать quote_ident для защиты от SQLi
  • передать значения с предложением USING, чтобы избежать приведения и цитирования безумия.
...