Синтаксическая ошибка PostgreSQL при использовании EXECUTE в Function - PullRequest
5 голосов
/ 28 июля 2011

Я пытаюсь создать функцию, которая ссылается на временную таблицу в PostgreSQL 8.4.Исходя из моих исследований, мне кажется, что лучший способ сделать это - использовать команду EXECUTE для выполнения моего запроса из определенной строки.

К сожалению, при попытке создать функцию я получаю странную синтаксическую ошибку.

Мое текущее определение функции выглядит следующим образом:

CREATE OR REPLACE FUNCTION example() RETURNS void AS $$
  EXECUTE 'INSERT INTO table1 (col1, col2, col3) SELECT col1, col2, col3 from temp_table';
$$ LANGUAGE SQL;

Я получаю ошибку:

ERROR:  syntax error at or near "'INSERT INTO table1 (col1, col2, col3) SELECT col1, col2, col3 from temp_table'"
LINE 2:   execute 'INSERT INTO table1 (col1, col2, col3) SELECT col1...

Кажется, я получаю одну и ту же ошибку независимо от того, чтона самом деле находится в строковом литерале.

Мои вопросы: 1) каков правильный синтаксис для использования функции EXECUTE, и 2) есть ли лучший способ написать такую ​​функцию, которая ссылается на временную таблицу?

Ответы [ 3 ]

11 голосов
/ 28 июля 2011

Я думаю, что ваша проблема в языке, который вы используете. EXECUTE на языке SQL:

EXECUTE используется для выполнения ранее подготовленного оператора.Поскольку подготовленные операторы существуют только на время сеанса, подготовленный оператор должен быть создан оператором PREPARE, выполненным ранее в текущем сеансе.

не совпадает с EXECUTE в PL / pgSQL :

Часто вы захотите генерировать динамические команды внутри ваших функций PL / pgSQL, то есть команды, которые будут включать разные таблицы или разные типы данных каждый раз, когда ониказнены.Обычные попытки PL / pgSQL кешировать планы для команд (как обсуждено в Разделе 39.10.2) не будут работать в таких сценариях.Для решения такого рода проблем предоставляется оператор EXECUTE:

EXECUTE command-string [ INTO [STRICT] target ] [ USING expression [, ... ] ];

Вы используете SQL EXECUTE (который выполняет подготовленный оператор), когда вы хотите использовать PL /pgSQL EXECUTE (который выполняет строку как SQL).

Попробуйте это:

CREATE OR REPLACE FUNCTION example() RETURNS void AS $$
BEGIN
    EXECUTE 'INSERT INTO table1 (col1, col2, col3) SELECT col1, col2, col3 from temp_table';
END;
$$ LANGUAGE PLPGSQL;

Или другой пример, который кажется более близким к тому, что вы пытаетесь сделать:

create or replace function example(tname text) returns void as $$
begin
    execute 'insert into ' || tname || ' (name) values(''pancakes'')';
end;
$$ language plpgsql;

Это вставит 'pancakes' в таблицу, которую вы передаете в аргумент tname функции.

0 голосов
/ 19 февраля 2017

Это пример, проверенный мной, где я использую EXECUTE для запуска выбора и помещаю результат в курсор.

1. Создайте таблицу:

create table people (
  nickname varchar(9),
  name varchar(12),
  second_name varchar(12),
  country varchar(30)
  );

2. Создайте функцию:

CREATE OR REPLACE FUNCTION fun_find_people (col_name text, col_value varchar)
RETURNS void AS
$BODY$
DECLARE
    local_cursor_p refcursor;
    row_from_people RECORD;

BEGIN
    open local_cursor_p FOR
        EXECUTE 'select * from people where '|| col_name || ' LIKE ''' || col_value || '%'' ';

    raise notice 'col_name: %',col_name;
    raise notice 'col_value: %',col_value;

    LOOP
        FETCH local_cursor_p INTO row_from_people; EXIT WHEN NOT FOUND;

        raise notice 'row_from_people.nickname: %',  row_from_people.nickname ;
        raise notice 'row_from_people.name: %', row_from_people.name ;
        raise notice 'row_from_people.country: %', row_from_people.country;
    END LOOP;
END;
$BODY$ LANGUAGE 'plpgsql'

3. Запустите функцию select fun_find_people('name', 'Cristian'); select fun_find_people('country', 'Chile');

0 голосов
/ 28 июля 2011

EXECUTE используется для выполнения подготовленных операторов и ожидает только подготовленное имя оператора в качестве аргумента.

Если вы пытаетесь выполнить оператор SQL (как в вашем примере), простовключите его в тело функции.

Проверьте руководство для получения дополнительной информации о «функциях языка запросов (SQL)».

OTOH, если вы пытаетесь создатьфункция PL / pgSQL (это не то, что вы показали в своем вопросе), тогда вам нужно преобразовать свою функцию в PL / pgSQL функцию .

...