Sql server SQL Server用户定义函数,采用任何类型的参数,如ISNULL

Sql server SQL Server用户定义函数,采用任何类型的参数,如ISNULL,sql-server,generics,types,user-defined-functions,isnull,Sql Server,Generics,Types,User Defined Functions,Isnull,我需要创建一个用户定义的函数,它的操作类似于ISNULL系统函数,因为它可以接受任何类型的参数并返回相同类型的值。 这是怎么做到的 使用SQL_VARIANT作为数据类型将不起作用,因为SQL_VARIANT值需要显式转换。ISNULL隐式地进行数据类型转换 如何声明不需要显式强制转换的泛型类型 让我说清楚。我不想复制ISNULL函数的功能。我使用ISNULL函数作为函数的模式,该函数接受SQL Server支持的任何数据类型的两个参数,并返回与参数相同的数据类型的值 还有其他SQL Serve

我需要创建一个用户定义的函数,它的操作类似于ISNULL系统函数,因为它可以接受任何类型的参数并返回相同类型的值。 这是怎么做到的

使用SQL_VARIANT作为数据类型将不起作用,因为SQL_VARIANT值需要显式转换。ISNULL隐式地进行数据类型转换

如何声明不需要显式强制转换的泛型类型

让我说清楚。我不想复制ISNULL函数的功能。我使用ISNULL函数作为函数的模式,该函数接受SQL Server支持的任何数据类型的两个参数,并返回与参数相同的数据类型的值

还有其他SQL Server函数实现相同的模式:接受未显式声明的数据类型的参数,并返回某些其他数据类型的值,这些数据类型也未在函数定义中显式声明。例如:NULLIF、CAST、CONVERT


我想知道这个模式是如何实现的,因为任何UDF都需要明确定义参数和返回值数据类型。

我刚刚回答了一个与此相关的问题:

没有安全的方法来处理空值。ISNULL在大多数情况下都很好,但是如果没有隐式可转换类型的两个参数,它将无法编译

看看这在XML中是如何处理的。只需将其粘贴到一个空的查询窗口中并执行:

--The NULL-element is not there at all
SELECT 'text' AS filled
      ,'' AS empty
      ,NULL AS NotThere
FOR XML PATH('row');   

--The NULL-element is rendered using "nil"
SELECT 'text' AS filled
      ,'' AS empty
      ,NULL AS NotThere
FOR XML PATH('row'),ELEMENTS XSINIL    

--Look at this: Both columns are called "TheName". They are implicitly concatenated
SELECT 'a' AS TheName
      ,'b' AS TheName
FOR XML PATH('row')

--That leads to: Concatenate nothing with an empty string will at least return the empty string.
--this is other/better than ISNULL, because it will work with any type...
SELECT NULL AS TheName
      ,'' AS TheName
FOR XML PATH('row')

--now an example with table data
DECLARE @tbl TABLE(int1 INT, int2 INT);
INSERT INTO @tbl VALUES(NULL,1); --first value is null

--int1 is swallowed
SELECT *
FROM @tbl
FOR XML PATH('row')

--both elements are there
SELECT int1, '' AS int1 --ISNULL(int1,'') would not compile here...
      ,int2, '' AS int2
FROM @tbl
FOR XML PATH('row')

--This is the result of the last example: Look what happens to the empty int element, its Zero! 
--This is the way this is handled in XML conversions. Try it with other types (like 'date' [result is 1900-01-01] or any other type)...
DECLARE @a XML='<row><int1></int1><int2>1</int2></row>';
SELECT a.b.value('int1[1]','int') AS int1
      ,a.b.value('int2[1]','int') AS int2
FROM @a.nodes('/row') a(b)
--空元素根本不存在
选择“文本”作为填充
,“”为空
,空为NotThere
用于XML路径(“行”);
--使用“nil”呈现空元素
选择“文本”作为填充
,“”为空
,空为NotThere
对于XML路径(“行”),元素为XSINIL
--看看这个:两列都称为“TheName”。它们是隐式连接的
选择“a”作为名称
“b”作为名称
用于XML路径(“行”)
--这就导致了:不使用空字符串连接任何内容至少会返回空字符串。
--这与ISNULL不同/更好,因为它可以用于任何类型。。。
选择NULL作为名称
,“”作为名称
用于XML路径(“行”)
--下面是一个表数据示例
声明@tbl表(int1 INT,int2 INT);
插入@tbl值(NULL,1)--第一个值为空
--int1被吞食了
挑选*
来自@tbl
用于XML路径(“行”)
--这两种元素都存在
选择int1“”,因为int1--ISNULL(int1“”)不会在此处编译。。。
,int2',作为int2
来自@tbl
用于XML路径(“行”)
--这是最后一个示例的结果:看看空int元素发生了什么,它的零!
--这是在XML转换中处理的方式。尝试其他类型(如“日期”[结果为1900-01-01]或任何其他类型)。。。
声明@a XML='1';
选择a.b.value('int1[1],'int')作为int1
,a.b.value('int2[1],'int')作为int2
来自@a.nodes('/row')a(b)

每种类型的替换值应该是多少?用空字符串替换空字符串很明显,但是datetime的非值是什么?零真的是数字类型的非值吗?您想要实现什么?T-SQL没有泛型,用户定义的函数返回类型是静态的(并且是必需的),因此您真正想要的是不可能的。我可以想到一些可以实现您想要的东西(比如生成表的存储过程或动态SQL),但也有一些很好的理由说明您不想在生产代码中使用这些东西。既然
ISNULL
已经存在并且工作正常,那么您到底想要什么与
ISNULL
类似,以及为什么呢?Shnugo,关键是要有一个与参数类型无关的函数,并且能够像ISNULL或NULLIF这样的函数那样执行任何操作。关键不是要实现另一个版本的ISNULL,而是要能够创建一个新函数,该函数可以处理任何时间的参数,更重要的是返回与参数相同类型的值。Jeroen Mostert,我很困惑,我原来的问题中有什么不清楚的地方。我清楚地声明,我不需要创建另一个ISNULL函数。我解释说,我所寻找的相似性严格来说是模式方面的。这真的很吸引人,而且信息量很大。我感谢你分享这些信息。我相信我会找到一个很好的用途。但是,这并没有让我更接近我的问题的答案:SQL Server如何在没有显式定义参数和返回值数据类型的情况下实现ISNULL、CONVERT、CAST、NULLIF等函数?