SQL geometry :: STGeomFromText抛出错误并停止作业

时间:2017-02-03 06:15:19

标签: sql sql-server stored-procedures sql-server-2008-r2

民间,

对你来说很奇怪。

我有一个存储过程用于解析一些表格数据以创建正确的SQL几何对象。

SP使用MakeValid()函数。

在我的情况下,我发现一些未通过测试的对象。但是,这些不会破坏存储过程。存储过程很乐意运行,只是在结果中显示错误。

  

Msg 6522,Level 16,State 1,Line 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)

感谢您提供的任何帮助。

2 个答案:

答案 0 :(得分:1)

我很难确认这对您有用(即我的本地实例在调用MakeValid()太好了),但这可能对您有用。< / p>

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部署到数据库并使用几何实例调用该函数。如果对MakeValid()的调用失败,它应该返回NULL。

答案 1 :(得分:0)

好的,这就是我的答案,但是对于CLR来说Ben Thul有很大的功劳,使用不同的方法可以获得相同的结果。

实现更正确地理解了这个问题。我犯了两个错误。第一个没有意识到我试图捕获的错误是在TRY..CATCH块之外。第二个是相信我需要尝试验证几何的WKB表达式。实际上,以下方法允许在尝试创建WKB之前验证WKT 。以下方法标识无效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