使用 geometry::STPolyFromText(

check which well known text can be transformed using geometry::STPolyFromText(

我有一些数据要批量导入到这个 table 结构中:

CREATE TABLE #Temp
(
    WellKnownText NVARCHAR(MAX)
)

部分条目无效。所以像这样:

SELECT geometry::STPolyFromText(WellKnownText,4326) FROM #Temp

不适用于所有行,因此会掉下来。

检测哪些 WellKnownText 无效的最佳方法是什么?我过去使用过 MakeValid - 所以理想情况下我想尽可能多地修复条目。

PS:

这不起作用:

SELECT * FROM #Temp 
WHERE geometry::STPolyFromText(WellKnownText,4326).STIsValid() = 0

PPS:

我最终选择了一种基于循环的方法:

IF OBJECT_ID('tempdb..#Temp') IS NOT NULL DROP TABLE #Temp;
IF OBJECT_ID('tempdb..#Temp1') IS NOT NULL DROP TABLE #Temp1;

DECLARE @LoopCounter INT = 1;
DECLARE @MaxCounter INT;
DECLARE @Valid BIT;
DECLARE @ValidCounter INT;
DECLARE @WellKnownText NVARCHAR(MAX); 

CREATE TABLE #Temp
(
    Guid UNIQUEIDENTIFIER,  
    PostcodeFraction NVARCHAR(50),
    WellKnownText NVARCHAR(MAX),
    GeoJson NVARCHAR(MAX)
);

CREATE TABLE #Temp1
(
    Guid UNIQUEIDENTIFIER,  
    PostcodeFraction NVARCHAR(50),
    WellKnownText NVARCHAR(MAX),
    GeoJson NVARCHAR(MAX)
);

BULK INSERT #Temp FROM 'D:\PolygonData.txt' WITH (FIELDTERMINATOR = '\t', FIRSTROW = 2, ROWTERMINATOR = '\n');

ALTER TABLE #Temp ADD Id INT IDENTITY(1,1);

SELECT @MaxCounter = MAX(Id) FROM #Temp

SET @ValidCounter = 0;

WHILE(@LoopCounter <= @MaxCounter)
BEGIN
    BEGIN TRY
        SELECT @WellKnownText = WellKnownText FROM #Temp WHERE Id = @LoopCounter;
        SET @Valid = GEOMETRY::STGeomFromText(@WellKnownText,4326).STIsValid();
        SET @ValidCounter = @ValidCounter + 1;
    END TRY
    BEGIN CATCH
        SET @Valid = 0;
    END CATCH

    IF(@Valid = 1)
        BEGIN 
            INSERT INTO #TEMP1
            SELECT Guid, PostcodeFraction, WellKnownText, GeoJson FROM #Temp WHERE Id = @LoopCounter; 
        END 

    SET @LoopCounter  = @LoopCounter  + 1;       
END

PRINT @ValidCounter;

SELECT * FROM #TEMP1;

根据评论中的要求,一些可能的解决方案

我猜你真的在寻找一个可以 CROSS APPLYed 的函数,比如

SELECT * FROM #Temp T
CROSS APPLY IsWKTValidFunc(T.WellKnownText, 4326) F
WHERE F.IsValid = <somecondition>

(或者甚至添加到计算列中,为您提供一个在插入 WKT 时设置的标志)

存储过程

https://gis.stackexchange.com/questions/66642/detecting-invalid-wkt-in-text-column-in-sql-server 有一个简单的 SP,它将 GEOMETREY::STGeomFromText 包装在一个 try catch 块中。

但是,存储过程不能被 CROSS APPLY 编辑(或者可以从 UDF 调用),因此这将导致基于游标的解决方案。

UDF

UDF 可以交叉应用,但不能有 TRY-CATCH 块。您也不能从 UDF 调用上述 SP。所以用处不大。

CLR UDF

GEOMETREY::STGeomFromText 调用包装在可以是 CROSS APPLIED 的 CLR UDF 中,可以有 try catch 和其他错误检查、规则等,以及 return 指示有效文本的标志。我还没有尝试过这个,但如果您的环境中启用了 CLR,这听起来是最好的选择。

希望这能给你一些想法。对这些建议的评论中的反馈表示赞赏。