формула для вычисляемого столбца на основе столбца другой таблицы - PullRequest
45 голосов
/ 05 мая 2010

Рассмотрим эту таблицу: c_const

 code  |  nvalue
 --------------
 1     |  10000
 2     |  20000  

и еще один стол t_anytable

 rec_id |  s_id  | n_code
 ---------------------
 2      |  x     | 1

Цель состоит в том, чтобы s_id был вычисляемым столбцом на основе этой формулы:

 rec_id*(select nvalue from c_const where code=ncode)

Это приводит к ошибке:

Подзапросы не допускаются в этом контексте. Допускаются только скалярные выражения.

Как вычислить значение для этого вычисляемого столбца, используя в качестве входных данных столбец другой таблицы?

Ответы [ 2 ]

71 голосов
/ 05 мая 2010

Вы можете создать пользовательскую функцию для этого:

CREATE FUNCTION dbo.GetValue(@ncode INT, @recid INT)
RETURNS INT
AS 
   SELECT @recid * nvalue 
   FROM c_const 
   WHERE code = @ncode

, а затем используйте его для определения вычисляемого столбца:

ALTER TABLE dbo.YourTable
   ADD NewColumnName AS dbo.GetValue(ncodeValue, recIdValue)
24 голосов
/ 05 мая 2010

Похоже, это больше работа для представлений (индексированные представления, если вам нужен быстрый поиск по вычисляемому столбцу):

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

Это имеет небольшое отличие от версии подзапроса в том, что он возвращает несколько записей вместо того, чтобы выдавать ошибку, если есть несколько результатов для объединения. Но это легко разрешается с помощью ограничения UNIQUE на c_const.code (я подозреваю, что это уже PRIMARY KEY).

Это также намного проще для понимания, чем версия подзапроса.

Вы можете сделать это с помощью подзапроса и UDF, как показал marc_s, но это, вероятно, будет очень неэффективным по сравнению с простым JOIN, поскольку скалярный UDF нужно будет вычислять построчно -строка.

...