В повечето случаи е най-добре да избягвате функциите със скаларна стойност, които препращат към таблици, защото (както други казаха) те са основно черни кутии, които трябва да се изпълняват веднъж за всеки ред и не могат да бъдат оптимизирани от механизма за план на заявки. Следователно те са склонни да се мащабират линейно, дори ако свързаните таблици имат индекси.
Може да искате да обмислите използването на функция със стойност на вградена таблица, тъй като те се оценяват в рамките на заявката и могат да бъдат оптимизирани. Получавате капсулирането, което искате, но ефективността на поставяне на изразите точно в оператора select.
Като страничен ефект от това, че са вградени, те не могат да съдържат никакъв процедурен код (без деклариране на @variable; set @variable =..; return). Те обаче могат да върнат няколко реда и колони.
Можете да пренапишете функциите си по следния начин:
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
);
Синтаксисът за използването им също е малко по-различен:
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)