簡體   English   中英

使用 T-SQL 運行函數時出錯

[英]Getting error while running function using T-SQL

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

首先,不能保證從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;

與大衛所說的相反:為了讓您的函數像您期望的那樣工作,您將需要一個標量用戶定義函數 (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 帖子

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM