Sql-Server

當參數不為空時,SQL geography::point null 參數錯誤?

  • November 12, 2020

我收到了這個錯誤:

'geography::Point' failed because parameter 1 is not allowed to be null.

在這個 sql 上:

SELECT [ID], geography::Point([lat], [long], 4326) AS [loc]
FROM (
 SELECT [ID], CONVERT(float, [lat]) AS [lat], CONVERT(float, [long]) AS [long]
 FROM (
   SELECT [ID], [lat], 
   [long], ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY [EFFDT] desc) AS [sequence]
   FROM [GEO]
 ) AS temp1
 WHERE [sequence] = 1
 AND [lat] IS NOT NULL
 AND [long] IS NOT NULL
) AS temp2
ORDER BY [ID]

但是那裡沒有空值,我只在我們的生產機器(生產 13.0.4422.0)上而不是在我們的開發機器(Dev 13.0.1728.2)上得到錯誤。經過數小時的搜尋和重試後,我發現通過重新排序一些東西會起作用:

SELECT [ID], [loc]
FROM (
 SELECT [ID], 
   geography::Point([lat], [long], 4326) AS [loc],
   ,ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY [EFFDT] desc) AS [sequence]
 FROM [GEO]
 WHERE [lat] IS NOT NULL
 AND [long] IS NOT NULL
) AS temp
WHERE [sequence] = 1

我真的很想了解我在第一個查詢中做錯了什麼以及為什麼這在第二個查詢中有效?

第一個查詢我嘗試根據使用有效日期列計算的序列號僅獲取具有最新記錄的行,然後將 lat 和 long 數據轉換為地理類型。

在第二個查詢中,我轉換了經緯度數據,然後進行過濾。

我認為我對第一個查詢的效率更高。

我之前遇到過幾何和地理數據類型的類似問題。我認為問題在於優化器決定在哪裡(以及如何)在計劃中建構幾何。

我遇到了插入語句的問題,基本上是

INSERT INTO (ID,GEOM)
SELECT ID, Geometry::Point(ISNULL(X,0),ISNULL(Y,0),0)
FROM HeapTable
WHERE X is not NULL and Y is not NULL

玩了一圈有點糊塗發現

INSERT INTO (ID,GEOM)
SELECT ID, Geometry::Point(ISNULL(X,0),ISNULL(Y,0),0)
FROM HeapTable;

INSERT INTO (ID,GEOM)
SELECT ID, Geometry::Point(ISNULL(X,0),ISNULL(Y,0),0)
FROM HeapTable
WHERE ISNULL(X,0) != 0;

兩者都有效,但以下無效

INSERT INTO (ID,GEOM)
SELECT ID, Geometry::Point(X,Y,0)
FROM HeapTable
WHERE ISNULL(X,0) != 0;

對於第一個查詢,計劃顯示計算標量在過濾器之前完成

測試 1

並且正在計算的表達式已經ISNULL從其中剝離了函式。

<ColumnReference Column="Expr1005" />
<ScalarOperator ScalarString="[Geometry]::Point(CONVERT_IMPLICIT(float(53),[sandbox].[dbo].[TestNullGeomIssueSource].[X],0),CONVERT_IMPLICIT(float(53),[sandbox].[dbo].[TestNullGeomIssueSource].[Y],0),(0))">

我認為幾何和地理上的點在不允許輸入 NULL 方面存在缺陷。在我看來,簡單地返回一個 NULL 結果會更正確。

如果您希望我可以為此放置我的整個測試腳本。

引用自:https://dba.stackexchange.com/questions/187986