Een algemeen bekende beperking van berekende kolommen in SQL Server is dat ze geen toegang hebben tot gegevens uit andere tabellen. Dat wil zeggen, uw expressie kan kolommen in dezelfde tabel gebruiken, maar niet uit andere tabellen.
Maar dit is maar half waar. Hoewel u niet rechtstreeks kunt verwijzen naar de kolom van een andere tabel in uw uitdrukking, kunt u wel een door de gebruiker gedefinieerde functie aanroepen. En daarom zou je een door de gebruiker gedefinieerde functie kunnen maken die de berekening uitvoert die je nodig hebt, en die functie dan gewoon aanroepen als de uitdrukking van je berekende kolom.
Hier is een voorbeeld om te demonstreren.
Voorbeeldtabellen
Ik heb een database met de volgende tabellen:
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 | +-----------+------------------------+---------------+------------+-----------+
Deze tabellen bevatten eigenlijk meer dan 5 rijen. Ik heb de bovenste 5 rijen geselecteerd, zodat u een beeld krijgt van de gegevens- en tabelstructuur.
Stel je nu voor dat ik een berekende kolom aan de eerste tabel wil toevoegen.
Ik wil dat de berekende kolom het aantal albums van elke artiest bevat. Met andere woorden, ik heb het nodig om de albums in de andere tabel te tellen - de Albums
tafel.
Aangezien de gegevens in een andere tabel staan, kan ik er niet rechtstreeks vanuit een berekende kolom naar verwijzen. Maar ik kan in plaats daarvan een door de gebruiker gedefinieerde functie maken en naar die functie verwijzen vanuit mijn berekende kolom.
Maak de functie
Hier is een eenvoudige functie die het aantal albums van een bepaalde artiest telt:
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
Maak de berekende kolom
Nu ik de functie heb gemaakt, kan ik een berekende kolom toevoegen die ernaar verwijst.
ALTER TABLE Artists ADD AlbumCount AS dbo.ufn_AlbumCount(ArtistId);
Test de berekende kolom
Nu kan ik een query uitvoeren op de Artists
tabel om het resultaat van mijn berekende kolom te zien:
SELECT TOP(10) * FROM Artists;
Resultaat:
+------------+------------------+--------------+-------------+--------------+ | 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 | +------------+------------------+--------------+-------------+--------------+
Indexeren
U kunt de berekende kolom alleen in een index gebruiken als de door de gebruiker gedefinieerde functie die wordt aangeroepen de volgende eigenschapswaarden heeft:
- IsDeterministisch =waar
- IsSystemVerified =waar (tenzij de berekende kolom behouden blijft)
- Gebruikersgegevenstoegang =onwaar
- SystemDataAccess =onwaar