2017-02-03 3 views
0

Люди,Геометрия SQL :: STGeomFromText ошибка бросания и прекращение работы

Получил нечетный для вас.

У меня есть хранимая процедура, которую я использую для анализа некоторых табличных данных для создания правильных объектов геометрии SQL.

SP использует функцию MakeValid().

В моем случае я нашел несколько объектов, которые не прошли тест. Однако они не нарушают хранимую процедуру. Хранимая процедура с удовольствием запускается и просто показывает ошибку в результатах.

Сообщ 6522, уровень 16, состояние 1, строка 257 .NET Framework произошла ошибка во время выполнения определяемой пользователем подпрограммы или статистической "геометрии": System.FormatException: 24306:

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

На самом деле я не уверен, что делать. Я пробовал блок TRY..CATCH, но это не останавливает возникшую ошибку, и работа завершается в любом случае.

Так что, хотя это функция MakeValid, которая вызывает ошибку, я бы предположил, что SP, который сталкивается с ошибкой функции, вызовет ту же проблему.

Любые мысли, как я могу справиться с этим? BTW У меня нет контроля над качеством ввода, кроме как для того, чтобы помечать ошибки, а затем возвращаться и восстанавливать их. Мне все равно хотелось бы, чтобы остальные действительные записи были обработаны.

Вот действующий раздел кода.

SET @GEOM = geometry::STGeomFromText(@GEOMWKT, 4326) 

IF @GEOM.STIsValid() = 0 
BEGIN 
    BEGIN TRY 
     SET @GEOM = @GEOM.MakeValid() 
    END TRY 
    BEGIN CATCH 
     Print 'Error here' 
    END CATCH 
END 

Ниже приведен пример недопустимой геометрии, которая вызывает ошибку.

SET @GEOM = geometry::STGeomFromText('LINESTRING(-121.895652 37.37225, -121.895652 37.37225)', 4326) 

Спасибо за любую помощь.

+0

Вы проверяете '@ GEOM', но делаете операции против' @ VALGEOM'. Это ваше намерение? –

+0

Орехи. Это было бы самым простым решением. Можете ли вы предоставить простой WKT, который производит эту ошибку? –

+0

Ben вот пример синтаксиса, который вызывает ошибку. SET @GEOM = геометрия :: STGeomFromText ('LINESTRING (-121.895652 37.37225, -121.895652 37.37225)', 4326) Также добавлен в исходный вопрос. – Andye

ответ

0

OK Это ответ, который я собираюсь, но значительный кредит для Ben Thul для CLR, который достигает того же результата, используя другой метод.

Реализация правильного понимания вопроса. Я допустил две ошибки. Первый не понимал, что ошибка, которую я пытался поймать, была вне блока TRY..CATCH. Второй верил, что мне нужно попробовать и проверить выражение WKB геометрии. Фактически, следующий метод позволяет проверить WKT до, пытаясь создать WKB. Следующий метод идентифицирует недействительный WKT, устанавливает условие TRUE/FALSE.При проверке WKT действительный WKB можно безопасно создать.

Как только я понял, вопрос, задающий правильный вопрос, поднял решение здесь. https://gis.stackexchange.com/questions/66642/detecting-invalid-wkt-in-text-column-in-sql-server

Я адаптировал код в соответствии с моей реализацией.

/*REVISED CODE*/ 

DECLARE @valid bit 
DECLARE @GEOMWKT varchar(max) 
DECLARE @GEOM geometry 

Set @GEOMWKT = 'LINESTRING(-121.895652 37.37225, -121.895652 37.37225)'-- Test faulty value 
Set @valid = 1 
--Test WKT 
BEGIN TRY               --The is the test here. 
    SET @valid = geometry::STGeomFromText(@GEOMWKT, 4326).STIsValid()--We don't try to 
END TRY               --MakeValid(). No point. 
BEGIN CATCH 
    SET @valid = 0 
END CATCH 
--Now that we know whether the WKT will pass or fail we can operate in a known 
--state and avoid raising an error 
IF @valid = 1 
BEGIN 
    SET @GEOM = geometry::STGeomFromText(@GEOMWKT, 4326)--Safely create a valid WKB 
END 
ELSE 
BEGIN 
    SET @GEOM = geometry::STGeomFromText('POINT EMPTY', 4326)-- Set geometry to empty on fail 
    Print 'Geometry Fail' 
END 
1

Я с трудом проверяющим, что это будет работать для вас (т.е. мой местный экземпляр слишком хорошо при заходе MakeValid()), но это может быть просто работать для вас.

using Microsoft.SqlServer.Server; 
using Microsoft.SqlServer.Types; 
using System.Data.SqlTypes; 

public partial class UserDefinedFunctions 
{ 
    [SqlFunction] 
    public static SqlGeometry TryMakeValid_geometry(SqlGeometry g) 
    { 
     SqlGeometry r; 
     try 
     { 
      r = g.MakeValid(); 

     } 
     catch (System.Exception) 
     { 
      r = SqlGeometry.Null; 
     } 
     return r; 
    } 

    [SqlFunction] 
    public static SqlGeometry TryParseWKT_geometry(SqlString wkt) 
    { 
     SqlGeometry r; 
     try 
     { 
      r = SqlGeometry.Parse(wkt).MakeValid(); 
     } 
     catch 
     { 
      r = SqlGeometry.Null; 
     } 
     return r; 
    } 
} 

Разверните эту среду CLR в своей базе данных и вызовите функцию с помощью экземпляра геометрии. Он должен вернуть NULL, если сбой на MakeValid().

+0

Ben Я получил это скомпилировано и развернуто. Небольшой совет для тех, кто стоит рядом. В Visual Studio вам нужно скомпилировать для .Net 2.0 для SQL 2008. Поздние версии .NET поддерживают более поздние версии SQL. В результате кажется, что я полностью неправильно охарактеризовал проблему. Ошибка вызывается линией SET @GEOM = geometry :: STGeomFromText ( не является MakeValid(). Так, как и многие другие потоки, которые я прочитал, я на самом деле не поймаю ошибку на всех, у меня есть код Я переработаю код и посмотрю, правильно ли это правильно его исправит, исправит проблему! – Andye

+0

Это заброшено чем-то! Я на штифтах и ​​иглах! –

+0

Брошенный по линии SET @GEOM = geometry :: STGeomFromText (@GEOMWKT, 4326). Если вы передадите эту строку недопустимой геометрии, это вызовет ошибку. Однако см. Мой следующий комментарий. – Andye