Uma limitação amplamente conhecida das colunas computadas no SQL Server é que elas não podem acessar dados de outras tabelas. Ou seja, sua expressão pode usar colunas na mesma tabela, mas não em outras tabelas.
Mas isso é apenas meia verdade. Embora você não possa referenciar a coluna de outra tabela diretamente em sua expressão, você pode invocar uma função definida pelo usuário. E, portanto, você pode criar uma função definida pelo usuário que executa o cálculo que você precisa e, em seguida, basta chamar essa função como a expressão da sua coluna computada.
Aqui está um exemplo para demonstrar.
Tabelas de amostra
Tenho um banco de dados com as seguintes tabelas:
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 | +-----------+------------------------+---------------+------------+-----------+
Essas tabelas, na verdade, contêm mais de 5 linhas. Selecionei as 5 principais linhas para que você tenha uma visão geral dos dados e da estrutura da tabela.
Agora, imagine que eu queira adicionar uma coluna computada à primeira tabela.
Quero que a coluna computada forneça o número de álbuns de cada artista. Em outras palavras, preciso contar os álbuns na outra tabela - os
Albums
tabela. Visto que os dados estão em outra tabela, não posso referenciá-los diretamente de dentro de uma coluna computada. Mas posso criar uma função definida pelo usuário e fazer referência a essa função de dentro da minha coluna computada.
Criar a função
Aqui está uma função simples que conta o número de álbuns de um determinado artista:
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
Criar a coluna computada
Agora que criei a função, posso adicionar uma coluna computada que a referencia.
ALTER TABLE Artists ADD AlbumCount AS dbo.ufn_AlbumCount(ArtistId);
Testar a coluna calculada
Agora posso executar uma consulta nos
Artists
table para ver o resultado da minha coluna computada:SELECT TOP(10) * FROM Artists;
Resultado:
+------------+------------------+--------------+-------------+--------------+ | 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 | +------------+------------------+--------------+-------------+--------------+
Indexação
Você só pode usar a coluna computada em um índice se a função definida pelo usuário que ela invoca tiver os seguintes valores de propriedade:
- ÉDeterminístico =verdadeiro
- IsSystemVerified =true (a menos que a coluna computada persista)
- UserDataAccess =falso
- SystemDataAccess =falso