Function 使用EXECUTE in函数时出现PostgreSQL语法错误

Function 使用EXECUTE in函数时出现PostgreSQL语法错误,function,postgresql,syntax-error,execute,temp-tables,Function,Postgresql,Syntax Error,Execute,Temp Tables,我正在尝试创建一个函数,该函数引用PostgreSQL 8.4中的一个临时表。根据我的研究,最好的方法似乎是使用EXECUTE命令从定义的字符串执行查询 不幸的是,我在尝试创建函数时遇到了一个奇怪的语法错误 我当前的函数定义如下: CREATE OR REPLACE FUNCTION example() RETURNS void AS $$ EXECUTE 'INSERT INTO table1 (col1, col2, col3) SELECT col1, col2, col3 from

我正在尝试创建一个函数,该函数引用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)有没有更好的方法来编写这样一个引用临时表的函数?

用于执行准备好的语句,并且只需要准备好的语句名作为参数

如果您试图执行SQL语句(如示例中所示),只需将其包含在函数体中即可

有关“查询语言(SQL)函数”的更多信息,请查看


如果您试图创建PL/pgSQL函数(这不是您在问题中所展示的),那么您需要将函数转换为。我认为您的问题在于您使用的语言。在SQL语言中:

EXECUTE
用于执行先前准备的语句。由于准备好的语句仅在会话期间存在,因此准备好的语句必须是由当前会话中较早执行的
PREPARE
语句创建的

不等于:

通常,您会希望在PL/pgSQL函数中生成动态命令,即每次执行时涉及不同表或不同数据类型的命令。PL/pgSQL缓存命令计划的正常尝试(如第39.10.2节所述)在此类场景中不起作用。为了处理这类问题,提供了
EXECUTE
语句:

EXECUTE command-string [ INTO [STRICT] target ] [ USING expression [, ... ] ];
当您想要使用PL/pgSQL EXECUTE(以SQL形式执行字符串)时,您正在使用SQL EXECUTE(它执行一条准备好的语句)

试试这个:

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
参数传递给函数。

这是我测试过的一个示例,我使用EXECUTE运行select并将其结果放入光标中

1。创建表格:

create table people (
  nickname varchar(9),
  name varchar(12),
  second_name varchar(12),
  country varchar(30)
  );
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'
2。创建函数:

create table people (
  nickname varchar(9),
  name varchar(12),
  second_name varchar(12),
  country varchar(30)
  );
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。运行该功能

选择fun_find_people('name','Cristian');
选择有趣的人(“国家”、“智利”);

或者,您可以使用
DO
在匿名代码块中运行它
根据(矿山)的重点:

DO
执行匿名代码块,或者换句话说,执行过程语言中的临时匿名函数

代码块被视为没有参数的函数体,返回void。它被解析并执行一次


这允许您运行通常无法运行的构造SQL,而无需构建函数来调用它:

DO $$
BEGIN
    execute 'ALTER DATABASE ' || current_database() || ' SET timezone TO ''UTC''';
    execute 'SET timezone TO ''UTC''';
END;
$$
而不是:

CREATE OR REPLACE FUNCTION fix_database_timezone()
RETURNS void AS
$BODY$
BEGIN
    execute 'ALTER DATABASE ' || current_database() || ' SET timezone TO ''UTC''';
    execute 'SET timezone TO ''UTC''';
END;
$BODY$ LANGUAGE 'plpgsql';

fix_database_timezone();

我不能只将查询包含在函数体中,因为它引用的临时表在创建函数时不存在。这是使用PL/pgSQL函数的唯一方法吗?