In this article, we will explore computed columns in SQL Server and their configurations.

在本文中,我们将探讨SQL Server中的计算列及其配置。

介绍 (Introduction)

Suppose you have an [Orders] table and it holds the information about orders placed by the customers for an online shopping portal.

假设您有一个[Orders]表,它包含有关客户为在线购物门户下的订单的信息。

You have different tax slabs for the different products, and you require a column in your table that has the amount for each order after adding required taxes. In this case, you can utilize computed columns in SQL Server.

对于不同的产品,您有不同的税率标准,并且您需要在表中的一列中添加每笔订单的税额,然后加上所需的税额。 在这种情况下,您可以利用SQL Server中的计算列。

Similarly, in another example of [Employee] table, we have a DOB for each employee. We need a computed column to show [Age] of the employee.

同样,在[Employee]表的另一个示例中,我们为每个员工都有一个DOB。 我们需要一个计算列来显示员工的[年龄]。

A computed column in SQL Server is a virtual column that computes its values from an expression. We can use a constant value, function, value derived from other columns, non-computed column name, or their combinations.

SQL Server中的计算列是一个虚拟列,它根据表达式计算其值。 我们可以使用常量值,函数,从其他列派生的值,未计算的列名或其组合。

SQL Server does not store these virtual columns physically, so it does not require any storage. We can store these columns physically as well using PERSISTED property if required. If we mark a computed column as persisted, we can define constraints such as Check, Not NULL, or Foreign key. It also allows you to define an index for the persisted computed column.

SQL Server不会物理存储这些虚拟列,因此不需要任何存储。 如果需要,我们还可以使用PERSISTED属性来物理存储这些列。 如果将计算列标记为持久列,则可以定义约束,例如Check,Not NULL或Foreign key。 它还允许您为持久化的计算列定义索引。

Let’s create a new table using the SSMS table designer wizard. Expand Databases -> right-click on Tables and navigate to New -> Table:

让我们使用SSMS表设计器向导创建一个新表。 展开数据库 ->右键单击表格 ,然后导航到新建 -> 表格

In the above image, the table shows multiple columns and their data types. We have defined a primary key and identity column on the [EmpID] column.

在上图中,该表显示了多个列及其数据类型。 我们在[EmpID]列上定义了一个主键和标识列。

Add a new column [Age]. In this column, do not select the data type. SQL Server automatically assigns an appropriate data type depending upon the columns for the computed column in SQL Server value.

添加一个新列[年龄]。 在此列中,不要选择数据类型。 SQL Server会根据SQL Server值中计算列的列自动分配适当的数据类型。

In the Computed Column Specification, specify the formula for computed column value. In my example [Age] column, we use the DATEDIFF() function to calculate the employee age.

在“ 计算列规格”中 ,指定计算列值的公式。 在我的示例[Age]列中,我们使用DATEDIFF()函数来计算员工年龄。

Formula: datediff(year,DOB,getdate())

公式: datediff(year,DOB,getdate())

We have a property in the Computed Column Specification for the persisted column – Is Persisted. Currently, we leave it as default as not persisted.

我们在持久列的“计算列规范”中有一个属性– Is Persisted 。 目前,我们将其保留为默认值,因为它没有持久化。

Save the table and give it an appropriate name.

保存该表并为其指定适当的名称。

Click OK, and it creates the table with the computed column. Expand the [Employee] table, and you can see that it shows the Computed keyword in place of a data type.

单击OK ,它将创建带有计算列的表。 展开[Employee]表,您会看到它显示了Computed关键字而不是数据类型。

Now, insert a few records in the [Employee] table. You can note here that we do not insert data in the [Age] column.

现在,在[Employee]表中插入一些记录。 您可以在此处注意,我们不会在[年龄]列中插入数据。

Insert into [SQLShack].[dbo].[Employee] (EmpID,EmpName,DOB) values(1,'Raj','1987-01-01')
Insert into [SQLShack].[dbo].[Employee] (EmpID,EmpName,DOB) values(2,'Mohan','1985-06-07')
Insert into [SQLShack].[dbo].[Employee] (EmpID,EmpName,DOB) values(3,'Ram','1983-09-01')

Once we retrieve the records from the [Employee] table, it shows the data for the [Age] column as well.

从[Employee]表检索记录后,它也会显示[Age]列的数据。

SELECT [EmpID], [EmpName], [DOB], [Age]
FROM [SQLShack].[dbo].[Employee];

If we update the records in the SQL table, and computed columns calculate updated value once we retrieve data again. However, we cannot update or insert values in the virtual computed columns in SQL Server.

如果我们更新SQL表中的记录,并且一旦我们再次检索数据,则计算列将计算更新值。 但是,我们无法在SQL Server的虚拟计算列中更新或插入值。

Previously, we used the SSMS table designer to define a computed table. We can create a new table using the following CREATE TABLE script. You can look at the [Age] column that has the formula to calculate its values.

以前,我们使用SSMS表设计器来定义计算表。 我们可以使用以下CREATE TABLE脚本创建一个新表。 您可以查看[Age]列,该列具有用于计算其值的公式。

CREATE TABLE [dbo].[Employee]
([EmpID]   [INT] NOT NULL, [EmpName] [VARCHAR](50) NOT NULL, [DOB]     [DATE] NOT NULL, [Age] AS (DATEDIFF(yy, [DOB], GETDATE())), CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED([EmpID] ASC)
);

Similarly, we can add a new column into the existing table with the ALTER TABLE statement. In this query, we calculate the retirement date for the employees. You can notice here that we did not specify a data type for the additional column [RetirementDate].

同样,我们可以使用ALTER TABLE语句在现有表中添加新列。 在此查询中,我们计算员工的退休日期。 您可以在此处注意到,我们没有为附加列[RetirementDate]指定数据类型。

ALTER TABLE [dbo].[Employee]
ADD [RetirementDate] AS (DATEADD(year,60, [DOB]));

With the existing data, we can see the employee retirement date calculated by the computed columns.

使用现有数据,我们可以看到通过计算列计算出的员工退休日期。

使用“计算列”中的用户定义函数 (Use the User-defined Function in the Computed Column)

Previously, we specified the formula for computed column calculation. We can use user-defined functions as well in the computed column.

以前,我们指定了用于计算列计算的公式。 我们也可以在计算列中使用用户定义的函数。

In the below query, we create a user-defined function to calculate the employee retirement date. This function calculates employees’ retirement date as per employee ID.

在下面的查询中,我们创建一个用户定义的函数来计算员工的退休日期。 此功能根据员工ID计算员工的退休日期。

CREATE FUNCTION fn_employee_promotion
(@empid INT
)
RETURNS DATE
WITH SCHEMABINDING
ASBEGINDECLARE @newdate DATE;SELECT @newdate = DATEADD(year, 60, [DOB])FROM [dbo].[Employee]WHERE EmpID = @empid;RETURN @newdate;END;

Before we apply this function in the computed column, let’s drop the existing column using the following ALTER TABLE query.

在将此函数应用到计算列中之前,让我们使用以下ALTER TABLE查询删除现有列。

ALTER TABLE [Employee] DROP COLUMN [RetirementDate];

Now, let’s add a new computed column, and you can see we use the user-defined function instead of the computed column formula.

现在,让我们添加一个新的计算列,您会看到我们使用了用户定义的函数而不是计算列的公式。

ALTER TABLE [dbo].[Employee]
ADD [RetirementDate] AS dbo.fn_employee_promotion([EmpID])

We can query the [Employee] table, and it returns the output similar to specify formula directly in the computed column.

我们可以查询[Employee]表,它返回的输出类似于直接在计算列中指定公式的输出。

在SQL Server中物理存储计算列 (Physically storing a computed column in SQL Server)

As we discussed earlier, a computed column is a virtual column, and it does not get stored in the database. SQL Server calculates its value during runtime.

如前所述,计算列是虚拟列,并且不会存储在数据库中。 SQL Server在运行时计算其值。

For this section, let’s create a new [Customer] table with the below script.

对于本节,让我们使用以下脚本创建一个新的[Customer]表。

CREATE TABLE Customer
(customerid  INT PRIMARY KEY IDENTITY, first_name NVARCHAR(100) NOT NULL, last_name  NVARCHAR(100) NOT NULL, );

To prove the above point, we insert sample data records in the customer’s table.

为了证明上述观点,我们将样本数据记录插入客户表中。

DECLARE @i INT= 15000;
WHILE(@i > 1)BEGININSERT INTO Customer(first_name, last_name)SELECT name, type_descFROM sys.objects;SET @i = @i - 1;END;

Once the above script completes, check the space used by the customer table using the sp_spaceused system stored procedure. It also shows the number of records in the table. We require multiple records to feel the difference in the computed column as a virtual column or persisted column.

以上脚本完成后,使用sp_spaceused系统存储过程检查客户表使用的空间。 它还显示表中的记录数。 我们需要多个记录,以感觉到虚拟列或持久列在计算列中的差异。

sp_spaceused 'Customer'

Now, let’s add the computed column to get the full customer name and check the space used again. You can also note that it quickly adds the computed column irrespective of the number of rows in the table.

现在,让我们添加计算列以获取完整的客户名称并再次检查使用的空间。 您还可以注意到,无论表中的行数如何,它都会快速添加计算列。

