Sql-Server

我可以在計算列中使用內置(確定性)SQL 函式,還是需要創建自己的函式作為傳遞來利用它們?

  • December 16, 2019

我試圖在一個表上創建一個(持久的)計算列,它本質上是:YEAR(DateColumn). 當我嘗試在計算列規範的公式中直接呼叫 YEAR() 函式時,我收到 SSMS 錯誤:

驗證列“ComputedColumnYear”的公式時出錯。

您要取消更改嗎?

等效的 T-SQL:

ALTER TABLE CorpIX
ADD ComputedColumnYear AS (YEAR(DateColumn)) PERSISTED;

使用 T-SQL 時出錯:

消息 1759,級別 16,狀態 0,第 41 行表 ‘CorpIX’ 中的計算列 ‘DateColumn’ 不允許在另一個計算列定義中使用。

我通過sys 視圖上的以下查詢驗證了 CorpIX 表沒有計算列:

系統列 1

或者這裡是 Solomon Rutzky 的查詢版本(只是為了顯示該表確實存在,抱歉列混淆):

系統列 2

聽起來它認為 DateColumn 已在計算列中使用,但事實並非如此。我檢查了這個表的 sys.columns 系統視圖,它目前沒有計算列。

我意識到您檢查sys.columns以驗證“DateColumn”是否是一個計算列並且它沒有顯示為一個,所以我推測您正在查看錯誤的表或sys.columns. 我這樣說是因為:

  1. YEAR()您當然可以使用(with or without PERSISTED)添加計算列
  2. 錯誤消息表明問題在於DateColumn已經是計算列,並且您不能在另一個計算列的定義中使用計算列。

簡單的測試表明您可以YEAR在計算列中使用,但是如果您嘗試在另一個計算列中使用計算列,則會得到與現在相同的錯誤:

USE [tempdb];

-- DROP TABLE dbo.CorpIX;
CREATE TABLE dbo.CorpIX
(
 ID INT NOT NULL IDENTITY(1, 1),
 Something NVARCHAR(50) NOT NULL,
 [DateColumn] DATE NOT NULL,
 [NextYear] AS (DATEADD(YEAR, 1, [DateColumn]))
);

ALTER TABLE dbo.CorpIX
ADD [ComputedColumnYear] AS (YEAR([DateColumn])) PERSISTED;
-- Success


ALTER TABLE dbo.CorpIX
ADD [ComputedColumnNextYear] AS (YEAR([NextYear])) PERSISTED;
/*
Msg 1759, Level 16, State 0, Line XXXXX
Computed column 'NextYear' in table 'CorpIX' is not allowed to be used
  in another computed-column definition.
*/

我在 SQL Server 2016 上進行了測試,因為這就是 OP 正在使用的。

要檢查現有的列定義,請使用以下查詢並只需更改OBJECT_ID()函式中的表名(也可能還有模式名):

SELECT col.[name], col.[is_computed], cmp.[definition]
FROM   sys.columns col
LEFT JOIN sys.computed_columns cmp
      ON cmp.[object_id] = col.[object_id]
     AND cmp.[column_id] = col.[column_id]
WHERE  col.[object_id] = OBJECT_ID(N'dbo.CorpIX') -- change to your table name!
ORDER BY col.[column_id];

該查詢將列出表的所有列(這就是我不使用 only 的原因sys.computed_columns)並顯示它們是否被計算,如果計算,它們的定義。

引用自:https://dba.stackexchange.com/questions/255718