INSERT (Transact-SQL)
将新行添加到表或视图。
 语法
 [ WITH <common_table_expression> [ ,...n ] ]
 INSERT 
     [ TOP ( expression ) [ PERCENT ] ] 
     [ INTO] 
     { <object> | rowset_function_limited 
       [ WITH ( <Table_Hint_Limited> [ ...n ] ) ]
     }
 {
     [ ( column_list ) ] 
     [ <OUTPUT Clause> ]
     { VALUES ( { DEFAULT | NULL | expression } [ ,...n ] ) 
     | derived_table 
     | execute_statement 
     } 
 } 
     | DEFAULT VALUES 
 [; ]
 <object> ::=
 { 
     [ server_name . database_name . schema_name . 
       | database_name .[ schema_name ] . 
       | schema_name . 
     ]
         table_or_view_name
 }
-  
       
         WITH <common_table_expression> 
        
       
- 
指定在 INSERT 语句作用域内定义的临时命名结果集(也称为公用表表达式)。结果集源自 SELECT 语句。 公用表表达式还可以与 SELECT、DELETE、UPDATE 和 CREATE VIEW 语句一起使用。有关详细信息,请参阅 。 
-  
       
         TOP 
        (
expression
) [ PERCENT ] 
        
       
- 
指定将插入的随机行的数目或百分比。expression 可以是行数或行的百分比。在和 INSERT、UPDATE 或 DELETE 语句结合使用的 TOP 表达式中引用的行不按任何顺序排列。 在 INSERT、UPDATE 和 DELETE 语句中,需要使用括号分隔 TOP 中的 expression。有关详细信息,请参阅 。 
-  
       
         INTO 
        
       
- 
一个可选的关键字,可以将它用在 INSERT 和目标表之间。 
- 
server_name 
- 
表或视图所在服务器的名称(将 OPENDATASOURCE 函数用作服务器名称)。如果指定了 server_name,则需要 database_name 和 schema_name。 
- 
database_name 
- 
数据库的名称。 
- 
schema_name 
- 
表或视图所属架构的名称。 
- 
table_or view_name 
- 
要接收数据的表或视图的名称。 table 变量在其作用域内可用作 INSERT 语句中的表源。 table_or_view_name 引用的视图必须可更新,并且只在该视图的 FROM 子句中引用一个基表。例如,多表视图中的 INSERT 必须使用只引用一个基表中各列的 column_list。有关可更新视图的详细信息,请参阅 。 
- 
rowset_function_limited 
- 
或 函数。 
-  
       
         WITH 
        ( <table_hint_limited> [... 
        n ] 
        )
- 
指定目标表允许的一个或多个表提示。需要有 WITH 关键字和括号。 不允许 READPAST、NOLOCK 和 READUNCOMMITTED。有关表提示的详细信息,请参阅。 重要提示: 在将来的 SQL Server 版本中,将删除对作为 INSERT 语句目标的表指定 HOLDLOCK、SERIALIZABLE、READCOMMITTED、REPEATABLEREAD 或 UPDLOCK 提示的功能。这些提示不影响 INSERT 语句的性能。请避免在新的开发工作中使用该功能,并计划修改当前使用该功能的应用程序。 对作为 INSERT 语句目标的表指定 TABLOCK 提示与指定 TABLOCKX 提示具有相同的效果。对表采用排他锁。 
- 
(
column_list
)
- 
要在其中插入数据的一列或多列的列表。必须用括号将 column_list 括起来,并且用逗号进行分隔。 如果某列不在 column_list 中,则 SQL Server 2005 数据库引擎必须能够基于该列的定义提供一个值;否则不能加载行。如果列满足下面的条件,则数据库引擎将自动为列提供值: - 具有 IDENTITY 属性。使用下一个增量标识值。
- 有默认值。使用列的默认值。
- 具有 timestamp 数据类型。使用当前的时间戳值。
- 可为空值。使用空值。
- 是计算列。使用计算值。
 当向标识列中插入显式值时,必须使用 column_list 和 VALUES 列表,并且表的 SET IDENTITY_INSERT 选项必须为 ON。 
