在SQL中调用动态函数名称

时间:2012-05-11 19:10:22

标签: sql sql-server tsql sql-function

是否可以在SQL中调用具有动态名称的函数?

例如:

SELECT functionid, (SELECT results FROM dbo.Function_*functionid*) AS results
FROM List_of_Functions

这将为表List_of_Functions中的每一行调用不同的函数。

或者我这样做错了吗?

3 个答案:

答案 0 :(得分:3)

您需要构建(根据您的表格输入或动态构建)一个SQL语句,如:

SELECT
    functionid
        ,CASE  functionid
            WHEN 1 THEN dbo.Function_1()
            WHEN 2 THEN dbo.Function_2()
            WHEN 3 THEN dbo.Function_3()
         END AS results
    FROM List_of_Functions

不是构建所有这些函数,而是构建一个函数并传入函数可用于区分处理的值不是更好吗?像:

SELECT
    functionid
        ,dbo.Function(functionid) AS results
    FROM List_of_Functions_Parameters

答案 1 :(得分:2)

  

是否可以在SQL中调用具有动态名称的函数?

不在纯SQL中。

您可以使用动态SQL实现此目的,但不能没有风险,特别是SQL Injection的风险。

我建议阅读Erland Sommarskog的The Curse and Blessings of Dynamic SQL来全面处理这个问题。

答案 2 :(得分:0)

只想扩展并反对Oded's answer

  
    

是否可以在SQL中调用具有动态名称的函数?

  
     

不在纯SQL中。

     

您可以使用动态SQL实现此目的,但不是没有风险,特别是SQL注入风险。

是的,可以不使用动态SQL。

准备:

CREATE TABLE List_of_Functions(functionid INT);
INSERT INTO List_of_functions(functionid) VALUES(1),(2),(3),(4);

CREATE FUNCTION Function_1()
RETURNS VARCHAR(100)
AS
BEGIN
   RETURN 'Return from Function_1';
END;

CREATE FUNCTION Function_2()
RETURNS VARCHAR(100)
AS
BEGIN
   RETURN 'Return from Function_2';
END;

CREATE FUNCTION Function_3()
RETURNS VARCHAR(100)
AS
BEGIN
   RETURN 'Return from Function_3';
END;

核心功能:

CREATE FUNCTION Function_dispatcher(@name SYSNAME)
RETURNS VARCHAR(100)
AS
BEGIN
  DECLARE @r VARCHAR(100);
  IF OBJECT_ID(@name, N'FN') IS NULL  --handling non-existing function
    RETURN NULL;
  EXEC @r = @name; 
  RETURN @r;
END;

最后的电话:

SELECT *, dbo.Function_dispatcher(s.n) AS result
FROM List_of_Functions lf
OUTER APPLY(SELECT CONCAT('dbo.Function_', lf.functionid)) s(n);

<强> DBFiddle Demo

输出:

┌────────────┬────────────────┬────────────────────────┐
│ functionid │       n        │         result         │
├────────────┼────────────────┼────────────────────────┤
│          1 │ dbo.Function_1 │ Return from Function_1 │
│          2 │ dbo.Function_2 │ Return from Function_2 │
│          3 │ dbo.Function_3 │ Return from Function_3 │
│          4 │ dbo.Function_4 │ null                   │
└────────────┴────────────────┴────────────────────────┘

使用这种方法,您可以避免在每次出现新功能时更改主要功能(例如,时间......),如KM.'s answer