SQLCLR .NET错误:未将对象引用设置为对象的实例

时间:2017-07-27 13:57:35

标签: c# sql-server tsql null sqlclr

我正在尝试执行一个简单的function(){ try{ var divHead= document.getElementsByClassName('card__media-overlapping__media'); var eventhandlerdoc = function(event){ var imgALT=event.currentTarget.firstElementChild.firstElementChild.getAttribute('alt'); return imgALT; } for(var index=0; index < divHead.length; index++){ divHead[index].addEventListener('click',eventhandlerdoc,true);} } catch(e){ return "n/a" } } 语句时收到错误,该语句引用包含Jaro-Winkler距离算法的C#代码的程序集。这是我第一次使用SQLCLR。

我能够在下成功运行代码,而无需额外的SELECT声明

示例:

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 ) 语句时,我收到此错误消息:

  

在执行用户定义的例程或聚合“JaroWinkler”期间发生了.NET Framework错误:

     

System.NullReferenceException:未将对象引用设置为对象的实例。   System.NullReferenceException:      在JaroWinklerDistanceCLR.JaroWinklerDistance.proximity(String aString1,String aString2)

以下代码可以运行并完成所需的操作。我只是想知道是否有另一种方式?理想情况下,我希望它包含在一个OR语句中。我不知道上面的错误指的是什么,SELECT列中没有NULL值。

程序集的权限集设置为“安全”。

工作示例:

UserID

3 个答案:

答案 0 :(得分:1)

OR语句很可能包括结果集中的NULL值,这些值将作为不同的数据类型返回。尝试使用

    OR (USERID = @USERID AND AND P.DATE_OF_BIRTH IS NOT NULL)

或者,如果您需要NULL值,则显式选择字段名称(而不是select *)并在转换语句中包装date_of_birth字段

答案 1 :(得分:1)

另外两个答案是解决方案,而不是解决方案。并且这种解决方法必须在使用此功能的每个地方重复,这非常容易出错且难以维护。

在进入主要问题之前,有一个小的相关问题应该先修复:输入参数类型不正确。对于SQLCLR方法,您应该使用Sql*类型而不是标准.NET类型。对于此特定代码,这意味着使用SqlString而不是String。有关SqlString代替String的原因的详细信息,请参阅以下S.O.的答案。问题:Should I use SqlString or string as parameter type to SQLCLR UDF's

现在,问题是SQLCLR代码没有正确处理NULL。幸运的是,要处理它们并不困难。有两个选项,具体取决于任何输入参数是否可以接受NULL

  • 如果输入参数中的任何可以有效地传入NULL,那么您需要在代码中处理此问题(这也适用于所有使用时的情况)表值函数和存储过程)。然后通过所有.IsNull类型都具有的Sql*属性检入代码。例如(假设aString2可以传入NULL):

    if (aString1.IsNull)
    {
      return SqlDouble.Null;
    }
    
  • 如果输入参数的 none 可以有效地接受NULL,那么您应该绕过所有处理而不首先通过使用{创建标量UDF来输入代码{1}} WITH RETURNS NULL ON NULL INPUT语句的{1}}选项。设置此选项后,如果任何输入参数为CREATE FUNCTION,则会跳过代码并假定返回NULL。请注意,这仅适用于标量UDF和用户定义类型方法。

有关使用SQLCLR的更多信息,请参阅我在SQL Server Central上就此主题撰写的一系列文章(阅读该网站上的内容需要免费注册):Stairway to SQLCLR

在相关的说明中,我会质疑使用字符串距离函数来做一个相当简单的日期计算。我认为,基于将字符串NULL转换为DATEDIFF@DOB,使用DATE替换JaroWinkler函数可以极大地利用此代码。

答案 2 :(得分:0)

谢谢。出生日期的NULL值。

工作!

SELECT
    * 
FROM
    USERS
WHERE
(
    DBO.JAROWINKLER(CONVERT(VARCHAR(6),ISNULL(P.DATE_OF_BIRTH,''),12),@DOB) > 0.9
)
OR
(
    USERID = @USERID
)