我正在尝试创建一个引用 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 语言中的EXECUTE:
用于执行之前准备好的语句。由于准备好的语句仅在会话期间存在,因此准备好的语句必须是由当前会话中较早执行的EXECUTE
语句创建的。PREPARE
与 PL/pgSQL 中的 EXECUTE 不同:
您常常希望在 PL/pgSQL 函数中生成动态命令,即每次执行时都会涉及不同表或不同数据类型的命令。 PL/pgSQL 缓存命令计划的正常尝试(如第 39.10.2 节中讨论的)在这种情况下将不起作用。为了处理这类问题,提供了当您想要使用 PL/pgSQL EXECUTE(将字符串作为 SQL 执行)时,您正在使用 SQL EXECUTE(它执行准备好的语句)。
EXECUTE
语句:EXECUTE command-string [ INTO [STRICT] target ] [ USING expression [, ... ] ];
试试这个:
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
参数中传递的表中。
查看OTOH,如果您尝试创建 PL/pgSQL 函数(这不是您在问题中显示的函数),那么您需要将函数转换为
PL/pgSQL 函数。
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');
DO
在匿名代码块内运行它。根据
DO
执行匿名代码块,或者换句话说,过程语言中的瞬态匿名函数。代码块被视为没有参数的函数体,返回 void。它被解析并执行一次。
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();
执行语句:
LANGUAGE plpgsql
)。
LANGUAGE SQL
),否则会出错。
EXECUTE
中使用
my_func()
语句,如下所示。 *我的帖子详细解释了如何在 PL/pgSQL 函数中使用
EXECUTE
语句:
CREATE FUNCTION my_func() RETURNS VOID
AS $$
BEGIN
EXECUTE 'UPDATE person SET age = 13 WHERE id = 2';
END;
$$ LANGUAGE plpgsql;