我知道T-SQL不是面向对象的。我需要编写一组模拟C#中方法重载的函数。
T-SQL中是否支持函数重载?如果有黑客这样做,是推荐吗?
答案 0 :(得分:11)
不,没有办法做到这一点。
我建议你重新审视这个要求,因为“让苹果看起来像橙子”通常很难做到,而且值得怀疑。
答案 1 :(得分:6)
我成功完成的一件事是以允许它处理空值的方式编写函数,然后使用空值来代替您想要省略的参数来调用它。
示例:
create function ActiveUsers
(
@departmentId int,
@programId int
)
returns int
as
begin
declare @count int
select @count = count(*)
from users
where
departmentId = isnull(@departmentId, departmentId)
and programId = isnull(@programId, programId)
return @count
end
go
用途:
select ActiveUsers(1,3) -- users in department 1 and program 3
select ActiveUsers(null,3) -- all users in program 3, regardless of department
select ActiveUsers(null,null) -- all users
答案 2 :(得分:5)
你可以通过一个sql_variant,但它附带了各种各样的危险;你不能像使用OO语言和重载一样使用强类型。
如果您需要在函数中找到基本类型,可以使用SQL_VARIANT_PROPERTY
函数。
答案 3 :(得分:1)
您可以在一个字符串中传入一组值,并将它们解析出来using this techique by Erland Sommarskog。
如果需要,创建一个带有varchar(max)
参数或多个参数的函数,然后将该参数值包含在该字符串中:
param1;param2;parma3;param4
或
param1:type;param2:type;param3:type
或
calltype|param1;param2;param3
等等,你只受想象力的限制......
使用链接中的技术拆分此数组,并使用程序逻辑根据需要使用这些值。
答案 4 :(得分:0)
一种解决方案是使用sql_variant
数据类型。只要对两个值使用相同的数据类型,此示例就有效。返回发送它的任何数据类型。
create function dbo.Greater(
@val1 sql_variant
,@val2 sql_variant
) returns sql_variant
as
begin
declare @rV sql_variant
set @rV = case when @val1 >= @val2 then @val1
else @val2 end
return @rV
end
go
答案 5 :(得分:0)
我已经一些幸运的解决方案是创建一些函数,每个函数采用不同的数据类型 - 或者将所有输入转换为NVARCHAR(MAX)。
<强> 1。创建许多函数,每个函数采用不同的数据类型
CREATE FUNCTION [dbo].[FunctionNameDatetime2]
CREATE FUNCTION [dbo].[FunctionNameInt]
CREATE FUNCTION [dbo].[FunctionNameString] --(this is not a typo)
CREATE FUNCTION [dbo].[FunctionNameUniqueidentifier]
...
问题: 代码重复,功能很多
<强> 2。将所有输入转换为NVARCHAR(MAX)
CREATE FUNCTION [dbo].[IntToNvarchar]
(
@Key INT
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
RETURN ISNULL(CAST(@Key AS NVARCHAR), '');
END
CREATE FUNCTION [dbo].[FunctionName]
(
@Key NVARCHAR(MAX)
)
RETURNS CHAR(32)
AS
BEGIN
DECLARE @something CHAR(32)
do stuff ...
RETURN @something;
END
SELECT [dbo].[FunctionName]([dbo].[IntToNvarchar](25))
问题: 代码不如重载
答案 6 :(得分:-4)
我一直在重载函数,但我碰巧知道这些问题通常高度依赖于平台。
在我们的DB2系统上,我经常按以下方式重载:
CREATE Function Schema1.F1(parm date) 返回日期 返回日期+ 1个月;
CREATE Function Schema1.F1(parm timestamp) 返回日期 返回日期(时间戳)+ 1个月;
当您有多个具有相似格式化要求的查询时,这实际上非常有用。
到目前为止我发现的唯一问题是,你最好确定你想要这个函数,因为标准的drop函数“schema”。“name”失败了,因为它无法确定要丢弃的函数。如果有人知道如何删除重载的sql函数,请告诉我!