ALTER TABLE Customer
ADD fullname AS (first_name + ' ' + last_name);

Now, drop this computed column and add it again with PERSISTED property. It takes approximately 2 minutes in script execution for me.

现在,删除此计算列,并再次使用PERSISTED属性添加它。 对我来说,执行脚本大约需要2分钟。

ALTER TABLE Customer DROP COLUMN fullname;Set QUOTED_IDENTIFIER ON
ALTER TABLE Customer
ADD fullname AS (first_name + ' ' + last_name) PERSISTED;

Let’s verify the space used by the customer table again. You can see data, and index size increased in Persisted computed column.

让我们再次验证客户表使用的空间。 您可以在持久计算列中看到数据,并且索引大小增加。

To make a computed column as persisted, it should be deterministic. We always get the same value provided we supply specific values in a deterministic function. It should have the same database as well.

为了使计算列持久化,它应该是确定性的。 只要我们在确定性函数中提供特定的值,我们总是会得到相同的值。 它也应该具有相同的数据库。

For example, a deterministic sum or avg function always returns the same value for specific inputs, but a non-deterministic GETDATE() function always returns a different value.

例如,确定性的sum或avg函数对于特定输入总是返回相同的值,但是不确定性的GETDATE()函数总是返回不同的值。

You can refer to Microsoft’s article Deterministic and Non-deterministic Functions for more details.

您可以参考Microsoft的文章“ 确定性函数和非确定性函数”以获取更多详细信息。

In the previous examples, we used the GETDATE() function to calculate the value of [Age] computed column. We cannot use this function directly because it does not satisfy the condition of a deterministic column.

在前面的示例中,我们使用了GETDATE()函数来计算[Age]计算列的值。 我们不能直接使用此函数,因为它不满足确定性列的条件。

If you try to add a column with a non-deterministic function such as GETDATE(), you get the following error message. It gives the message that we cannot add the column because it is non-deterministic.

如果您尝试添加具有诸如GETDATE()之类的不确定函数的列,则会收到以下错误消息。 它提示我们由于不确定性而无法添加该列。

ALTER TABLE Customer
ADD CurrentDate AS (getdate()) PERSISTED;

As stated earlier, we can use the user-defined function as well in computed columns in SQL Server. You might also get an error message for the non-deterministic function while adding it in the computed column. You should specify WITH DETERMINISTIC clause in the function to avoid this issue.

如前所述,我们也可以在SQL Server的计算列中使用用户定义的函数。 将不确定的函数添加到计算列中时,您可能还会收到错误消息。 您应该在函数中指定WITH DETERMINISTIC子句,以避免出现此问题。

You might have a question here, should we add a column as persisted or virtual? We should add a virtual computed column in case we have a small number of rows. In the case of a large number of rows, we should filter the records with the WHERE clause. SQL Server calculates the virtual computed column at run time so that you may face performance issues.

您可能在这里有一个问题,我们应该将列添加为持久列还是虚拟列? 如果行数少,我们应该添加一个虚拟的计算列。 对于大量行,我们应该使用WHERE子句过滤记录。 SQL Server在运行时计算虚拟计算列,因此您可能会遇到性能问题。

Once you create a deterministic persisted computed column, it gives you additional flexibility. You can create indexes to optimize your queries and get an optimized execution plan. You can also create constraints such as Null, Check, Foreign key for persisted computed column.

创建确定性的持久化计算列后,它将为您提供更多的灵活性。 您可以创建索引来优化查询并获得优化的执行计划。 您还可以为持久化的计算列创建约束,例如Null,Check,外键。

You should refer to create indexes on SQL Server computed columns to explore indexing on computed columns in SQL Server.

您应该参考在SQL Server计算列上创建索引,以探索对SQL Server计算列的索引。

获取SQL Server数据库中计算列的列表 (Get a list of computed columns in a SQL Server database)

We can use the system function sys.computed_columns and join it with the sys.objects to get a list of available computed columns, their data type, and the column definition (formula). Let’s run this script in the [AdventureWorks] sample database, and you get a list of all computed columns in SQL Server.

我们可以使用系统函数sys.computed_columns并将其与sys.objects结合使用,以获取可用计算列,它们的数据类型和列定义(公式)的列表。 让我们在[AdventureWorks]示例数据库中运行此脚本,然后获得SQL Server中所有计算列的列表。

SELECT SCHEMA_NAME(o.schema_id) AS schema_name, c.name AS column_name, OBJECT_NAME(c.object_id) AS table_name, TYPE_NAME(user_type_id) AS data_type, definition
FROM sys.computed_columns cJOIN sys.objects o ON o.object_id = c.object_id
ORDER BY schema_name, table_name, column_id;

