从 sql 程序调用用户定义的标量函数

Posted

技术标签:

【中文标题】从 sql 程序调用用户定义的标量函数【英文标题】:Calling a user defined scalar function from a sql program 【发布时间】:2010-07-02 14:23:16 【问题描述】:

我对 SQL 函数还是很陌生。我试图弄清楚如何在 SQL 程序中正确使用。我想测试我创建的标量 UDF,以查看正确返回数据并可以按顺序返回大量数据。我不确定我在 SQL 中使用该函数的语法有什么问题,因为这是我的第一次尝试。有人可以引导我朝着正确的方向前进吗?

这是一个例子。

功能代码:

SET ANSI_NULLS_ON
GO
GET QUOTED_IDENTIFIER ON
GO

ALTER FUNCTION dbo.FN_LTV_Ranges

(

   @LTV_RANGE     decimal(4,3)
)

Returns variable (160
as 
Begin

declare @Return     varchar(16)
select  @Return =

        Case 
        When @LTV_Range is NULL then 'Missing'
        When @LTV_Range is 00.00 then 'Missing'
        When @LTV_Range <= 0.75 then '<=0.75'
        When @LTV_Range between 0.75 and 0.80 then '75-80'
        When @LTV_Range between 0.80 and 0.90 then '80-90'
        When @LTV_Range between 0.90 and 1.00 then '90-100'
        When @LTV_Range >= 100 then '100+'
        else null end

        Return &Return
END

这里是调用和测试上述函数的SQL程序:

declare @LTV_Range         decimal(4,3)

Select top 600   s.LNumber

from OPENQUERY (SvrLink,  '

Select Lnumber, dbo.FN_LTV_Range(@LTV_Range)

 from some_table s
        where s.LNumber > '0'
          group by @LTV_Range
          Order by @LTV_Range

for Fetch only with UR')

这是尝试运行 SQL 程序时返回的错误:

链接服务器“SvrLink”的 OLE CB 提供程序“MSDASQL”返回消息“(IBM)(CLI 驱动程序) (DB2/LINUXX8641) SQL0306N“@LTV_RANGE”在使用它的上下文中无效。SQLSTATE= 42703

消息 7350,第 16 级,状态 2,第 5 行 无法从链接服务器“SrvLinnk”的 OLE DB 提供程序“MSDASQL”获取列信息

【问题讨论】:

该函数是 SQL Server 函数吗? 是的,该函数是用户定义的 sql server 函数 它不会在 SQL Server 中以当前格式创建... 【参考方案1】:

好吧,该函数至少应该是这样的如果它用于 SQL Server:你上面的内容是错误的

ALTER FUNCTION dbo.FN_LTV_Ranges
(

   @LTV_RANGE     decimal(4,3)
)
Returns varchar(16)
as 
Begin
declare @Return     varchar(16)
select  @Return =
        Case 
        When @LTV_Range is NULL then 'Missing'
        When @LTV_Range = 0 then 'Missing'
        When @LTV_Range <= 0.75 then '<=0.75'
        When @LTV_Range between 0.75 and 0.80 then '75-80'
        When @LTV_Range between 0.80 and 0.90 then '80-90'
        When @LTV_Range between 0.90 and 1.00 then '90-100'
        When @LTV_Range >= 100 then '100+'
        else null end
        Return @Return
END

对于小数 (4,3),您的最小值/最大值为 +/- 9.999,那么为什么要使用“When @LTV_Range &gt;= 100 then '100+'”?

接下来,为什么 OPENQUERY 向包含 SQL Server 函数的 DB2 实例提交 SQL 调用?

我假设您想要函数调用 + 分组 + 外部排序。你在哪里设置@LTV_Range?

最后,@LTV_Range 上的分组+排序是没有意义的:它是一个单一的值,所以我假设您的意思是对函数调用的结果进行分组/排序

declare @LTV_Range decimal(4,3)
Select top 600
   s.LNumber, dbo.FN_LTV_Range(@LTV_Range)
from
     OPENQUERY (SvrLink,  '
Select Lnumber
 from some_table s
        where s.LNumber > '0'
for Fetch only with UR')
group by dbo.FN_LTV_Range(@LTV_Range)
Order by dbo.FN_LTV_Range(@LTV_Range)

我很抱歉说这个问题毫无意义......

【讨论】:

很抱歉,我输入了有关返回变量的函数信息,右括号无意中输入为零。返回的值是以整数表示的百分比 需要对返回的数据进行分组和排序的原因是,当开发人员使用摘要类型的函数时(例如使用 Count(*) 报告,那么所有潜在的返回值是有序的,就这种类型的输出而言:Lnumber LTV_Range 123 Missing 300

以上是关于从 sql 程序调用用户定义的标量函数的主要内容,如果未能解决你的问题,请参考以下文章

数据库原理与应用(SQL Server)笔记 第十章 用户定义函数

从 Linq Query 调用 SQL 标量函数

SQL Server如何定位自定义标量函数被那个SQL调用次数最多浅析

SQL Server如何定位自定义标量函数被那个SQL调用次数最多浅析

如何使用 GETDATE 解决 SQL 标量变量的错误

使用 Entity Framework Core (2.1) 调用标量函数的最佳实践