按select返回的名称调用sql函数
我想了解如何调用从select查询返回其名称的函数。比如说,我有一个select查询:按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 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);