2015-03-09 4 views
1
BEGIN 
    _table_name := 'mytable'; 

    CREATE TEMPORARY TABLE _table_name (
    id integer NOT NULL, 
    name character varying, 
    active boolean 
    ) ON COMMIT DROP'; 

-- logic here 

RETURN QUERY SELECT table1.id, table1.name FROM _table_name AS table1; 
END; 

Я упростил свою проблему. Я пытаюсь использовать переменную в качестве имени таблицы.Как использовать переменную как имя таблицы?

Я знаю, что вы можете делать такие вещи, как SELECT * FROM table1 WHERE id = _id, где _id является объявленной varaible.

Я знаю, что могу это сделать EXECUTE, но тогда у меня есть запрос вроде: INSERT INTO table2 (id) SELECT id FROM unnest(_ids) as id где _ids - это массив.

В любом случае, чтобы решить проблему 1 с использованием переменной в качестве имени таблицы? и проблема 2, используя unnest внутри EXECUTE?

Таким образом, проблема заключается в том, что запросы принимают _table_name как имя таблицы литералов, но не похоже, что вместо этого используется «mytable» в качестве имени таблицы.

+0

http://www.postgresql.org/docs/current/static/plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN –

+0

@a_horse_with_no_name я уже прочитал, что. Мой аргумент заключался в том, что, как вы можете использовать переменные в литералах, как в примере с '_id' против примера create table. – user962449

ответ

2

Если вы динамически меняете имя таблицы (т. Е. Через переменную), то вам нужно будет использовать EXECUTE. Вы можете использовать это с массивами и отключать, пока вы бросаете массивы в/из представления TEXT.

DECLARE 
    _ids INT[] = ARRAY[ 1, 2, 3, 4, 5 ]; 
    _table_name TEXT = 'mytable'; 
BEGIN 
    EXECUTE 
    'INSERT INTO ' || QUOTE_IDENT(_table_name) || ' (id) 
    SELECT id 
    FROM unnest(' || QUOTE_LITERAL(_ids::TEXT) || '::INT[]) AS id'; 
END; 
1

Вы сказали около dynamic SQL with EXECUTE in plpgsql. Вы динамически строят строку запроса, включая неизменный код и идентификаторы.

Но сделать не конкатенации значения. Используйте пункт в USING вместо:

DECLARE 
    _ids INT[] = ARRAY[ 1, 2, 3, 4, 5 ]; 
    _table_name TEXT = 'mytable'; 
BEGIN 
    EXECUTE 
    'INSERT INTO ' || quote_ident(_table_name) || ' (id) 
    SELECT * FROM unnest($1)' 
    USING ids; 
END; 

Избегает подвержены ошибкам литья назад и вперед.