В SQL Server можете да създадете скаларна дефинирана от потребителя функция, като използвате CREATE FUNCTION
изявление. Скаларна дефинирана от потребителя функция, известна още като скаларен UDF, е дефинирана от потребителя функция, която връща една стойност.
Тази статия съдържа примери за създаване на някои основни T-SQL скаларни UDF.
Синтаксис
Първо, нека разгледаме синтаксиса за създаване на скаларни UDF.
Синтаксисът за T-SQL скаларни UDF е така:
СЪЗДАЙТЕ [ ИЛИ ПРОМЕНИ ] ФУНКЦИЯ [ име_на_схема. ] име_на_функция ( [ { @parameter_name [ AS ][ type_schema_name. ] parameter_data_type [ =по подразбиране ] [ САМО ЧЕТЕНЕ ] } [ ,...n ] ] ) ВРЪЩА return_data_type [ WITH[ ,...n ] ] [ AS ] BEGIN function_body RETURN скаларен_израз END [; ]
И синтаксисът за CLR скаларни UDFs:
СЪЗДАЙТЕ [ ИЛИ ПРОМЕНИ ] ФУНКЦИЯ [ име_на_схема. ] име_на_функция ( { @parameter_name [AS] [ type_schema_name. ] parameter_data_type [ =default ] } [ ,...n ] ) ВРЪЩА { return_data_type } [ С[ ,...n ] ] [ AS ] ВЪНШНО ИМЕ <метод_спецификатор> [; ]
Частите на <function_option>
за T-SQL функции и <clr_function_option>
за CLR функциите ви позволяват да зададете опции за UDF. Опциите за функции включват добавяне на криптиране, свързване на схема, EXECUTE AS
клауза, както и уточняване какво да се прави, когато се подаде NULL стойност като аргумент.
Пълен списък с аргументи и опции за функции можете да намерите на уебсайта на Microsoft.
Документацията на Microsoft съдържа много подробности, така че следващите примери са насочени към предоставяне на бърз преглед на някои общи концепции и опции при създаване на скаларни UDF.
Пример 1 – Основен скаларен UDF
Ето пример за кода, използван за създаване на основен T-SQL скаларен UDF.
СЪЗДАВАНЕ НА ФУНКЦИЯ dbo.ufn_discountPrice( @price DECIMAL(12,2), @discount DECIMAL(12,2) ) ВРЪЩА DECIMAL (12,2) КАТО ЗАПОЧВА ВРЪЩАНЕ @price * (1 - @discount);END;предварително>Този скаларен UDF приема два параметъра;
@price
и@discount
. Те се предават на функцията като аргументи при всяко извикване на функцията. Функцията взема стойността на тези аргументи, извършва изчисление, използвайки тези стойности, след което връща получената стойност. В този случай намалената цена се връща.Пример 2 – Извикване на UDF
След като UDF бъде създаден, той може да бъде извикан в T-SQL код по всяко време, когато имате нужда от него.
Ето пример за извикване на UDF:
ИЗБЕРЕТЕ dbo.ufn_discountPrice(100, .2) КАТО резултат;Резултат
+---------+| Резултат ||----------|| 80,00 |+----------+Пример 3 – Запитване на таблица
Скаларните UDF могат също да правят неща като заявки за таблици на база данни.
Ето един, който връща броя на албумите в базата данни за даден изпълнител.
СЪЗДАВАНЕ НА ФУНКЦИЯ dbo.ufn_CountAlbums (@ArtistId int) ВРЪЩА smallintAS BEGIN DECLARE @AlbumCount int; ИЗБЕРЕТЕ @AlbumCount =COUNT(AlbumId) ОТ Албуми WHERE ArtistId =@ArtistId; ВРЪЩАНЕ @AlbumCount;END;Това е скаларна функция, защото връща една стойност. Ако искаме да върнем списък с албуми, тогава ще трябва да използваме функция с таблично значение, тъй като функциите с таблична стойност връщат нейните резултати като набор от редове.
Пример 4 – Обвързване на схема
Когато създавате дефинирана от потребителя функция, която зависи от други обекти в базата данни, обикновено е добра идея да обвържете UDF по схема. Обвързването на схемата на UDF гарантира, че не могат да се правят промени в основните обекти, които биха могли да повлияят потенциално на функцията.
Например, не бихте могли да пуснете таблица, която UDF, обвързан със схема, използва в своята дефиниция.
За да свържете схематично UDF, използвайте
WITH SCHEMABINDING
в неговата дефиниция. Също така трябва да използвате имена от две части за всички обекти, които са препратки в UDF.Ето предишния пример, пренаписан така, че да е обвързан със схема:
СЪЗДАВАНЕ НА ФУНКЦИЯ dbo.ufn_CountAlbums (@ArtistId int) ВРЪЩА smallintWITH SCHEMABINDINGAS BEGIN DECLARE @AlbumCount int; ИЗБЕРЕТЕ @AlbumCount =COUNT(AlbumId) ОТ dbo.Albums WHERE ArtistId =@ArtistId; ВРЪЩАНЕ @AlbumCount;END;И така, промених две неща от първия пример. Добавих
WITH SCHEMABINDING
, и променихAlbums
къмdbo.Albums
.Сега, ако някой се опита да изхвърли тази таблица или да направи други промени в нея, ще получи грешка.
Пример 5 – Шифроване
Можете също да използвате
WITH ENCRYPTION
за криптиране на функцията.СЪЗДАВАНЕ НА ФУНКЦИЯ dbo.ufn_CountAlbums (@ArtistId int) ВРЪЩА smallintWITH ENCRYPTIONAS BEGIN DECLARE @AlbumCount int; ИЗБЕРЕТЕ @AlbumCount =COUNT(AlbumId) ОТ dbo.Albums WHERE ArtistId =@ArtistId; ВРЪЩАНЕ @AlbumCount;END;Пример 6 – NULL вход
При извикване на функцията, ако някой от аргументите е NULL, тялото на функцията все още се изпълнява. Това е, освен ако не сте посочили изрично
RETURNS NULL ON NULL INPUT
в дефиницията на функцията.Посочването на тази опция ще върне NULL, ако някой от аргументите е NULL.
СЪЗДАВАНЕ НА ФУНКЦИЯ dbo.ufn_CountAlbums (@ArtistId int) ВРЪЩА smallintWITH ВРЪЩА NULL НА NULL INPUTAS BEGIN DECLARE @AlbumCount int; ИЗБЕРЕТЕ @AlbumCount =COUNT(AlbumId) ОТ dbo.Albums WHERE ArtistId =@ArtistId; ВРЪЩАНЕ @AlbumCount;END;Когато извикам функцията, използвайки NULL като аргумент:
ИЗБЕРЕТЕ dbo.ufn_CountAlbums(NULL) КАТО резултат;Получавам различен резултат, в зависимост от това, което съм посочил за тази опция.
Ето резултата, когато функцията използва настройката по подразбиране (
CALLED ON NULL INPUT
):+---------+| Резултат ||----------|| 0 |+---------+И ето резултата, когато използва
RETURNS NULL ON NULL INPUT
:+---------+| Резултат ||----------|| NULL |+----------+Пример 7 – Множество опции
Можете да разделите няколко опции със запетая.
Ето пример, който добавя както криптиране, така и свързване на схема към функцията:
СЪЗДАВАНЕ НА ФУНКЦИЯ dbo.ufn_CountAlbums (@ArtistId int) ВРЪЩА smallintС ШИФИРАНЕ, СХЕМА ЗА СВЪРЗВАНЕ ЗАПОЧВА ДЕКЛАРИРАНЕ @AlbumCount int; ИЗБЕРЕТЕ @AlbumCount =COUNT(AlbumId) ОТ dbo.Albums WHERE ArtistId =@ArtistId; ВРЪЩАНЕ @AlbumCount;END;Пример 8 – Промяна на функция
Можете да промените скаларен UDF, като замените
CREATE
сALTER
.ALTER FUNCTION dbo.ufn_CountAlbums (@ArtistId int) ВРЪЩА smallintWITH SCHEMABINDINGAS BEGIN DECLARE @AlbumCount int; ИЗБЕРЕТЕ @AlbumCount =COUNT(AlbumId) ОТ dbo.Albums WHERE ArtistId =@ArtistId; ВРЪЩАНЕ @AlbumCount;END;