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)
我需要为 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)