当参数不为空时,SQL geography::point null 参数错误?

use*_*599 6 sql-server t-sql spatial sql-server-2016

我收到此错误:

'geography::Point' failed because parameter 1 is not allowed to be null.
Run Code Online (Sandbox Code Playgroud)

在这个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]
Run Code Online (Sandbox Code Playgroud)

但那里没有空值,而且我只在我们的生产计算机(Production 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
Run Code Online (Sandbox Code Playgroud)

我真的很想了解我在第一个查询中做错了什么以及为什么这在第二个查询中有效?

第一个查询我尝试根据使用有效日期列计算的序列号仅获取具有最新记录的行,然后将纬度和经度数据转换为地理类型。

在第二个查询中,我转换纬度和经度数据,然后进行过滤。

我认为我的第一个查询效率更高。

Mic*_*kyT 2

我之前也遇到过关于几何和地理数据类型的类似问题。我认为问题在于优化器决定在计划中构建几何图形的位置(以及如何)。

我遇到了插入语句的问题,基本上是

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
Run Code Online (Sandbox Code Playgroud)

经过一番玩弄并变得有点困惑后发现

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;
Run Code Online (Sandbox Code Playgroud)

两者都有效,但以下无效

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

对于第一个查询,计划显示计算标量在过滤器之前完成

测试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))">
Run Code Online (Sandbox Code Playgroud)

我认为几何和地理上的观点有缺陷,不允许输入 NULL。在我看来,简单地返回 NULL 作为结果会更正确。

如果您愿意,我可以为此提供我的整个测试脚本。