Подтвердить что ты не робот

Есть ли способ выполнить запрос внутри значения строки (например, eval) в PostgreSQL?

Я хочу сделать вот так:

SELECT (EVAL 'SELECT 1') + 1;

Есть ли способ сделать это (EVAL) в PostgreSQL?

4b9b3361

Ответ 1

Если утверждения, которые вы пытаетесь "eval", всегда возвращают один и тот же тип данных, вы можете написать функцию eval(), которая использует EXECUTE, упомянутую Grzegorz.

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, это не проблема.

Ответ 2

ПРИМЕЧАНИЯ

Синтаксис языка PLpgSQL имеет много способов сказать:

 Y := f(X);

Предложение EXECUTE предназначено только для "динамического исполнения" (меньше производительности),

 EXECUTE 'f(X)' INTO Y;     

Используйте Y := f(X); или SELECT для выполнения статических объявлений,

 SELECT f(X) INTO Y;

Используйте PERFORM statment при отбрасывании результатов или работе с возвратами void:

 PERFORM f(X);     

Ответ 3

Я бы пошел с текстом типа данных, так как он более гибкий, используя при этом следующие операторы литья, такие как ::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

Ответ 4

Я не уверен, подходит ли он вам, но PostgreSQL имеет EXECUTE.

Ответ 5

Хорошая идея. Вы можете изменить для выполнения прямых выражений:

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');