我使用 T-SQL 创建了小表值函数,该函数将一个输入参数电话号码作为并从中返回区号。 函数编译成功,但运行时出现错误:

Msg 4121, Level 16, State 1, Line 1776
找不到列“dbo”或用户定义的函数或聚合“dbo.getareacode1”,或者名称不明确

参考我的代码:

create or alter function dbo.getareacode1 (@phoneno as nvarchar(20))
returns table
with schemabinding
as
    return
       (select top 1 
            @phoneno as PhoneNumber, value as AreaCode 
        from 
            string_split(@phoneno,'-')
       );


select dbo.getareacode1( N'323-234-2111');

#1楼 票数:2 已采纳

首先,不能保证从STRING_SPLIT返回的行的顺序,所以这个函数一开始就被破坏了。

但是错误是由于尝试调用需要标量的表值函数引起的。

不能将 TVF 视为标量函数。 所以

create or alter function dbo.getareacode1 (@phoneno as nvarchar(20))
returns table
with schemabinding
as
return
(
select top 1 @phoneno as PhoneNumber, value as AreaCode 
from string_split(@phoneno,'-')
);
go
select * from dbo.getareacode1( N'323-234-2111');

如果您想从另一个查询中调用它,请使用 CROSS APPLY,例如

with phoneNumbers as
(
    select N'323-234-2111' phoneno
    from sys.objects 
)
select ac.*
from phoneNumbers p
cross apply dbo.getareacode1(p.phoneno) ac;

#2楼 票数:1

与大卫所说的相反:为了让您的函数像您期望的那样工作,您将需要一个标量用户定义函数 (udf)。 这个功能:

-- Create function
create or alter function dbo.getareacode1 (@phoneno as nvarchar(20))
returns nvarchar(20) with schemabinding as
begin
  return
  (
    select top (1) AreaCode = ss.[value]
    from string_split(@phoneno,'-') ss
  );
  end
GO

...将允许此查询工作:

select dbo.getareacode1( N'323-234-2111');

尽管如此我强烈建议不要使用标量 udfs 我将在这篇文章的底部包含几个很好的链接来解释原因。 正如大卫所展示的那样,保持函数原样并使用 APPLY 是要走的路。 此外,这里不需要 string_split。 如果电话号码总是以这种格式出现:NNN-NNN-NNNN,您可以只使用 SUBSTRING:

SUBSTRING(N'323-234-2111', 1, 3). 

对于具有可变长度区号格式(区号(2 位或更多位))-NNN-NNNN 的国家,您可以执行以下操作:

declare @phoneno nvarchar(30) = N'39-234-2111'; -- Using a variable for brevity
select substring(@phoneno,1, charindex('-',@phoneno)-1);

如果你,无论出于何种原因,真的需要一个函数,那么我会这样写:

-- using the variable-length requirement as an example
create or alter function dbo.getareacode1_itvf(@phoneno as nvarchar(20))
returns table with schemabinding as
return (select areacode = substring(@phoneno,1, charindex('-',@phoneno)-1));
go

关于标量 UDF 以及为什么 iTVF 更好的精彩文章:

如何使标量 UDF 运行得更快——Jeff Moden

标量函数、内联和性能——Adam Machanic

TSQL 标量函数是邪恶的——安迪欧文——Stackoerflow 帖子

  ask by Jay Desai translate from so

未解决问题?本站智能推荐:

1回复

使用T-SQL无法从函数获得期望的输出

我使用T-SQL创建了一个小函数,该函数将一个输入参数作为电话号码,并从中返回区号。 函数编译成功,但仅获得电话号码的第一位数字,而不是三位数字。 请参考以下代码:
1回复

当用作IN子查询时,T-SQL表函数不返回行

我具有以下TSQL Table函数,当其本身用作查询时,该函数完全按要求工作: ...当作为基本查询执行时: ....但是当我尝试将该函数用作子查询的一部分时,即使是非常简单的子查询,也不会返回任何行。 谁能阐明为什么? 我不明白在IN子查询中有什么不同,这意味着它不起作用?
1回复

从自定义T-SQL函数返回Varchar[关闭]

我想从我定义如下的函数返回一个简单的varchar值: 应该返回已下订单#1063609但失败的客户的客户类型
1回复

使用临时表创建函数时出错

我正在创建一个包含临时表的函数,对我来说使用带有临时表的函数有点困难,我完全不知道它是否允许在函数中使用,因为我是新的。 我正在尝试创建的功能如下: 如果您注意到我正在使用一个名为#Temp的临时表。 作为尝试编译函数时的错误消息,我收到以下错误消息: 无法从函数内部访问临时表。 这就是为什么我之
2回复

列中的SQL函数运行缓慢

我有一个computed column (函数),导致我的一个表非常慢(它的输出是我的表中的一列。我认为它可能是我的函数中的一些逻辑语句。我评论了那些,只是返回一个字符串称为'test' 。这仍然导致表变慢。我相信SELECT语句正在减慢函数。当我注释掉select语句时,一切都是樱桃。我想我没
2回复

SQL函数遍历表

我是tSQL函数的新手,正在尝试执行以下操作: 我有一个像这样的表叫做Projects: 而且我想创建一个SQL函数以产生以下查询结果: 我想出了以下功能: 但是它运行时似乎处于无限循环中。 有人对实现相同结果有任何想法或更好的方法吗? 提前致谢。
1回复

SQL函数忽略特定条件

我经常编写在WHERE语句中具有重复几行的SQL脚本,以消除记录。 例如: 如果我不必每次都添加这些行,则不太容易出错。 我如何创建一个函数来代替我呢?: 这是我目前拥有的: 但是我觉得我缺少重要的东西。 该函数仅提供我认为对Field1有效的值。 所以我未来的脚本应该是:
2回复

SQL函数返回所有行的总和值

我有两个表,作业表和项目表。 我创建了一个函数,试图为每个作业返回客户价格的总和。 而是返回所有作业的总和。 以下是我创建的函数: 如果可以的话,我想获得每个工作的客户价格的总和,而不是所有工作的总和。 如果有人可以帮助我,我将不胜感激。 谢谢