使用 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 APPLY
ed 的函数,比如
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,这听起来是最好的选择。
希望这能给你一些想法。对这些建议的评论中的反馈表示赞赏。
我有一些数据要批量导入到这个 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 APPLY
ed 的函数,比如
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,这听起来是最好的选择。
希望这能给你一些想法。对这些建议的评论中的反馈表示赞赏。