首页 > 解决方案 > SQL Server 2012 程序集执行失败 - System.NullReferenceException:对象引用未设置为对象的实例

问题描述

我正在尝试执行使用 CLR 程序集的 UDF。每次我尝试运行它时,都会出现以下错误:

消息 6522,级别 16,状态 1,第 45
行在执行用户定义的例程或聚合“地理代码”期间发生 .NET Framework 错误:
System.NullReferenceException:对象引用未设置为对象的实例。

在 ProSpatial.UserDefinedFunctions.GeocodeUDF (SqlString countryRegion, SqlString adminDistrict, SqlString locality, SqlString postalCode, SqlString addressLine)

它是一个地理编码程序集,基于以下博客:

https://alastaira.wordpress.com/2012/05/04/geocoding-in-sql-server-with-the-bing-maps-locations-api/

有什么我可以解决的吗?它工作正常,但最近刚刚停止工作。我将 Bing Maps 键更改为新键,但这并没有解决问题。有人有想法么?

干杯

编辑:我在 Chrome 中输入了一个格式化的 URL,看看我是否能得到错误。我输入了以下 URL 格式:

http://dev.virtualearth.net/REST/v1/Locations?countryRegion={0}&adminDistrict={1}&locality={2}&postalCode={3}&addressLine={4}&key={5}&output=xml

我所做的只是用它们各自的条目替换项目 0 到 5。我把大括号留在了那里,然后也尝试了没有大括号的情况。如果没有大括号,则 URL 返回没有问题的结果。

在浏览器中,我得到了地理编码结果,但不再是 SQL

标签: sql-server.net-assemblysqlclr

解决方案


查看该博客中的代码,如果您传入 a NULL,那么引发错误的不是 API。发生错误是因为NULL首次调用该方法时未处理值。代码只是将SqlString输入参数转换为,string而不首先检查变量中是否有值SqlStringSqlString与可为空的 非常相似string

NULL幸运的是,调整代码以正确处理输入参数中的值是相当容易的。从下面的原始代码的编辑片段开始,我将展示如何对一个参数执行此操作,您可以对其他参数重复该修改(嗯,可能实际上NULL在数据库中的那些;不需要对参数执行此操作由于在NOT NULL列中,所以保证在那里)。

    public static SqlGeography GeocodeUDF(
      SqlString countryRegion,
      SqlString adminDistrict,
      SqlString locality,
      SqlString postalCode,
      SqlString addressLine
      )
    {
 
      ...

      string localAdminDistrict = string.Empty;

      if (!adminDistrict.IsNull)
      {
          localAdminDistrict = adminDistrict.Value;
      }

 
      // Attempt to geocode the requested address
      try
      {
        geocodeResponse = Geocode(
          (string)countryRegion,
          localAdminDistrict,
          (string)locality,
          (string)postalCode,
          (string)addressLine
        );
      }

我所做的只是:

  1. 为 增加了一个局部变量localAdminDistrict,默认为空字符串。
  2. 添加了一个if块来设置localAdminDistrictif adminDistrictis not null
  3. 更新了Geocode()对使用的调用,localAdminDistrict而不是(string)adminDistrict.

只要 Bing Maps API 可以使用adminDistrict(ie ...&adminDistrict=&locality=...) 的空值,而adminDistrict不是在 GET 请求中不存在(这很容易,它只需要额外的修改),这应该可以工作。

另外:只要您要在那里更新代码,您确实应该将对Close()andDispose()方法的调用移动到该/的finally块中。trycatch


有关一般使用 SQLCLR 的更多信息,请访问:SQLCLR 信息


推荐阅读