我需要创建一个用户定义的函数,它的操作类似于ISNULL系统函数,因为它接受任何类型的参数并返回相同类型的值。 这是怎么做到的?
使用SQL_VARIANT作为数据类型不起作用,因为SQL_VARIANT值需要显式转换。 ISNULL隐式执行数据类型转换。
如何声明不需要显式转换的泛型类型?
让我说清楚。我不打算复制ISNULL功能的功能。我使用ISNULL函数作为函数的模式,它接受SQL Server支持的任何数据类型的两个参数,并返回与参数相同的数据类型的值。
还有其他SQL Server函数实现相同的模式:接受未显式声明数据类型的参数,并返回某些其他数据类型的值,这也未在函数定义中显式声明。示例包括:NULLIF,CAST,CONVERT。
我想知道如何实现这种模式,因为任何UDF都需要显式定义参数和返回值数据类型。
答案 0 :(得分:0)
我刚回答了一个与某种程度相关的问题:https://stackoverflow.com/a/32985478/5089204
没有安全的方法来处理空值。在大多数情况下,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)