民间,
对你来说很奇怪。
我有一个存储过程用于解析一些表格数据以创建正确的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)
感谢您提供的任何帮助。
答案 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