1、計算列web
一、概念正則表達式
計算列由可使用同一表中的其餘列的表達式計算得來。表達式能夠是非計算列的列名、常量、函數,也能夠是用一個或多個運算符鏈接的上述元素的任意組合。表達式不能爲子查詢。數據庫
通常在寫SQL的時候應該避免在條件中使用函數,由於這樣就不能有效的使用索引,從而沒法生成高效的執行計劃。SQL Server提供了計算列能夠幫助咱們解決這個問題。 express
例如,某查詢對大小寫敏感,但願查詢某列所有轉爲小寫,若是程序設計時沒有考慮到,那麼須要在查詢的時候就必需要強制轉化。 select * from table1 where lower(column1) = 'abc'ide
計算列可用於選擇列表、WHERE 子句、ORDER BY 子句或任何可以使用正則表達式的其餘位置,但下列狀況除外:函數
(1)用做 CHECK、FOREIGN KEY 或 NOT NULL 約束的計算列必須標記爲 PERSISTED。若是計算列的值由具備肯定性的表達式定義,而且索引列中容許使用計算結果的數據類型,則可將該列用做索引中的鍵列,或者用做 PRIMARY KEY 或 UNIQUE 約束的一部分。優化
(2)計算列不能做爲 INSERT 或 UPDATE 語句的目標。spa
數據庫引擎基於使用的表達式自動肯定計算列的爲 Null 性。即便只有非空列,大多數表達式的結果也「認爲」可爲空值,由於下溢或溢出生成的結果也可能爲空。經過指定 ISNULL (check_expression,constant) 能夠將可爲空值的表達式轉換爲不可爲空值的表達式,其中, constant 是可替換全部空結果的非空值. 設計
二、建立計算列orm
CREATE TABLE t2 (a int, b int, c int, x float, y AS CASE x WHEN 0 THEN a WHEN 1 THEN b ELSE c END) |
三、建立持久化計算列
若是不使用PERSISTED 關鍵字,計算列是未實際存儲在表中的虛擬列。每當在查詢中引用計算列時,都將從新計算它們的值。
使用PERSISTED 關鍵字計算列實際存儲在表中。若是在計算列的計算更改時涉及任何列,將更新計算列的值。
2、爲計算列建立索引的限制條件
1. 全部權
計算列中的全部函數引用必須與表具備相同的全部者。
2. 肯定性
若是對於一組指定的輸入表達式始終返回相同的結果,則說明表達式具備肯定性。
computed_column_expression 必須具備肯定性。若是下列一項或多項爲真,則 computed_column_expression 具備肯定性:
(1)表達式引用的全部函數都具備肯定性,而且是精確的。這些函數包括用戶定義函數和內置函數。若是計算列是 PERSISTED,則函數可能不精確。
(2)表達式引用的全部列都來自包含計算列的表。
(3)沒有列引用從多行中請求數據。例如,聚合函數(如 SUM 或 AVG)依靠來自多行的數據,這使 computed_column_expression 具備不肯定性。
(4)沒有系統數據訪問或用戶數據訪問。
任何包含公共語言運行時 (CLR) 表達式的計算列都必須具備肯定性並標記爲 PERSISTED,這樣才能爲該列建立索引。容許在計算列定義中使用 CLR 用戶定義類型的表達式。類型爲 CLR 用戶定義類型的計算列只要其類型是可比較的,就能夠在該列上建立索引。
3. 精度
computed_column_expression 必須精確。若是下列一項或多項爲真,則 computed_column_expression 是精確的:
(1)表達式的數據類型不是 float 或 real。
(2)表達式定義中沒有使用 float 或 real 數據類型。
任何 float 或 real 表達式都被認爲是不精確的,不能做爲索引鍵;float 或 real 表達式能夠在索引視圖中使用,但不能做爲鍵使用。對於計算列一樣如此。若是任何函數、表達式或用戶定義函數包含任何 float 或 real 表達式,則被認爲是不精確的。這也包括邏輯表達式(比較)。
若是計算列使用肯定性但不精確的表達式定義,但在 CREATE TABLE 或 ALTER TABLE 語句中標記爲 PERSISTED,則能夠在該列上建立索引。這意味着數據庫引擎在表中存儲計算值,而且在計算列所依賴的任何其餘列發生更新時更新這些值。若是數據庫引擎對列建立了索引而且該索引由某查詢引用,則會使用這些持久值。當數據庫引擎不能準確證實返回計算列表達式的函數(特別是在 .NET Framework 中建立的 CLR 函數)是否既具備肯定性又精確時,使用此選項能夠對計算列建立索引。
4. 數據類型
數據類型要求以下:
(1)爲計算列定義的 computed_column_expression 的值不能爲 text、ntext 或 p_w_picpath 數據類型。
(2)只要計算列的數據類型能夠做爲索引鍵列,從 p_w_picpath、ntext、text、varchar(max)、nvarchar(max)、varbinary(max) 和 xml 數據類型派生的計算列上就能夠建立索引。
(3)只要計算列的數據類型能夠做爲非鍵索引列,從 p_w_picpath、ntext 和 text 數據類型派生的計算列就能夠做爲非彙集索引中的非鍵(包含性)列。
5. SET選項
SET 選項要求以下:
(1)執行定義計算列的 CREATE TABLE 或 ALTER TABLE 語句時,必須將 ANSI_NULLS 鏈接級選項設置爲 ON。
(2)對於在其中建立索引的鏈接和全部嘗試執行 INSERT、UPDATE 或 DELETE 語句(將更改索引中的值)的鏈接,必須將六個 SET 選項(ANSI_NULLS、ANSI_PADDING、ANSI_WARNINGS、ARITHABORT、CONCAT_NULL_YIELDS_NULL、QUOTED_IDENTIFIER)設置爲 ON,將一個選項(NUMERIC_ROUNDABORT)設置爲 OFF。若是不具備上述選項設置的鏈接執行了任何 SELECT 語句,優化器將忽略計算列的索引。
(3)當數據庫兼容級別設置爲 90 時,若是 ANSI_WARNINGS 設置爲 ON,則會將 ARITHABORT 隱式設置爲 ON。若是數據庫兼容級別設置爲 80 或更低,則必須將 ARITHABORT 選項顯式設置爲 ON。
本文結語:
須要頻繁訪問的計算列能夠考慮持久化。當計算列爲肯定性且精確,或肯定性、不精確、持久化時,能夠建立索引。