It gives you enough information with examples to start exploring the computed columns in SQL Server.

它通过示例为您提供了足够的信息,以开始探索SQL Server中的计算列。

结论 (Conclusion)

In this article, we explored computed columns in SQL Server along with its virtual and persisted property. You should analyze your requirement and plan whether you require a persisted column or not. You can also create indexes on these columns for improving query performance.

在本文中,我们探讨了SQL Server中的计算列及其虚拟和持久属性。 您应该分析您的需求并计划是否需要持久化列。 您也可以在这些列上创建索引以提高查询性能。

翻译自: https://www.sqlshack.com/an-overview-of-computed-columns-in-sql-server/

SQL Server中的计算列概述相关推荐

  1. SQL Server中的标识列

    一.标识列的定义以及特点 SQL Server中的标识列又称标识符列,习惯上又叫自增列. 该种列具有以下三种特点: 1.列的数据类型为不带小数的数值类型 2.在进行插入(Insert)操作时,该列的值 ...

  2. SQL Server中Identity标识列

    SQL Server中,经常会用到Identity标识列,这种自增长的字段操作起来的确是比较方便.但它有时还会带来一些麻烦. SQL Server中,经常会用到Identity标识列,这种自增长的字段 ...

  3. SQL Server中的登录触发器概述

    This article gives you an overview of Logon triggers in SQL Server and its usage to control SQL Serv ...

  4. sql安装弹出sqlcmd_SQL Server中SQLCMD实用工具概述

    sql安装弹出sqlcmd This article is aimed at helping you understand the sqlcmd utility. Of course, this is ...

  5. SQL Server中唯一索引和唯一约束之间的区别

    This article gives you an overview of Unique Constraints in SQL and also the Unique SQL Server index ...

  6. 如何将用户迁移到SQL Server中的部分包含的数据库

    介绍 (Introduction) Microsoft introduced the Contained Database feature in SQL Server 2012. In this ar ...

  7. 细说SQL Server中的加密

    简介 加密是指通过使用密钥或密码对数据进行模糊处理的过程.在SQL Server中,加密并不能替代其他的安全设置,比如防止未被授权的人访问数据库或是数据库实例所在的Windows系统,甚至是数据库所在 ...

  8. SQL server 中的插入表行数据,以及插入标识值

    语法介绍 (1)在SQL server数据库中我们如何添加新的行,并且添加数据呢? Insert:该语句向表中添加新行 values: 要插入的值 语法如下: Insert into 模式.表名(字段 ...

  9. 如何在SQL Server中索引外键列

    Before going through the main concern of this article, indexing the foreign key columns, let's take ...

最新文章

  1. 湖南大学超级计算机中心 舒教授,湖南大学岳麓书院哲学系舒远招教授应邀来我院讲学...
  2. Visual Basic中实现带预览的对话框
  3. 五万块钱买什么车好_10万预算买什么车好?看空间、动力和配置
  4. Python之路番外(第二篇):PYTHON基本数据类型和小知识点
  5. 一文搞懂RSA算法原理及简单实现
  6. mmap父子进程间通信
  7. python的类和对象例题_Python类、类对象和实例对象、组合、绑定详细讲解
  8. caffe测试多张图片--需改代码
  9. 修改PPT文档属性工具使用教程
  10. 基于FPGA的AD9854并行接口驱动(VerilogHDL语言)
  11. vmware虚拟化故障虚拟磁盘丢失恢复办法
  12. 大计基作业记录(3)
  13. 企业为什么要进行数字化转型1.1——顺势而为谋发展
  14. 美团点评2018春招后台开发方向编程题 - 题解
  15. thinkphp框架配置验证是否登录公共函数的方法
  16. 陶瓷工厂的进销存管理系统的设计与实现
  17. K3 CLOUD出纳相关知识(应收金额、手工日记账、银行对账单)
  18. [HCIP] 03 - 路由控制之路由策略
  19. 快递鸟 快递100接口示例
  20. 沪上首个千人区块链产业峰会!POW'ER 2020上海峰会首日精华实录

热门文章

  1. centos恢复图形界面_CentOS 7 启动与切换图形界面
  2. linux img提取文件系统,Linux下 mount IMG文件提示“您必须制定文件系统类型”解决方法...
  3. node sqlite 插入数据_方便且实用,Python内置的轻量级数据库实操
  4. Java 集合(初稿)
  5. 使用U盘安装Ubuntu
  6. 白话容器namespace
  7. Oracle创建视图的一个问题
  8. flex 与 后台通讯
  9. kubernetes之五:资源管理
  10. Android Fetch请求问题