En allmänt känd begränsning av beräknade kolumner i SQL Server är att de inte kan komma åt data från andra tabeller. Det vill säga, ditt uttryck kan använda kolumner i samma tabell, men inte från andra tabeller.
Men detta är bara halvt sant. Även om du inte kan referera till en annan tabells kolumn direkt i ditt uttryck, kan anropa en användardefinierad funktion. Och därför kan du skapa en användardefinierad funktion som utför den beräkning du behöver och sedan helt enkelt kalla den funktionen som din beräknade kolumns uttryck.
Här är ett exempel att visa.
Exempeltabeller
Jag har en databas med följande tabeller:
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 | +-----------+------------------------+---------------+------------+-----------+
Dessa tabeller innehåller faktiskt mer än 5 rader. Jag har valt de 5 översta raderna så att du får bilden av data och tabellstruktur.
Föreställ dig nu att jag vill lägga till en beräknad kolumn i den första tabellen.
Jag vill att den beräknade kolumnen ska visa antalet album från varje artist. Med andra ord, jag behöver den för att räkna albumen i den andra tabellen – Albums
bord.
Eftersom data finns i en annan tabell kan jag inte referera till den direkt från en beräknad kolumn. Men jag kan skapa en användardefinierad funktion istället och referera till den funktionen från min beräknade kolumn.
Skapa funktionen
Här är en enkel funktion som räknar antalet album från en given artist:
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
Skapa den beräknade kolumnen
Nu när jag har skapat funktionen kan jag lägga till en beräknad kolumn som refererar till den.
ALTER TABLE Artists ADD AlbumCount AS dbo.ufn_AlbumCount(ArtistId);
Testa den beräknade kolumnen
Nu kan jag köra en fråga mot Artists
tabell för att se resultatet av min beräknade kolumn:
SELECT TOP(10) * FROM Artists;
Resultat:
+------------+------------------+--------------+-------------+--------------+ | 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 | +------------+------------------+--------------+-------------+--------------+
Indexering
Du kan bara använda den beräknade kolumnen i ett index om den användardefinierade funktionen som den anropar har följande egenskapsvärden:
- Är deterministisk =sant
- IsSystemVerified =sant (såvida inte den beräknade kolumnen finns kvar)
- UserDataAccess =falskt
- SystemDataAccess =falskt