按select返回的名称调用sql函数

按select返回的名称调用sql函数,sql,sql-server,sql-server-2008,postgresql,tsql,Sql,Sql Server,Sql Server 2008,Postgresql,Tsql,我想了解如何调用从select查询返回其名称的函数。比如说,我有一个select查询: SELECT function_name FROM functions WHERE id=1; 现在让我们假设,返回的函数名是fce1 现在我想执行: SELECT fce1(parameters); 我最初的想法是: SELECT CONCAT(SELECT function_name FROM functions WHERE id=1;, "(params)"); 我很肯定这个想法是错误的。但不久前

我想了解如何调用从select查询返回其名称的函数。比如说,我有一个select查询:

SELECT function_name FROM functions WHERE id=1;
现在让我们假设,返回的函数名是fce1 现在我想执行:

SELECT fce1(parameters);
我最初的想法是:

SELECT CONCAT(SELECT function_name FROM functions WHERE id=1;, "(params)");

我很肯定这个想法是错误的。但不久前我还试图弄明白这一点,我记得至少MS SQL能够实现我的目标,还有POSTGRESQL。不管怎样,我也记不起来,也找不到怎么做。如果所有函数都返回相同的数据类型,您可以在Postgres中构建一个包装函数,传递要调用的函数的ID:

DECLARE @func NVARCHAR(50);

SELECT @func = function_name FROM functions WHERE id=1;

EXEC ('select ' + @func + '()')
create or replace function call_func(p_id integer)
  returns integer
as
$$
declare 
  l_result integer;
  l_name   text;
  l_params text;
begin 
  select function_name, parameters
    into l_name, l_params
  from functions
  where id = p_id;

  execute 'select '||l_name||'('||l_params||')'
    into l_result;

  return l_result;    
end;
$$
language plpgsql;
注意:以上只是一个示例

它对SQL注入非常开放,并且不进行任何错误检查或清理参数!但它可能会为你指明正确的方向

假设您具有以下功能:

create or replace function foo(p_arg_1 integer, p_arg_2 integer)
  returns integer
as
$$
  select p_arg_1 + p_arg_2;
$$
language sql;

create or replace function bar(p_value integer)
  returns integer
as
$$
  select p_value * 4;
$$
language sql;
函数
表如下所示:

id | function_name | parameters
---+---------------+-----------
 1 | fce           | 42        
 2 | foo           | 1,2       
然后你就可以做了

select call_func(2);


但同样:只有当所有函数返回相同的结果时,这才有效。e、 g.返回单个值的标量函数,或返回相同表定义的集合返回函数。

(1)对此需要使用动态SQL(或巨型
case
语句)。(2)您使用的是SQL Server还是Postgres?请适当地标记问题。我正在决定使用哪个。我更喜欢Postgres,但决定是基于所需的功能。CASE实际上不是一个选项(我们谈论的是数千种可能的功能)。我想只有在除dev/DBA之外的任何人都可以访问functions表(或调用它的参数)的情况下,才可以进行SQL注入,否则应该是这样ok@Charleh:SQL注入从来都不正常,即使对于开发人员或DBA也是如此。请使用quote_ident()为了避免这个错误。@FrankHeikens:即使使用
quote_ident()
引用函数名,它仍然会将参数作为潜在的“威胁”保留下来-我不知道如何正确地转义/引用它们来防止这种情况发生-但这是否是一个问题取决于使用它的环境。有时这种动态SQL并不是一个真正的问题。@FrankHeikens我想说,如果你已经考虑了所有问题,并且你对数据的来源没有意见,那么就没关系了……再加上你自己甚至可以使用它来注入有用的代码:)
select call_func(1);