Широко известно ограничение на изчислените колони в SQL Server е, че те нямат достъп до данни от други таблици. Тоест вашият израз може да използва колони в същата таблица, но не и от други таблици.
Но това е само наполовина вярно. Въпреки че не можете да препращате колона на друга таблица директно във вашия израз, вие можете извикване на дефинирана от потребителя функция. И следователно можете да създадете дефинирана от потребителя функция, която извършва изчислението, от което се нуждаете, след което просто да извикате тази функция като израз на вашата изчислена колона.
Ето пример за демонстрация.
Примерни таблици
Имам база данни със следните таблици:
SELECT TOP(5) * FROM Artists; +------------+------------------+--------------+-------------+ | ArtistId | ArtistName | ActiveFrom | CountryId | |------------+------------------+--------------+-------------| | 1 | Iron Maiden | 1975-12-25 | 3 | | 2 | AC/DC | 1973-01-11 | 2 | | 3 | Allan Holdsworth | 1969-01-01 | 3 | | 4 | Buddy Rich | 1919-01-01 | 6 | | 5 | Devin Townsend | 1993-01-01 | 8 | +------------+------------------+--------------+-------------+ SELECT TOP(5) * FROM Albums; +-----------+------------------------+---------------+------------+-----------+ | AlbumId | AlbumName | ReleaseDate | ArtistId | GenreId | |-----------+------------------------+---------------+------------+-----------| | 1 | Powerslave | 1984-09-03 | 1 | 1 | | 2 | Powerage | 1978-05-05 | 2 | 1 | | 3 | Singing Down the Lane | 1956-01-01 | 6 | 3 | | 4 | Ziltoid the Omniscient | 2007-05-21 | 5 | 1 | | 5 | Casualties of Cool | 2014-05-14 | 5 | 1 | +-----------+------------------------+---------------+------------+-----------+
Тези таблици всъщност съдържат повече от 5 реда. Избрах горните 5 реда, така че да получите картината на данните и структурата на таблицата.
Сега си представете, че искам да добавя изчислена колона към първата таблица.
Искам изчислената колона да предоставя броя на албумите от всеки изпълнител. С други думи, трябва ми, за да преброя албумите в другата таблица – Albums
таблица.
Виждайки, че данните са в друга таблица, не мога да ги препращам директно от изчислена колона. Но вместо това мога да създам дефинирана от потребителя функция и да препращам към тази функция от изчислената си колона.
Създайте функцията
Ето една проста функция, която отчита броя на албумите от даден изпълнител:
CREATE FUNCTION [dbo].[ufn_AlbumCount] (@ArtistId int) RETURNS smallint AS BEGIN DECLARE @AlbumCount int; SELECT @AlbumCount = COUNT(AlbumId) FROM Albums WHERE ArtistId = @ArtistId; RETURN @AlbumCount; END; GO
Създайте изчислената колона
Сега, след като създадох функцията, мога да добавя изчислена колона, която я препраща.
ALTER TABLE Artists ADD AlbumCount AS dbo.ufn_AlbumCount(ArtistId);
Тествайте изчислената колона
Сега мога да изпълня заявка към Artists
таблица, за да видите резултата от моята изчислена колона:
SELECT TOP(10) * FROM Artists;
Резултат:
+------------+------------------+--------------+-------------+--------------+ | ArtistId | ArtistName | ActiveFrom | CountryId | AlbumCount | |------------+------------------+--------------+-------------+--------------| | 1 | Iron Maiden | 1975-12-25 | 3 | 5 | | 2 | AC/DC | 1973-01-11 | 2 | 3 | | 3 | Allan Holdsworth | 1969-01-01 | 3 | 2 | | 4 | Buddy Rich | 1919-01-01 | 6 | 1 | | 5 | Devin Townsend | 1993-01-01 | 8 | 3 | | 6 | Jim Reeves | 1948-01-01 | 6 | 1 | | 7 | Tom Jones | 1963-01-01 | 4 | 3 | | 8 | Maroon 5 | 1994-01-01 | 6 | 0 | | 9 | The Script | 2001-01-01 | 5 | 1 | | 10 | Lit | 1988-06-26 | 6 | 0 | +------------+------------------+--------------+-------------+--------------+
Индексиране
Можете да използвате изчислената колона в индекс само ако дефинираната от потребителя функция, която извиква, има следните стойности на свойствата:
- Едетерминистично =вярно
- SystemVerified =true (освен ако изчислената колона не е запазена)
- UserDataAccess =невярно
- SystemDataAccess =невярно