- 具有 IDENTITY 属性。使用下一个增量标识值。
-  
       
         OUTPUT 子句 
        
       
- 
将插入行作为插入操作的一部分返回。引用本地分区视图、分布式分区视图或远程表的 DML 语句,或包含 execute_statement 的 INSERT 语句,都不支持 。 
-  
       
         VALUES 
        
       
- 
引入要插入的数据值的列表。对于 column_list(如果已指定)或表中的每个列,都必须有一个数据值。必须用圆括号将值列表括起来。 如果 VALUES 列表中的各值与表中各列的顺序不相同,或者未包含表中各列的值,则必须使用 column_list 显式指定存储每个传入值的列。 
-  
       
         DEFAULT 
        
       
- 
强制数据库引擎加载为列定义的默认值。如果某列并不存在默认值,并且该列允许空值,则插入 NULL。对于使用 timestamp 数据类型定义的列,插入下一个时间戳值。DEFAULT 对标识列无效。 
- 
expression 
- 
一个常量、变量或表达式。表达式不能包含 SELECT 或 EXECUTE 语句。 
- 
derived_table 
- 
任何有效的 SELECT 语句,它返回将加载到表中的数据行。SELECT 语句不能包含公用表表达式 (CTE)。 
- 
execute_statement 
- 
任何有效的 EXECUTE 语句,它使用 SELECT 或 READTEXT 语句返回数据。SELECT 语句不能包含 CTE。 如果 execute_statement 使用 INSERT,则每个结果集必须与表或 column_list 中的列兼容。 可以使用 execute_statement 对同一服务器或远程服务器执行存储过程。执行远程服务器中的过程,并将结果集返回到本地服务器并加载到本地服务器的表中。 如果 execute_statement 使用 READTEXT 语句返回数据,则每个 READTEXT 语句最多可以返回 1 MB (1024 KB) 的数据。execute_statement 还可以用于扩展过程。execute_statement 插入由扩展过程的主线程返回的数据,但不插入主线程以外的线程的输出。 
-  
       
         DEFAULT VALUES 
        
       
- 
强制新行包含为每个列定义的默认值。 
INSERT 将新行追加到表中。若要替换表中的数据,必须在使用 INSERT 加载新数据之前,使用 或 语句清除现有的数据。若要修改现有行中的列值,请使用 。可以创建新表,并使用 语句的 INTO 选项通过一个步骤为它加载数据。
使用 uniqueidentifier 数据类型创建的列存储特殊格式的 16 位二进制值。与标识列不同,数据库引擎不为 uniqueidentifier 数据类型的列自动生成值。在插入操作过程中,可以将 uniqueidentifier 数据类型的变量和 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 格式的字符串常量(包括连字符在内共 36 个字符,其中 x 表示从 0 到 9 或从 a 到 f 的十六进制数字)用于 uniqueidentifier 列。例如,6F9619FF-8B86-D011-B42D-00C04FC9FF 是 uniqueidentifier 变量或列的有效值。使用 NEWID() 函数获取全局唯一 ID (GUID)。
在本地和远程分区视图上,忽略 INSERT 语句的 SET ROWCOUNT 选项的设置。此外,当兼容级别设置为 80 或更高时,对于针对数据库引擎中的远程表发出的 INSERT 语句也不支持此选项。
如果在表达式计算过程中 INSERT 语句遇到算术错误(溢出、被零除或域错误),则数据库引擎会处理这些错误,就好像 SET ARITHABORT 设置为 ON 一样。停止批处理的其余部分,并返回一条错误消息。
插入行的规则
插入行时,可以应用下列规则:
- 如果将值加载到 char、varchar 或 varbinary 数据类型的列中,则尾随空格(对于 char 和 varchar 为空格,对于 varbinary 为零)的填充或截断由创建表时为该列定义的 SET ANSI_PADDING 设置确定。有关详细信息,请参阅 。 
 下表显示了 SET ANSI_PADDING OFF 的默认操作。
 数据类型 默认操作 char 将带有空格的值填充到已定义的列宽。 varchar 删除最后的非空格字符后面的尾随空格,而对于只由空格组成的字符串,一直删除到只留下一个空格。 varbinary 删除尾随的零。 
