SQL SERVER 创建计算列

本文介绍了如何在SQL Server中使用计算列,包括非持久化及持久化计算列的区别。通过示例展示了如何创建计算列以及使用PERSISTED选项来存储计算结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在CREATE TABLE或ALTER TABLE语句中定义的列可以源于独立的或者基于列的计算。如果需要在相关查询中对相同的数据重复计算,则计算列就变得很有用。计算列以创建表或修改表的时候定义的表达式为基础,除非使用了PERSISTED关键字,否则计算列不会物理保存在表中。

在这个技巧中,我会给出创建计算列的演示,并且介绍使用SQL Server 2005的PERSISTED选项的方法。通过CREATE或ALTER TABLE增加一个计算列的语法如下:

alert table table_name
add column_name AS computed_column_expression [PERSISTED]

column_name是新列的名字。computed_column_expression是你为了得到列的值而执行的计算。增加PERSISTED关键字能让计算的结果被物理保存。

示例1:
ALTER TABLE Production.TransactionHistory  
ADD CostPerUnit AS (ActualCost/Quantity) 

示例2:
ALTER TABLE Production.TransactionHistory  
ADD CostPerUnit AS (ActualCost/Quantity)  PERSISTED

解析:
第一个示例向Production.TransactionHistory表添加了一个名为CostPerUnit的非持久化列,使它在SELECT查询中能像普通表列那样被引用:
ADD CostPerUnit AS (ActualCost/Quantity) 
计算列不能用DEFAULT或者FOREIGN KEY约束。计算列不能被显式更新或插入(因为它的值都是计算出的)。
计算列能用在索引中,但是一定要符合一些条件。比如是确定的(对于一组给定的输入总是返回相同的结果)和精确的(不包含浮点值)。

第二个示例演示了在CREATE TABLE命令中使用计算列:
AvgSharesPerShareholder AS (SharesOutStanding/Shareholders) PERSISTED 
和第一个示例不同,增加了PERSISTED意味着数据被物理地保存在数据库中。对计算中使用的列进行的任何修改都会引起存储值的再一次更新。但是保存的数据仍然不可以直接修改--数据仍然要经过计算。然而和非持久化的方式不同,保存数据意味着列能用于表分区(请参阅4.7.1节的"实现表分区"技巧)或者非精确(基于浮点)值的索引。
### 如何在 SQL Server创建和使用计算 #### 创建计算的方法 在 SQL Server 中,可以通过两种方式定义计算:一种是在设计表结构时通过 **SQL Server Management Studio (SSMS)** 的图形界面完成;另一种是通过编写 **Transact-SQL** 脚本实现。 1. **通过 SSMS 图形界面** 在 SSMS 中新建或修改一张表时,在“属性”的部分找到名为“计算所得的规范”选项卡。在此处输入用于计算值的公式即可[^2]。例如,如果希望基于 `Price` 和 `TaxRate` 动态生成一表示商品总价格,则可以在公式框中填入 `(Price * TaxRate)` 表达式。 2. **通过 T-SQL 命令** 下面展示了一个具体的例子说明如何利用 T-SQL 来新增加一个计算字段到现有表格里: ```sql ALTER TABLE Products ADD TotalCost AS (UnitPrice * Quantity); ``` 上述语句向 `Products` 表添加了一名叫做 `TotalCost` 的新成员,它并不真正占用物理空间而是依据每条记录里的 `UnitPrice` 乘以 `Quantity` 得出的结果作为显示内容[^1]。 #### 使用持久化(Persisted)提高性能 为了提升查询效率或者支持建立索引等功能需求,可以选择将某些频繁访问又耗时较长运算得出的数据项设置成持久化的状态存储下来而不是每次重新演算出来。这可通过扩展前面提到过的语法形式达成目标: ```sql ALTER TABLE Products ADD TotalCost AS (UnitPrice * Quantity) PERSISTED; ``` 这里的关键字 `PERSISTED` 就是用来指示数据库引擎把每一次更新后的最终数值实际写回到磁盘上去保存起来以便后续更快读取。 #### 关于索引的支持情况 值得注意的是,并不是所有的计算都能够被赋予索引对象。只有那些满足特定条件——比如确定性和精确性的函数所构成的表达式的计算才允许创建相应的索引结构来进一步优化检索速度等问题解决办法[^4]。 ### 示例代码片段 下面给出一段完整的示范程序用来演示整个过程从头至尾的操作步骤: ```sql -- Step 1: Create a sample table without computed column initially. CREATE TABLE Orders ( OrderID INT PRIMARY KEY, UnitPrice MONEY NOT NULL, Quantity SMALLINT NOT NULL ); -- Step 2: Add the computed column 'TotalAmount'. ALTER TABLE Orders ADD TotalAmount AS (UnitPrice * Quantity); -- Optional step: If you want to persist this value physically within your storage system. ALTER TABLE Orders DROP COLUMN IF EXISTS PersistedTotalAmount; -- Ensure no duplicate columns exist before altering again. GO ALTER TABLE Orders ADD PersistedTotalAmount AS (UnitPrice * Quantity) PERSISTED; -- Insert some test data into our orders table now that everything is set up properly. INSERT INTO Orders(OrderID, UnitPrice, Quantity) VALUES(101, CAST('99.99' AS MONEY), 5), (102, CAST('75.00' AS MONEY), 3); SELECT * FROM Orders; ``` 以上脚本首先构建了一个简单的订单表模型不含任何预先设定好的合计金额项目接着再分别追加上去两个版本一个是普通的即时求解型另一个则是经过持久处理之后的形式最后还插入了几笔模拟交易数据供验证查看效果之用。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值