I de flesta fall är det bäst att undvika skalära funktioner som refererar till tabeller eftersom de (som andra sa) i princip är svarta rutor som måste köras en gång för varje rad och inte kan optimeras av frågeplansmotorn. Därför tenderar de att skala linjärt även om de associerade tabellerna har index.
Du kanske vill överväga att använda en inline-tabellvärderad funktion, eftersom de utvärderas inline med frågan och kan optimeras. Du får den inkapsling du vill ha, men prestanda för att klistra in uttrycken direkt i select-satsen.
Som en bieffekt av att vara infogade kan de inte innehålla någon procedurkod (ingen declare @variable; set @variable =..; return). Däremot kan de returnera flera rader och kolumner.
Du kan skriva om dina funktioner ungefär så här:
create function usf_GIS_GET_LAT(
@City varchar (30),
@State char (2)
)
returns table
as return (
select top 1 lat
from GIS_Location with (nolock)
where [State] = @State
and [City] = @City
);
GO
create function usf_GIS_GET_LON (
@City varchar (30),
@State char (2)
)
returns table
as return (
select top 1 LON
from GIS_Location with (nolock)
where [State] = @State
and [City] = @City
);
Syntaxen för att använda dem är också lite annorlunda:
select
Lat.Lat,
Lon.Lon
from
Address_Location with (nolock)
cross apply dbo.usf_GIS_GET_LAT(City,[State]) AS Lat
cross apply dbo.usf_GIS_GET_LON(City,[State]) AS Lon
WHERE
ID IN (SELECT TOP 100 ID FROM Address_Location WITH(NOLOCK) ORDER BY ID DESC)