- 如果将一个空字符串 (' ') 加载到 varchar 或 text 数据类型的列,则默认操作是加载一个零长度的字符串。
- 如果 INSERT 语句违反约束或规则,或者包含与列的数据类型不兼容的值,则该语句将失败,并且数据库引擎显示错误消息。
- 将空值插入到 text 或 image 列不创建有效的文本指针,也不预分配 8 KB 的文本页。有关插入 text 和 image 数据的详细信息,请参阅。
- 如果 INSERT 是使用 SELECT 或 EXECUTE 加载多行,那么一旦加载的值中出现任何违反规则或约束的情况,就会导致终止整个语句,且不会加载任何行。
- 当向远程数据库引擎实例的表中插入值且没有为所有列指定所有值时,用户必须标识将向其中插入指定值的列。
对 INSERT 操作使用 INSTEAD OF 触发器
当为表或视图的 INSERT 操作定义了 INSTEAD OF 触发器时,则执行该触发器而不是 INSERT 语句。SQL Server的早期版本只支持在 INSERT 和其他数据修改语句上定义的 AFTER 触发器。有关 INSTEAD OF 触发器的详细信息,请参阅 。
将值插入到用户定义的类型列中
可以通过以下方法将值插入到用户定义的类型列中:
- 提供用户定义类型的值。 
- 提供 SQL Server 2005 系统数据类型的值,条件是该用户定义类型支持该类型的隐式转换或显式转换。以下示例显示了如何基于字符串进行显式转换将值插入到用户定义的类型 Point 的列中。 
         由于所有用户定义的类型可以从二进制值进行隐式转换,因此还可以在不执行显式转换的情况下提供二进制值。有关转换和用户定义类型的详细信息,请参阅。INSERT INTO Cities (Location) VALUES ( CONVERT(Point, '12.3:46.2') );
- 调用一个用户定义函数,该函数返回用户定义类型的值。以下示例使用用户定义函数 CreateNewPoint() 创建一个用户定义类型 Point 的新值,并将该值插入到 Cities 表中。 
 
 INSERT INTO Cities (Location)
 VALUES ( dbo.CreateNewPoint(x, y) );
使用 OPENROWSET 和 BULK 大容量加载数据
在 SQL Server 2005 数据库引擎中,可用于 OPENROWSET BULK 行集提供程序的新表提示为 INSERT 语句提供了以下大容量加载优化:
- 大容量加载日志记录(使插入操作的日志记录数最小化)
- 可以将约束检查设置为 ON 或 OFF
- 可以将触发器执行设置为 ON 或 OFF
这些优化类似于可与 BULK INSERT 命令一起使用的优化。
当 INSERT 语句向非空表中执行大容量加载时,存在以下附加的性能增强功能:
- 在大容量加载过程中拆分页面时,不必完全记录添加到该页面的新行。
- 如果表存在非聚集索引,但不存在聚集索引,则可能必须完全记录单个索引行,但不必完全记录数据行。
有关详细信息,请参阅 和。
需要目标表上的 INSERT 权限。
默认情况下,INSERT 权限被授予 sysadmin 固定服务器角色成员、db_owner 和 db_datawriter 固定数据库角色成员以及表的所有者。sysadmin、db_owner 和 db_securityadmin 角色成员和表所有者可以将权限传递给其他用户。
若要使用 OPENROWSET 函数 BULK 选项执行 INSERT,您必须是 sysadmin 固定服务器角色成员或 bulkadmin 固定服务器角色成员。
 示例 
