Considérez ce tableau: c_const
code | nvalue
--------------
1 | 10000
2 | 20000
et une autre table t_anytable
rec_id | s_id | n_code
---------------------
2 | x | 1
Le but est d'avoir s_id
être une colonne calculée, basée sur cette formule:
rec_id*(select nvalue from c_const where code=ncode)
Cela produit une erreur:
Les sous-requêtes ne sont pas autorisées dans ce contexte. Seules les expressions scalaires sont autorisées.
Comment puis-je calculer la valeur de cette colonne calculée en utilisant la colonne d'une autre table comme entrée?
Vous pouvez créer une fonction définie par l'utilisateur pour cela:
CREATE FUNCTION dbo.GetValue(@ncode INT, @recid INT)
RETURNS INT
AS
SELECT @recid * nvalue
FROM c_const
WHERE code = @ncode
puis utilisez-le pour définir votre colonne calculée:
ALTER TABLE dbo.YourTable
ADD NewColumnName AS dbo.GetValue(ncodeValue, recIdValue)
Cela semble être plus un travail pour les vues (vues indexées, si vous avez besoin de recherches rapides sur la colonne calculée):
CREATE VIEW AnyView
WITH SCHEMABINDING
AS
SELECT a.rec_id, a.s_id, a.n_code, a.rec_id * c.nvalue AS foo
FROM AnyTable a
INNER JOIN C_Const c
ON c.code = a.n_code
Cela présente une différence subtile par rapport à la version de sous-requête en ce sens qu'elle retournerait plusieurs enregistrements au lieu de produire une erreur s'il y a plusieurs résultats pour la jointure. Mais cela est facilement résolu avec une contrainte UNIQUE
sur c_const.code
(Je soupçonne que c'est déjà un PRIMARY KEY
).
C'est aussi beaucoup plus facile à comprendre pour quelqu'un que la version de sous-requête.
Vous pouvez le faire avec une sous-requête et une UDF comme l'a montré marc_s, mais cela risque d'être fortement inefficace par rapport à un simple JOIN
, car une UDF scalaire devra être calculée en ligne- par rangée.