Powszechnie znanym ograniczeniem kolumn obliczanych w SQL Server jest to, że nie mają dostępu do danych z innych tabel. Oznacza to, że Twoje wyrażenie może używać kolumn w tej samej tabeli, ale nie z innych tabel.
Ale to tylko w połowie prawda. Chociaż nie możesz odwoływać się do kolumny innej tabeli bezpośrednio w swoim wyrażeniu, możesz wywołać funkcję zdefiniowaną przez użytkownika. Dlatego możesz utworzyć funkcję zdefiniowaną przez użytkownika, która wykonuje potrzebne obliczenia, a następnie po prostu wywołać tę funkcję jako wyrażenie kolumny wyliczanej.
Oto przykład do zademonstrowania.
Przykładowe tabele
Mam bazę danych z następującymi tabelami:
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 | +-----------+------------------------+---------------+------------+-----------+
Te tabele faktycznie zawierają więcej niż 5 wierszy. Wybrałem 5 górnych wierszy, aby uzyskać obraz struktury danych i tabeli.
Teraz wyobraź sobie, że chcę dodać obliczoną kolumnę do pierwszej tabeli.
Chcę, aby kolumna wyliczona zawierała liczbę albumów każdego wykonawcy. Innymi słowy, potrzebuję go do policzenia albumów w drugiej tabeli – Albums
tabela.
Ponieważ dane znajdują się w innej tabeli, nie mogę odwoływać się do nich bezpośrednio z kolumny wyliczanej. Ale zamiast tego mogę utworzyć funkcję zdefiniowaną przez użytkownika i odwołać się do tej funkcji z mojej obliczonej kolumny.
Utwórz funkcję
Oto prosta funkcja zliczająca liczbę albumów danego wykonawcy:
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
Utwórz kolumnę obliczeniową
Teraz, po utworzeniu funkcji, mogę dodać kolumnę obliczeniową, która się do niej odwołuje.
ALTER TABLE Artists ADD AlbumCount AS dbo.ufn_AlbumCount(ArtistId);
Przetestuj kolumnę obliczeniową
Teraz mogę uruchomić zapytanie względem Artists
tabela, aby zobaczyć wynik mojej obliczonej kolumny:
SELECT TOP(10) * FROM Artists;
Wynik:
+------------+------------------+--------------+-------------+--------------+ | 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 | +------------+------------------+--------------+-------------+--------------+
Indeksowanie
Kolumny wyliczanej w indeksie można używać tylko wtedy, gdy wywołana przez nią funkcja zdefiniowana przez użytkownika ma następujące wartości właściwości:
- Jest deterministyczny =prawda
- Zweryfikowano system =true (chyba że obliczona kolumna jest utrwalona)
- Dostęp do danych użytkownika =fałsz
- Dostęp do danych systemowych =fałsz