- 
A. 执行简单的 INSERT 语句以下示例在 Production.UnitMeasure 表中插入一行。由于提供了所有列的值并按表中各列的顺序列出这些值,因此不必在 column_list. 中指定列名。 
 USE AdventureWorks;
 GO
 INSERT INTO Production.UnitMeasure
 VALUES (N ' F2 ' , N ' Square Feet ' , GETDATE ());
 GOB. 按与表列不同的顺序插入数据以下示例使用 column_list 显式指定插入到每个列的值。UnitMeasure 表中的列顺序为 UnitMeasureCode、Name、ModifiedDate;但这些列的列出顺序与 column_list 中的顺序不同。 USE AdventureWorks;
 GO
 INSERT INTO Production.UnitMeasure (Name, UnitMeasureCode,
 ModifiedDate)
 VALUES (N ' Square Yards ' , N ' Y2 ' , GETDATE ());
 GOC. 插入值少于列个数的数据 以下示例显示了如何将行插入到包含自动生成值或具有默认值的列的表中。INSERT 语句插入一些行,这些行只有部分列包含值。在最后一个 INSERT 语句中,未指定列并只插入了默认值。 USE AdventureWorks;
 GO
 IF OBJECT_ID ( ' dbo.T1 ' , ' U ' ) IS NOT NULL
 DROP TABLE dbo.T1;
 GO
 CREATE TABLE dbo.T1
 (
 column_1 int IDENTITY ,
 column_2 varchar ( 30 )
 CONSTRAINT default_name DEFAULT ( ' my column default ' ),
 column_3 timestamp ,
 column_4 varchar ( 40 ) NULL
 );
 GO
 INSERT INTO dbo.T1 (column_4)
 VALUES ( ' Explicit value ' );
 INSERT INTO dbo.T1 (column_2, column_4)
 VALUES ( ' Explicit value ' , ' Explicit value ' );
 INSERT INTO dbo.T1 (column_2)
 VALUES ( ' Explicit value ' );
 INSERT INTO T1 DEFAULT VALUES ;
 GO
 SELECT column_1, column_2, column_3, column_4
 FROM dbo.T1;
 GOD. 将数据插入到带有标识列的表以下示例显示了将数据插入标识列的不同方法。前两个 INSERT 语句允许为新行生成标识值。第三个 INSERT 语句用 SET IDENTITY_INSERT 语句覆盖列的 IDENTITY 属性,并将一个显式值插入到标识列。 USE AdventureWorks;
 GO
 IF OBJECT_ID ( ' dbo.T1 ' , ' U ' ) IS NOT NULL
 DROP TABLE dbo.T1;
 GO
 CREATE TABLE dbo.T1 ( column_1 int IDENTITY , column_2 VARCHAR ( 30 ));
 GO
 INSERT T1 VALUES ( ' Row #1 ' );
 INSERT T1 (column_2) VALUES ( ' Row #2 ' );
 GO
 SET IDENTITY_INSERT T1 ON ;
 GO
 INSERT INTO T1 (column_1,column_2)
 VALUES ( - 99 , ' Explicit identity value ' );
 GO
 SELECT column_1, column_2
 FROM T1;
 GOE. 通过使用 NEWID() 将数据插入到 uniqueidentifier 列以下示例使用 NEWID() 函数获取 column_2 的 GUID。与标识列不同,数据库引擎不为 uniqueidentifier 数据类型的列自动生成值(如第二个 INSERT 语句所示)。 USE AdventureWorks;
 GO
 IF OBJECT_ID ( ' dbo.T1 ' , ' U ' ) IS NOT NULL
 DROP TABLE dbo.T1;
 GO
 CREATE TABLE dbo.T1
 (
 column_1 int IDENTITY ,
 column_2 uniqueidentifier ,
 );
 GO
 INSERT INTO dbo.T1 (column_2)
 VALUES ( NEWID ());
 INSERT INTO T1 DEFAULT VALUES ;
 GO
 SELECT column_1, column_2
 FROM dbo.T1;
 GOF. 通过视图将数据加载到表以下示例在 INSERT 语句中指定一个视图名,但将新行插入到该视图的基础表中。INSERT 语句中 VALUES 列表的顺序必须与视图的列顺序相匹配。 USE AdventureWorks;
 GO
 IF OBJECT_ID ( ' dbo.T1 ' , ' U ' ) IS NOT NULL
 DROP TABLE dbo.T1;
 GO
 IF OBJECT_ID ( ' dbo.V1 ' , ' V ' ) IS NOT NULL
 DROP VIEW dbo.V1;
 GO
 CREATE TABLE T1 ( column_1 int , column_2 varchar ( 30 ));
 GO
 CREATE VIEW V1 AS
 SELECT column_2, column_1
 FROM T1;
 GO
 INSERT INTO V1
 VALUES ( ' Row 1 ' , 1 );
 GO
 SELECT column_1, column_2
 FROM T1;
 GO
 SELECT column_1, column_2
 FROM V1;
 GOG. 使用 SELECT 和 EXECUTE 选项插入数据 以下示例显示三种不同的方法,用来从一个表获取数据,并将数据插入到另一个表。每种方法都基于一个多表 SELECT 语句,该语句在列列表中包含一个表达式及一个文字值。 第一个 INSERT 语句使用 SELECT 语句直接从源表(Employee、SalesPerson 和 Contact)中检索数据,并将结果集存储在 EmployeeSales 表中。第二个 INSERT 执行一个包含 SELECT 语句的存储过程,而第三个 INSERT 将 SELECT 语句作为一个字符串执行。 USE AdventureWorks;
 GO
 IF OBJECT_ID ( ' dbo.EmployeeSales ' , ' U ' ) IS NOT NULL
 DROP TABLE dbo.EmployeeSales;
 GO
 IF OBJECT_ID ( ' dbo.uspGetEmployeeSales ' , ' P ' ) IS NOT NULL
 DROP PROCEDURE uspGetEmployeeSales;
 GO
 CREATE TABLE dbo.EmployeeSales
 ( DataSource varchar ( 20 ) NOT NULL ,
 EmployeeID varchar ( 11 ) NOT NULL ,
 LastName varchar ( 40 ) NOT NULL ,
 SalesDollars money NOT NULL
 );
 GO
 CREATE PROCEDURE dbo.uspGetEmployeeSales
 AS
 SELECT ' PROCEDURE ' , e.EmployeeID, c.LastName,
 sp.SalesYTD
 FROM HumanResources.Employee AS e
 INNER JOIN Sales.SalesPerson AS sp
 ON e.EmployeeID = sp.SalesPersonID
 INNER JOIN Person.Contact AS c
 ON e.ContactID = c.ContactID
 WHERE e.EmployeeID LIKE ' 2% '
 ORDER BY e.EmployeeID, c.LastName;
 GO
 -- INSERTSELECT example
 INSERT dbo.EmployeeSales
 SELECT ' SELECT ' , e.EmployeeID, c.LastName, sp.SalesYTD
 FROM HumanResources.Employee AS e
 INNER JOIN Sales.SalesPerson AS sp
 ON e.EmployeeID = sp.SalesPersonID
 INNER JOIN Person.Contact AS c
 ON e.ContactID = c.ContactID
 WHERE e.EmployeeID LIKE ' 2% '
 ORDER BY e.EmployeeID, c.LastName;
 GO
 -- INSERTEXECUTE procedure example
 INSERT EmployeeSales
 EXECUTE uspGetEmployeeSales;
 GO
 -- INSERTEXECUTE('string') example
 INSERT EmployeeSales
 EXECUTE
 ( '
 SELECT '' EXEC STRING '' , e.EmployeeID, c.LastName,
 sp.SalesYTD
 FROM HumanResources.Employee AS e
 INNER JOIN Sales.SalesPerson AS sp
 ON e.EmployeeID = sp.SalesPersonID
 INNER JOIN Person.Contact AS c
 ON e.ContactID = c.ContactID
 WHERE e.EmployeeID LIKE '' 2% ''
 ORDER BY e.EmployeeID, c.LastName
 ' );
 GO
 -- Show results.
 SELECT DataSource,EmployeeID,LastName,SalesDollars
 FROM dbo.EmployeeSales;
 GOH. 通过使用 TOP 子句插入数据USE AdventureWorks;
 GO
 IF OBJECT_ID (N ' HumanResources.NewEmployee ' , N ' U ' ) IS NOT NULL
 DROP TABLE HumanResources.NewEmployee;
 GO
 CREATE TABLE HumanResources.NewEmployee
 (
 EmployeeID int NOT NULL ,
 LastName nvarchar ( 50 ) NOT NULL ,
 FirstName nvarchar ( 50 ) NOT NULL ,
 Phone Phone NULL ,
 AddressLine1 nvarchar ( 60 ) NOT NULL ,
 City nvarchar ( 30 ) NOT NULL ,
 State nchar ( 3 ) NOT NULL ,
 PostalCode nvarchar ( 15 ) NOT NULL ,
 CurrentFlag Flag
 );
 GO
 INSERT TOP ( 10 ) INTO HumanResources.NewEmployee
 SELECT
 e.EmployeeID, c.LastName, c.FirstName, c.Phone,
 a.AddressLine1, a.City, sp.StateProvinceCode,
 a.PostalCode, e.CurrentFlag
 FROM HumanResources.Employee e
 INNER JOIN HumanResources.EmployeeAddress AS ea
 ON e.EmployeeID = ea.EmployeeID
 INNER JOIN Person.Address AS a
 ON ea.AddressID = a.AddressID
 INNER JOIN Person.StateProvince AS sp
 ON a.StateProvinceID = sp.StateProvinceID
 INNER JOIN Person.Contact as c
 ON e.ContactID = c.ContactID;
 GO
 SELECT EmployeeID, LastName, FirstName, Phone,
 AddressLine1, City, State, PostalCode, CurrentFlag
 FROM HumanResources.NewEmployee;
 GOI. 使用带 INSERT 语句的 OUTPUT以下示例将行插入 ScrapReason 表,并使用 OUTPUT 子句将语句的结果返回到 @MyTableVar table 变量。由于 ScrapReasonID 列使用 IDENTITY 属性定义,因此未在 INSERT 语句中为该列指定一个值。但应注意,数据库引擎为该列生成的值在 INSERTED.ScrapReasonID 列中的 OUTPUT 子句中返回。 USE AdventureWorks;
 GO
 DECLARE @MyTableVar table ( ScrapReasonID smallint ,
 Name varchar ( 50 ),
 ModifiedDate datetime );
 INSERT Production.ScrapReason
 OUTPUT INSERTED.ScrapReasonID, INSERTED.Name, INSERTED.ModifiedDate
 INTO @MyTableVar
 VALUES (N ' Operator error ' , GETDATE ());
 -- Display the result set of the table variable.
 SELECT ScrapReasonID, Name, ModifiedDate FROM @MyTableVar ;
 -- Display the result set of the table.
 SELECT ScrapReasonID, Name, ModifiedDate
 FROM Production.ScrapReason;
 GOJ. 使用带 INSERT 语句的 WITH 公用表表达式以下示例创建 NewEmployee 表。公用表表达式 (EmployeeTemp) 定义要插入 NewEmployee 表中的行。INSERT 语句引用公用表表达式中的列。 USE AdventureWorks;
 GO
 IF OBJECT_ID (N ' HumanResources.NewEmployee ' , N ' U ' ) IS NOT NULL
 DROP TABLE HumanResources.NewEmployee;
 GO
 CREATE TABLE HumanResources.NewEmployee
 (
 EmployeeID int NOT NULL ,
 LastName nvarchar ( 50 ) NOT NULL ,
 FirstName nvarchar ( 50 ) NOT NULL ,
 Phone Phone NULL ,
 AddressLine1 nvarchar ( 60 ) NOT NULL ,
 City nvarchar ( 30 ) NOT NULL ,
 State nchar ( 3 ) NOT NULL ,
 PostalCode nvarchar ( 15 ) NOT NULL ,
 CurrentFlag Flag
 );
 GO
 WITH EmployeeTemp (EmpID, LastName, FirstName, Phone,
 Address, City, StateProvince,
 PostalCode, CurrentFlag)
 AS ( SELECT
 e.EmployeeID, c.LastName, c.FirstName, c.Phone,
 a.AddressLine1, a.City, sp.StateProvinceCode,
 a.PostalCode, e.CurrentFlag
 FROM HumanResources.Employee e
 INNER JOIN HumanResources.EmployeeAddress AS ea
 ON e.EmployeeID = ea.EmployeeID
 INNER JOIN Person.Address AS a
 ON ea.AddressID = a.AddressID
 INNER JOIN Person.StateProvince AS sp
 ON a.StateProvinceID = sp.StateProvinceID
 INNER JOIN Person.Contact as c
 ON e.ContactID = c.ContactID
 )
 INSERT INTO HumanResources.NewEmployee
 SELECT EmpID, LastName, FirstName, Phone,
 Address, City, StateProvince, PostalCode, CurrentFlag
 FROM EmployeeTemp;
 GOK. 将 OUTPUT 用于 Identity 和 Computed 列下面的示例创建 EmployeeSales 表,然后使用 INSERT 语句向其中插入若干行,并使用 SELECT 语句从源表中检索数据。EmployeeSales 表包含标识列 (EmployeeID) 和计算列 (ProjectedSales)。由于这些值是在插入操作期间由数据库引擎生成的,因此,不能在 @MyTableVar 中定义上述两列。 USE AdventureWorks ;
 GO
 IF OBJECT_ID ( ' dbo.EmployeeSales ' , ' U ' ) IS NOT NULL
 DROP TABLE dbo.EmployeeSales;
 GO
 CREATE TABLE dbo.EmployeeSales
 ( EmployeeID int IDENTITY ( 1 , 5 ) NOT NULL ,
 LastName nvarchar ( 20 ) NOT NULL ,
 FirstName nvarchar ( 20 ) NOT NULL ,
 CurrentSales money NOT NULL ,
 ProjectedSales AS CurrentSales * 1.10
 );
 GO
 DECLARE @MyTableVar table (
 LastName nvarchar ( 20 ) NOT NULL ,
 FirstName nvarchar ( 20 ) NOT NULL ,
 CurrentSales money NOT NULL
 );
 INSERT INTO dbo.EmployeeSales (LastName, FirstName, CurrentSales)
 OUTPUT INSERTED.LastName,
 INSERTED.FirstName,
 INSERTED.CurrentSales
 INTO @MyTableVar
 SELECT c.LastName, c.FirstName, sp.SalesYTD
 FROM HumanResources.Employee AS e
 INNER JOIN Sales.SalesPerson AS sp
 ON e.EmployeeID = sp.SalesPersonID
 INNER JOIN Person.Contact AS c
 ON e.ContactID = c.ContactID
 WHERE e.EmployeeID LIKE ' 2% '
 ORDER BY c.LastName, c.FirstName;
 SELECT LastName, FirstName, CurrentSales
 FROM @MyTableVar ;
 GO
 SELECT EmployeeID, LastName, FirstName, CurrentSales, ProjectedSales
 FROM dbo.EmployeeSales;
 GO
 
