【问题标题】:SQL Server Why is geography::Point inside function non-deterministic?SQL Server 为什么函数内部的 geography::Point 是不确定的?
【发布时间】:2019-05-26 07:32:27
【问题描述】:

我存储来自用户的纬度和经度(float null)数据,并希望根据这些值创建一个地理数据类型的持久计算列(目的是在此列上使用空间索引)。

计算列公式为:

(case when @lat IS NULL OR @lng IS NULL then NULL else [geography]::Point(@lat,@lng,(4326)) end)

当计算列上的 persistent 设置为 true 时,这将按预期工作(当 Latitude 和 Longitude 存在时返回 Geography 值,否则返回 null。

但是,我希望将其抽象为用户定义的函数,因为其他表将使用相同的计算。我创建了以下函数:

CREATE FUNCTION [dbo].[GetGeography] 
(
    @lat float null,
    @lng float null
)
RETURNS geography
AS
BEGIN   
    RETURN (case when @lat IS NULL OR @lng IS NULL then NULL else [geography]::Point(@lat,@lng,(4326)) end)
END

当我尝试在计算列公式中使用此函数并将持久设置为 true 时,我收到以下错误消息:

Computed column 'Geog_LatLng' in table 'Tmp_Locations' cannot be persisted because the column is non-deterministic.

没有关于POINT 的确定性的文档,Deterministic Functions 上的文档也没有提到地理或点。

短期解决方案是在所有表中复制公式,但我想知道是否可以将公式抽象为用户定义的函数。

【问题讨论】:

  • 我建议尝试创建函数with schemabinding 看看是否能解决您的问题。
  • 这可以解释为什么你需要模式绑定:The Halloween Problem

标签: sql-server sql-function sqlgeography


【解决方案1】:

解决方法是使用with schemabinding:

CREATE FUNCTION [dbo].[GetGeography] 
(
    @lat float null,
    @lng float null
)
WITH SCHEMABINDING -- <--- modified
RETURNS geography
AS
BEGIN   
    RETURN (case when @lat IS NULL OR @lng IS NULL then NULL else [geography]::Point(@lat,@lng,(4326)) end)
END

解释在Docs

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    相关资源
    最近更新 更多