Проблемы с пространственной репликацией данных Spatial Data

Здравствуйте, я просто изучаю 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.

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

    Вы не можете писать динамический 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, чтобы избежать кастинга и процитировать безумие.