SQL server Function - 以列名作为输入参数

SQL server Function - Take column name as input parameter

我需要为 return 列特定值编写一个 SQL 函数,因此我将列名作为参数传递给 SQL 函数到 return其对应的值。这是示例函数

CREATE FUNCTION GETDATETIME(@columnName VARCHAR(100)) 
RETURNS DATETIME
AS 
BEGIN
    RETURN (SELECT TOP 1.@columnName  FROM TEST_TABLE ) 
END
GO

上面的功能看起来很简单,但并没有像预期的那样工作。 当我执行函数时

SELECT dbo.GETDATETIME('DATETIMECOLUMNNAME')

我收到这个错误:

Conversion failed when converting date and/or time from character string.

谁能帮我找出问题所在?

为此,您需要编写动态 sql。但是函数不支持执行语句。

所以需要为每一列写多个If条件。[​​=13=]

CREATE FUNCTION GETDATETIME(@columnName VARCHAR(100)) 
RETURNS DATETIME
AS 
BEGIN
   DECLARE @RESULT DATETIME;
    IF (@columnName = 'ABC')
    Begin
        SELECT TOP 1 @RESULT  = [ABC]  FROM TEST_TABLE
    END
    ELSE IF (@columnName = 'DEF')
    Begin
        SELECT TOP 1 @RESULT  = [DEF]  FROM TEST_TABLE
    END
    ELSE IF (@columnName = 'GHI')
    Begin
        SELECT TOP 1 @RESULT = [GHI]  FROM TEST_TABLE
    END

    RETURN  @RESULT
END
GO

编辑 2: 如果你的列总是 return 日期时间,那么你可以像下面那样做。

CREATE TABLE A_DUM (ID INT, STARTDATE DATETIME, ENDDATE DATETIME, MIDDLEDATE DATETIME)

INSERT INTO A_DUM 
SELECT 1, '2019-07-24 11:35:58.910', '2019-07-28 11:35:58.910', '2019-07-26 11:35:58.910'
UNION ALL
SELECT 2, '2019-07-29 11:35:58.910', '2019-08-01 11:35:58.910', '2019-07-24 11:35:58.910'

你的函数如下所示

CREATE FUNCTION GETDATETIME(@columnName VARCHAR(100)) 
RETURNS DATETIME
AS 
BEGIN

DECLARE @RESULT DATETIME;

SELECT TOP 1 @RESULT = CAST(PROP AS DATETIME)
FROM A_DUM
UNPIVOT
(
PROP FOR VAL IN (STARTDATE, ENDDATE,MIDDLEDATE)
)UP

WHERE VAL = @columnName

    RETURN @RESULT 
END
GO

不,您不能在 SQL 的函数中使用动态 sql。请查看此 link 了解更多信息 link

因此无法通过任何函数实现此目的,是的,您可以使用具有相同输出参数的存储过程。

您可能会找到此 link 以供参考 link

有一个解决方法,类似于@Shakeer 的回答 - 如果您尝试对列名进行 GROUP BY 或执行 WHERE,那么您可以只使用 CASE 语句创建一个子句以匹配特定列名字(如果你知道的话)。

显然,如果您有很多列要硬编码,这显然不会很好地工作,但至少这是实现总体思路的一种方式。

例如使用 WHERE 子句:

WHERE
(CASE 
  WHEN @columnname = 'FirstColumn' THEN FirstColumnCondition
  WHEN @columnname = 'SecondColumn' THEN SecondColumnCondition
  ELSE SomeOtherColumnCondition
  END)

或使用 GROUP BY:

GROUP BY
(CASE 
  WHEN @columnname = 'FirstColumn' THEN FirstColumnGroup
  WHEN @columnname = 'SecondColumn' THEN SecondColumnGroup
  ELSE SomeOtherColumnGroup
  END)