民间, 我怀疑这很容易,但我很难找到一个好的参考。
我有一个包含线,点和多边形的WKT列的表。我正在将WKT处理成地理列。
在大部分时间里,我都希望在处理之前对WKT进行质量检查。
我在这里遇到了麻烦。
我尝试过的最简单的事情是
select *
from GEOMWKT
where geometry::STGeomFromText(GEOG_WKT, 4326).STIsValid() = 0;
然而,如果记录确实存在错误,则会中断。
A .NET Framework error occurred during execution of user-defined routine or aggregate "geometry":
System.FormatException: 24117: The LineString input is not valid because it does not have enough distinct points. A LineString must have at least two distinct points.
为了尝试缓解这种情况,我尝试了以下
-- Verify that the stored procedure does not already exist.
IF OBJECT_ID ( 'usp_GetErrorInfo', 'P' ) IS NOT NULL
DROP PROCEDURE usp_GetErrorInfo;
GO
-- Create procedure to retrieve error information.
CREATE PROCEDURE usp_GetErrorInfo
AS
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
GO
BEGIN TRY
select * from GEOMWKT where geometry::STGeomFromText(GEOG_WKT, 4326).STIsValid() = 0;
END TRY
BEGIN CATCH
-- Execute error retrieval routine.
EXECUTE usp_GetErrorInfo;
END CATCH;
虽然这可以恢复它的功能,但是管理并返回了错误,但我仍然不知道它是哪条记录。
如何返回ID列或某些记录失败的内容?
答案 0 :(得分:0)
创建一个存储过程以将txt转换为几何,也不需要转换为几何,该函数已经返回几何对象。
CREATE PROCEDURE usp_GetGeometry
(@Geomtxt varchar(500) )
AS
DECLARE @ReturnValue as geometry
BEGIN TRY
select @ReturnValue = STGeomFromText(@Geomtxt , 4326);
RETURN @ReturnValue
END TRY
BEGIN CATCH
RETURN NULL
END CATCH;
GO
然后将函数用于每一行。
select *, usp_GetGeometry( GEOG_WKT )
from GEOMWKT
答案 1 :(得分:0)
这是我使用游标的问题的答案。正如我所读,我们不喜欢游标,但这有效。
我更喜欢存储过程或函数的优雅,但这样就完成了。
请注意:根据原始链接,这使用两种方法来查找无效的几何图形。有时你会得到一个重复的ID,有时不依赖于失败。
我仍然对改进感兴趣,因为在我们对它们进行处理之前,我想设置一个存储过程来报告这些内容。
-- ----------------------------------------------------
-- Find invalid geometry in given Spatial table
-- ----------------------------------------------------
DECLARE @id INT, @n INT, @g varchar(max);
-- create error log table
IF EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[ERR_CorruptedGeom]') AND type in (N'U'))
DROP TABLE [dbo].[ERR_CorruptedGeom];
CREATE TABLE [dbo].[ERR_CorruptedGeom](
recordid [int] NULL,
table_name Varchar(25) NULL,
errtext Varchar(MAX) NULL
) ON [PRIMARY];
-- define QA cursor on spatial table
DECLARE qa_cursor CURSOR FOR
SELECT GEOMID, GEOG_WKT
FROM dbo.GEOMWKT;
OPEN qa_cursor -- open cursor
FETCH NEXT FROM qa_cursor INTO @id, @g;
-- run over table records from the begining to the end
WHILE (@@FETCH_STATUS <> -1)
BEGIN
BEGIN TRY
-- conventional way to find invalid geometry
IF geometry::STGeomFromText(@g, 4326).STIsValid()=0
BEGIN
-- insert problematic record number into Log table
INSERT INTO dbo.ERR_CorruptedGeom (recordid, table_name, errtext)
VALUES (@id, 'dbo.GEOMWKT', 'Invalid Geometry');
END
-- trying to read invalid geometry will raise Error
SET @n = geometry::STGeomFromText(@g, 4326).STNumGeometries();
END TRY
-- error catch block
BEGIN CATCH
-- insert problematic record reference to Log table
INSERT INTO dbo.ERR_CorruptedGeom (recordid, table_name, errtext)
VALUES (@id, 'dbo.GEOMWKT', ERROR_MESSAGE());
END CATCH;
FETCH NEXT FROM qa_cursor INTO @id, @g;
END
-- close cursor
CLOSE qa_cursor;
DEALLOCATE qa_cursor;
-- see results
select * from ERR_CorruptedGeom
这是来自http://www.sqlexamples.info/SPAT/mssql_invalid_geometry.htm