SQLCLR .NET Error: Object reference not set to an instance of an object
SQLCLR .NET Error: Object reference not set to an instance of an object
我目前在尝试执行一个简单的 SELECT
语句时收到一个错误,该语句引用了一个包含 Jaro-Winkler 距离算法的 C# 代码的程序集。这是我第一次使用 SQLCLR。
我能够 运行 下面的代码成功 而无需 额外的 OR
语句
示例:
SELECT
*
FROM
USERS
WHERE
(
DATE_OF_BIRTH IS NOT NULL
AND DBO.JAROWINKLER(CONVERT(VARCHAR(6),DATE_OF_BIRTH,12),@DOB) > 0.9
)
OR
(
USERID = @USERID
)
然而,当我包含 OR
语句时,我收到此错误消息:
A .NET Framework error occurred during execution of user-defined routine or aggregate "JaroWinkler":
System.NullReferenceException: Object reference not set to an instance of an object.
System.NullReferenceException:
at JaroWinklerDistanceCLR.JaroWinklerDistance.proximity(String aString1, String aString2)
下面的代码可以工作并且可以完成所需的工作。我只是想知道是否有另一种方法?理想情况下,我希望它包含在一个 SELECT
语句中。我不知道上面的错误指的是什么,UserID
列中没有 NULL
值。
程序集的权限设置为安全。
工作示例:
SELECT
*
FROM
USERS
WHERE
DATE_OF_BIRTH IS NOT NULL
AND DBO.JAROWINKLER(CONVERT(VARCHAR(6),DATE_OF_BIRTH,12),@DOB) > 0.9
UNION ALL
SELECT
*
FROM
USERS
WHERE
USERID = @USERID
OR 语句很可能将 NULL 值包含到作为不同数据类型返回的结果集中。尝试使用
OR (USERID = @USERID AND AND P.DATE_OF_BIRTH IS NOT NULL)
或者,如果您需要 NULL 值,则 select 字段名称显式(而不是 select *)并将 date_of_birth 字段包装在转换语句中
谢谢。 NULL
出生日期字段中的值。
工作中!
SELECT
*
FROM
USERS
WHERE
(
DBO.JAROWINKLER(CONVERT(VARCHAR(6),ISNULL(P.DATE_OF_BIRTH,''),12),@DOB) > 0.9
)
OR
(
USERID = @USERID
)
其他两个答案是解决方法,而不是解决方案。而且这个变通办法必须在每个使用这个函数的地方重复,这很容易出错并且难以维护。
在进入主要问题之前,有一个相关的小问题需要先解决:输入参数类型不正确。对于 SQLCLR 方法,您应该使用 Sql*
类型而不是标准的 .NET 类型。对于这个特定的代码,这意味着使用 SqlString
而不是 String
。为什么SqlString
而不是String
,请看我对下面S.O的回答。问题:Should I use SqlString or string as parameter type to SQLCLR UDF's.
现在,问题是 SQLCLR 代码没有正确处理 NULL
s。幸运的是,让它处理它们并不难。有两个选项,取决于输入参数的 any 是否可以接受 NULL
:
如果任何的入参都可以有效传入一个NULL
,那么你需要在代码中处理这个(这也是适用于使用 Table-Valued Functions 和 Stored Procedures 时的所有情况)。然后您通过所有 Sql*
类型都具有的 .IsNull
属性 签入代码。例如(假设aString2
可以传入一个NULL
):
if (aString1.IsNull)
{
return SqlDouble.Null;
}
如果none的输入参数可以有效地接受NULL
,那么你应该绕过所有处理而不输入代码首先通过使用 CREATE FUNCTION
语句的 WITH RETURNS NULL ON NULL INPUT
选项创建标量 UDF。设置此选项后,如果 any 输入参数为 NULL
,则跳过代码并假定 NULL
return 值。请注意,这仅适用于标量 UDF 和用户定义类型方法。
有关一般使用 SQLCLR 的更多信息,请参阅我在 SQL Server Central 上就此主题撰写的系列文章(需要免费注册才能阅读其中的内容站点): Stairway to SQLCLR.
在相关说明中,我质疑使用字符串距离函数来执行相当简单的日期计算。我认为这段代码将从基于将字符串 @DOB
转换为 DATE
或 DATETIME
.
的 DATEDIFF
替换 JaroWinkler 函数中受益匪浅
我目前在尝试执行一个简单的 SELECT
语句时收到一个错误,该语句引用了一个包含 Jaro-Winkler 距离算法的 C# 代码的程序集。这是我第一次使用 SQLCLR。
我能够 运行 下面的代码成功 而无需 额外的 OR
语句
示例:
SELECT
*
FROM
USERS
WHERE
(
DATE_OF_BIRTH IS NOT NULL
AND DBO.JAROWINKLER(CONVERT(VARCHAR(6),DATE_OF_BIRTH,12),@DOB) > 0.9
)
OR
(
USERID = @USERID
)
然而,当我包含 OR
语句时,我收到此错误消息:
A .NET Framework error occurred during execution of user-defined routine or aggregate "JaroWinkler":
System.NullReferenceException: Object reference not set to an instance of an object. System.NullReferenceException: at JaroWinklerDistanceCLR.JaroWinklerDistance.proximity(String aString1, String aString2)
下面的代码可以工作并且可以完成所需的工作。我只是想知道是否有另一种方法?理想情况下,我希望它包含在一个 SELECT
语句中。我不知道上面的错误指的是什么,UserID
列中没有 NULL
值。
程序集的权限设置为安全。
工作示例:
SELECT
*
FROM
USERS
WHERE
DATE_OF_BIRTH IS NOT NULL
AND DBO.JAROWINKLER(CONVERT(VARCHAR(6),DATE_OF_BIRTH,12),@DOB) > 0.9
UNION ALL
SELECT
*
FROM
USERS
WHERE
USERID = @USERID
OR 语句很可能将 NULL 值包含到作为不同数据类型返回的结果集中。尝试使用
OR (USERID = @USERID AND AND P.DATE_OF_BIRTH IS NOT NULL)
或者,如果您需要 NULL 值,则 select 字段名称显式(而不是 select *)并将 date_of_birth 字段包装在转换语句中
谢谢。 NULL
出生日期字段中的值。
工作中!
SELECT
*
FROM
USERS
WHERE
(
DBO.JAROWINKLER(CONVERT(VARCHAR(6),ISNULL(P.DATE_OF_BIRTH,''),12),@DOB) > 0.9
)
OR
(
USERID = @USERID
)
其他两个答案是解决方法,而不是解决方案。而且这个变通办法必须在每个使用这个函数的地方重复,这很容易出错并且难以维护。
在进入主要问题之前,有一个相关的小问题需要先解决:输入参数类型不正确。对于 SQLCLR 方法,您应该使用 Sql*
类型而不是标准的 .NET 类型。对于这个特定的代码,这意味着使用 SqlString
而不是 String
。为什么SqlString
而不是String
,请看我对下面S.O的回答。问题:Should I use SqlString or string as parameter type to SQLCLR UDF's.
现在,问题是 SQLCLR 代码没有正确处理 NULL
s。幸运的是,让它处理它们并不难。有两个选项,取决于输入参数的 any 是否可以接受 NULL
:
如果任何的入参都可以有效传入一个
NULL
,那么你需要在代码中处理这个(这也是适用于使用 Table-Valued Functions 和 Stored Procedures 时的所有情况)。然后您通过所有Sql*
类型都具有的.IsNull
属性 签入代码。例如(假设aString2
可以传入一个NULL
):if (aString1.IsNull) { return SqlDouble.Null; }
如果none的输入参数可以有效地接受
NULL
,那么你应该绕过所有处理而不输入代码首先通过使用CREATE FUNCTION
语句的WITH RETURNS NULL ON NULL INPUT
选项创建标量 UDF。设置此选项后,如果 any 输入参数为NULL
,则跳过代码并假定NULL
return 值。请注意,这仅适用于标量 UDF 和用户定义类型方法。
有关一般使用 SQLCLR 的更多信息,请参阅我在 SQL Server Central 上就此主题撰写的系列文章(需要免费注册才能阅读其中的内容站点): Stairway to SQLCLR.
在相关说明中,我质疑使用字符串距离函数来执行相当简单的日期计算。我认为这段代码将从基于将字符串 @DOB
转换为 DATE
或 DATETIME
.
DATEDIFF
替换 JaroWinkler 函数中受益匪浅