2017-08-16 3 views
0

Ich habe kleine Tabellenwertfunktion mit T-SQL erstellt, die eine Eingabeparametrufnummer als akzeptiert und Ortskennzahl daraus zurückgibt. Funktion erfolgreich kompiliert, aber wenn ich es benutze ich Störung erhalte:Fehler beim Ausführen der Funktion unter Verwendung von T-SQL

Msg 4121, Level 16, State 1, Line 1776
Cannot find either column "dbo" or the user-defined function or aggregate "dbo.getareacode1", or the name is ambiguous

Siehe meinen Code:

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'); 

Antwort

2

A TVF kann nicht wie eine Skalar-Funktion behandelt werden. So

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'); 

Und wenn Sie wollen, dass es aus einer anderen Abfrage Verwendung CROSS aufrufen GILT, zB

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

Auf der Kehrseite dessen, was David gesagt: für Ihre Funktion zu arbeiten, wie Sie Sie erwarten benötigt eine skalare benutzerdefinierte Funktion (udf). Diese Funktion:

-- 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 

... wird diese Abfrage ermöglichen zu arbeiten:

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

Alles, was gesagt, Ich rate dringend gegen die Verwendung von skalaren udfs. Ich werde ein paar gute Links hinzufügen, die erklären, warum am Ende dieses Beitrags. Verlassen Sie Ihre Funktion wie gewohnt und verwenden Sie APPLY, wie David gezeigt hat, ist der Weg zu gehen. Auch hier ist string_split nicht erforderlich. Wenn Telefonnummern immer in diesem Format kommen: NNN-NNN-NNNN, könnten Sie einfach SUBSTRING verwenden:

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

Für Länder mit varible Länge postleitzahlen im Format (Ortsnetzkennzahl (2 oder mehr Stellen)) -NNN-NNNN Sie dies tun könnte:

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

Wenn Sie aus irgendeinem Grund, braucht wirklich eine Funktion, dann ist dies, wie ich es schreiben würde:

-- 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 

Große Artikel über Scalar UDF und warum iTVFs besser sind:

How to Make Scalar UDFs Run Faster - Jeff Moden

Scalar functions, inlining, and performance - Adam Machanic

TSQL Scalar functions are evil – Andy Irving - Stackoerflow Post

+0

Thanks.It sehr geholfen. –

Verwandte Themen