如何在 SQL where 子句中调用函数/过程?

Posted

技术标签:

【中文标题】如何在 SQL where 子句中调用函数/过程?【英文标题】:How to call a function/procedure in an SQL where clause? 【发布时间】:2014-03-21 09:06:30 【问题描述】:

在我试图在我的 sql 查询中调用一个函数时,我被卡住了。理想情况下,我想做以下事情:

from c in db.items
where calcDistance(c.Latitude, c.Longitude, Latitude, Longitude) =< radius
select ...

但是,据我所知,我不能在 where 子句中调用本地 c# 函数。我做了一些研究,并尝试创建一个存储过程来调用用户定义的函数,该函数执行如下等效操作:

CREATE PROCEDURE dbo.DistanceProc
    @lat1 decimal,
    @long1 decimal,
    @lat2 decimal,
    @long2 decimal
AS
    DECLARE @return FLOAT
    SET @return = dbo.Distance(@lat1, @long1, @lat2, @long2)
SELECT @return

其中 dbo.Distance 是我的用户定义函数,其逻辑与我原来的 c# 函数相同。然后我尝试添加一个函数导入,但没有标量类型 FLOAT,我尝试返回一个双精度。然后尝试使用此代码:

from c in db.items
where radius >=  db.DistanceProc(c.Latitude, c.Longitude, Latitude, Longitude)
select ...

但是,db.DistanceProc() 返回一个 System.Data.Entity.Core.Objects.ObjectResult 类型,而不仅仅是一个普通的 double。我尝试在其中添加一个 .Cast().FirstOrDefault() ,但它无法转换为商店表达式。

在这一点上,我几乎停留在想法上。有没有一种简单的方法可以实现这一目标?我只需要在数据库中每个项目的 where 子句中执行这个额外的距离计算逻辑。我也在考虑只返回 IEnumerable 中的所有项目,然后在本地运行逻辑,但由于数据库相当大,返回每个项目是不可行的。

谢谢!

编辑:

我也尝试过只调用 UDF 而不是使用 these instructions on msdn 的存储过程,但它仍然不起作用。它编译得很好,但在运行时它会抛出 NotSupportedException 并显示以下消息:

LINQ to Entities 无法识别方法 'System.Nullable`1[System.Double] Distance(System.Decimal, System.Decimal, System.Decimal, System.Decimal)' 方法,并且该方法无法翻译成商店表达式。

有什么想法吗?

【问题讨论】:

【参考方案1】:

需要在where子句中调用sql函数,不能调用存储过程。

from c in db.items
where radius >=  db.Distance(c.Latitude, c.Longitude, Latitude, Longitude) -- CALL function instead of procedure

【讨论】:

我的 c# 类似乎没有引用该函数,当我尝试导入该函数时,它没有显示在选择的下拉列表中。我需要做一些额外的工作才能让 udf 出现吗? 我尝试详细了解您的方法,并尝试了一种方法(请参阅原始帖子中的编辑),但唯一的区别是我必须直接调用它而不是前缀为“ db.",因为在该上下文中它仍然未定义,因为我无法创建函数导入。当我尝试时,它抱怨 functionimports 不能有标量返回类型。

以上是关于如何在 SQL where 子句中调用函数/过程?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 IQueryable 的 where 子句中调用函数

在存储过程 sql server 2005 中使用函数调用?

如何在 SQL Server where 子句中使用表值函数

sql优化

如何在 SQL*Plus 中将参数(值)从函数传递/调用到“选择”stmt?

LINQ to SQL查询中的C#Dynamic WHERE子句