使用T-SQL运行函数时出错

时间:2017-08-16 00:19:26

标签: sql sql-server function tsql

我使用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');

2 个答案:

答案 0 :(得分:2)

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;

答案 1 :(得分:1)

在David的说法的另一面:为了使你的功能像你期望的那样工作,你将需要一个标量的用户定义函数(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 。我将在这篇文章的底部包含一些很好的链接来解释原因。正如David所说,让你的功能保持原样并使用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更好:

How to Make Scalar UDFs Run Faster - 杰夫莫登

Scalar functions, inlining, and performance - Adam Machanic

TSQL Scalar functions are evil – Andy Irving - Stackoerflow帖子