SQL Ошибка выполнения сборки Server 2012 - System.NullReferenceException: ссылка на объект не установлена ​​на экземпляр объекта - PullRequest
1 голос
/ 03 августа 2020

Я пытаюсь выполнить UDF, который использует сборку CLR. Каждый раз, когда я пытаюсь запустить его, я получаю следующую ошибку:

Msg 6522, уровень 16, состояние 1, строка 45 A. NET Ошибка платформы во время выполнения пользовательской подпрограммы или совокупного "Геокодирования": System.NullReferenceException: ссылка на объект не установлена ​​для экземпляра объекта.

в ProSpatial.UserDefinedFunctions.GeocodeUDF (SqlString countryRegion, SqlString adminDistrict, SqlString locality, SqlString postalCode, SqlString *

1006 * addressLine) 1008 * Это сборка геокодирования, основанная на блоге, приведенном ниже:

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

Могу ли я что-нибудь сделать, чтобы это исправить? Он работал нормально, но недавно просто перестал работать. Я изменил ключ Bing Maps на новый, но это не решило проблему. У кого-нибудь есть идеи?

Ура

Изменить: я ввел отформатированный URL-адрес в Chrome, чтобы узнать, могу ли я получить сообщение об ошибке. Я ввел следующий формат 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 больше

Ответы [ 2 ]

0 голосов
/ 05 августа 2020

Глядя на код в этом блоге, если вы передаете NULL, значит, ошибку выдает не API. Ошибка возникает из-за того, что NULL значения не обрабатываются при первом вызове метода. Код просто преобразует входные параметры SqlString в string без предварительной проверки, есть ли значение в переменной SqlString. SqlString очень похож на обнуляемый 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 для установки localAdminDistrict, если adminDistrict равно не null.
  3. Обновлен вызов на Geocode(), чтобы использовать localAdminDistrict вместо (string)adminDistrict.

Это должно работать, пока Bing Maps API работает с пустым значением для adminDistrict (т.е. ...&adminDistrict=&locality=...) , в отличие от adminDistrict, отсутствующего в запросе GET (что достаточно просто, просто требуется дополнительная модификация).

ТАКЖЕ: Пока вы собираетесь при обновлении кода вам действительно следует переместить вызовы методов Close() и Dispose() в finally блок для этого try / catch.

Для получения дополнительной информации о работе с SQLCLR в целом посетите: Информация о SQLCLR

0 голосов
/ 04 августа 2020

Просто разобрался. Одно из полей адреса, которое геокодировалось, было пустым в базе данных, и API это не понравилось. Поэтому я удалил это из списка геокодирования

...