我想要做这样的事情:
SELECT (EVAL 'SELECT 1') + 1;
在 PostgreSQL 中有没有类似于这样的方法(EVAL
)?
我想要做这样的事情:
SELECT (EVAL 'SELECT 1') + 1;
在 PostgreSQL 中有没有类似于这样的方法(EVAL
)?
create or replace function eval(expression text) returns integer
as
$body$
declare
result integer;
begin
execute expression into result;
return result;
end;
$body$
language plpgsql
那么你可以做类似这样的事情:
SELECT eval('select 41') + 1;
但是,如果您的动态语句对于要评估的每个表达式返回不同的内容,则此方法将无效。
还要注意,通过运行任意语句,这会带来巨大的安全风险。这是否是问题取决于您的环境。如果仅在交互式SQL会话中使用,则不是问题。
如果需要,我会选择使用数据类型文本,因为它使用强制转换运算符比如::int
更加灵活。
create or replace function eval( sql text ) returns text as $$
declare
as_txt text;
begin
if sql is null then return null ; end if ;
execute sql into as_txt ;
return as_txt ;
end;
$$ language plpgsql
-- select eval('select 1')::int*2 -- => 2
-- select eval($$ select 'a'||1||'b' $$) -- => a1b
-- select eval( null ) -- => null
我还添加了这个和另一个eval( sql, keys_arr, vals_arr )
函数,支持一些自定义的键-值替换,例如方便的:param1
替换到postgres-utils
PLpgSQL语言有许多表达方式:
Y := f(X);
EXECUTE
子句仅用于"动态执行"(性能较差)。 EXECUTE 'f(X)' INTO Y;
Y := f(X);
或SELECT
执行静态声明。 SELECT f(X) INTO Y;
当需要丢弃结果或处理空返回值时,请使用PERFORM语句:
PERFORM f(X);
create or replace function eval(expression text) returns integer
as
$body$
declare
result integer;
begin
execute 'SELECT ' || expression into result;
return result;
end;
$body$
language plpgsql;
只需键入以下内容即可运行:
SELECT eval('2*2');
select * from eval('select 1, ''hello''')
... 目前这个实现只返回结果集中的第一列,即1
。 - skilbjoeval2(...)
变体。 - Andreas Covidiot