insert into语句

本文详细介绍 SQL 中 INSERT 语句的使用方法及其各种变体,包括语法结构、参数说明和多个示例,帮助读者掌握如何正确地向数据库表中添加新记录。

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

insert   into  Salary( 8 , ' Mr.Gao ' , ' Au-Dollar ' , 1330 );  /**/ /*incorrect*/
insert   into  Salary  values ( 8 , ' Mr.Gao ' , ' Au-Dollar ' , 1330 ); /**/ /*correct*/
insert   into  Salary(id)  values ( 8 , ' Mr.Gao ' , ' Au-Dollar ' , 1330 ); /**/ /*incorrect*/
insert   into  Salary(id,fullname,currency,salary)  values ( 8 , ' Mr.Gao ' , ' Au-Dollar ' , 1330 ); /**/ /*correct*/
insert  Salary(id,fullname,currency,salary)  values ( 8 , ' Mr.Gao ' , ' Au-Dollar ' , 1330 ); /**/ /*correct*/
insert  Salary(id,fullname,currency)  values ( 8 , ' Mr.Gao ' , ' Au-Dollar ' ); /**/ /*correct*/

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 语句一起使用。有关详细信息,请参阅 WITH common_table_expression (Transact-SQL)

TOP ( expression ) [ PERCENT ]

指定将插入的随机行的数目或百分比。expression 可以是行数或行的百分比。在和 INSERT、UPDATE 或 DELETE 语句结合使用的 TOP 表达式中引用的行不按任何顺序排列。

在 INSERT、UPDATE 和 DELETE 语句中,需要使用括号分隔 TOP 中的 expression。有关详细信息,请参阅 TOP (Transact-SQL)

INTO

一个可选的关键字,可以将它用在 INSERT 和目标表之间。

server_name

表或视图所在服务器的名称(将 OPENDATASOURCE 函数用作服务器名称)。如果指定了 server_name,则需要 database_nameschema_name

database_name

数据库的名称。

schema_name

表或视图所属架构的名称。

table_or view_name

要接收数据的表或视图的名称。

table 变量在其作用域内可用作 INSERT 语句中的表源。

table_or_view_name 引用的视图必须可更新,并且只在该视图的 FROM 子句中引用一个基表。例如,多表视图中的 INSERT 必须使用只引用一个基表中各列的 column_list。有关可更新视图的详细信息,请参阅 CREATE VIEW (Transact-SQL)

rowset_function_limited

OPENQUERYOPENROWSET 函数。

WITH ( <table_hint_limited> [... n ] )

指定目标表允许的一个或多个表提示。需要有 WITH 关键字和括号。

不允许 READPAST、NOLOCK 和 READUNCOMMITTED。有关表提示的详细信息,请参阅表提示 (Transact-SQL)

重要提示:
在将来的 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。

OUTPUT 子句

将插入行作为插入操作的一部分返回。引用本地分区视图、分布式分区视图或远程表的 DML 语句,或包含 execute_statement 的 INSERT 语句,都不支持 OUTPUT 子句

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 加载新数据之前,使用 DELETETRUNCATE TABLE 语句清除现有的数据。若要修改现有行中的列值,请使用 UPDATE。可以创建新表,并使用 SELECT 语句的 INTO 选项通过一个步骤为它加载数据。

使用 uniqueidentifier 数据类型创建的列存储特殊格式的 16 位二进制值。与标识列不同,数据库引擎不为 uniqueidentifier 数据类型的列自动生成值。在插入操作过程中,可以将 uniqueidentifier 数据类型的变量和 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 格式的字符串常量(包括连字符在内共 36 个字符,其中 x 表示从 0 到 9 或从 a 到 f 的十六进制数字)用于 uniqueidentifier 列。例如,6F9619FF-8B86-D011-B42D-00C04FC964FF 是 uniqueidentifier 变量或列的有效值。使用 NEWID() 函数获取全局唯一 ID (GUID)。

在本地和远程分区视图上,忽略 INSERT 语句的 SET ROWCOUNT 选项的设置。此外,当兼容级别设置为 80 或更高时,对于针对数据库引擎中的远程表发出的 INSERT 语句也不支持此选项。

如果在表达式计算过程中 INSERT 语句遇到算术错误(溢出、被零除或域错误),则数据库引擎会处理这些错误,就好像 SET ARITHABORT 设置为 ON 一样。停止批处理的其余部分,并返回一条错误消息。

插入行的规则

插入行时,可以应用下列规则:

  • 如果将值加载到 charvarcharvarbinary 数据类型的列中,则尾随空格(对于 charvarchar 为空格,对于 varbinary 为零)的填充或截断由创建表时为该列定义的 SET ANSI_PADDING 设置确定。有关详细信息,请参阅 SET ANSI_PADDING (Transact-SQL)
    下表显示了 SET ANSI_PADDING OFF 的默认操作。

    数据类型 默认操作

    char

    将带有空格的值填充到已定义的列宽。

    varchar

    删除最后的非空格字符后面的尾随空格,而对于只由空格组成的字符串,一直删除到只留下一个空格。

    varbinary

    删除尾随的零。

  • 如果将一个空字符串 (' ') 加载到 varchartext 数据类型的列,则默认操作是加载一个零长度的字符串。
  • 如果 INSERT 语句违反约束或规则,或者包含与列的数据类型不兼容的值,则该语句将失败,并且数据库引擎显示错误消息。
  • 将空值插入到 textimage 列不创建有效的文本指针,也不预分配 8 KB 的文本页。有关插入 textimage 数据的详细信息,请参阅使用 text、ntext 和 image 函数
  • 如果 INSERT 是使用 SELECT 或 EXECUTE 加载多行,那么一旦加载的值中出现任何违反规则或约束的情况,就会导致终止整个语句,且不会加载任何行。
  • 当向远程数据库引擎实例的表中插入值且没有为所有列指定所有值时,用户必须标识将向其中插入指定值的列。

对 INSERT 操作使用 INSTEAD OF 触发器

当为表或视图的 INSERT 操作定义了 INSTEAD OF 触发器时,则执行该触发器而不是 INSERT 语句。SQL Server的早期版本只支持在 INSERT 和其他数据修改语句上定义的 AFTER 触发器。有关 INSTEAD OF 触发器的详细信息,请参阅 CREATE TRIGGER (Transact-SQL)

将值插入到用户定义的类型列中

可以通过以下方法将值插入到用户定义的类型列中:

  • 提供用户定义类型的值。
  • 提供 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 语句向非空表中执行大容量加载时,存在以下附加的性能增强功能:

  • 在大容量加载过程中拆分页面时,不必完全记录添加到该页面的新行。
  • 如果表存在非聚集索引,但不存在聚集索引,则可能必须完全记录单个索引行,但不必完全记录数据行。

有关详细信息,请参阅 OPENROWSET (Transact-SQL)表提示 (Transact-SQL)

需要目标表上的 INSERT 权限。

默认情况下,INSERT 权限被授予 sysadmin 固定服务器角色成员、db_ownerdb_datawriter 固定数据库角色成员以及表的所有者。sysadmindb_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 ());
GO

 

B. 按与表列不同的顺序插入数据

以下示例使用 column_list 显式指定插入到每个列的值。UnitMeasure 表中的列顺序为 UnitMeasureCodeNameModifiedDate;但这些列的列出顺序与 column_list 中的顺序不同。

USE  AdventureWorks;
GO
INSERT   INTO  Production.UnitMeasure (Name, UnitMeasureCode,
    ModifiedDate)
VALUES  (N ' Square Yards ' , N ' Y2 ' GETDATE ());
GO

C. 插入值少于列个数的数据

以下示例显示了如何将行插入到包含自动生成值或具有默认值的列的表中。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;
GO

D. 将数据插入到带有标识列的表

以下示例显示了将数据插入标识列的不同方法。前两个 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;
GO

E. 通过使用 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;
GO

F. 通过视图将数据加载到表

以下示例在 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;
GO

G. 使用 SELECT 和 EXECUTE 选项插入数据

以下示例显示三种不同的方法,用来从一个表获取数据,并将数据插入到另一个表。每种方法都基于一个多表 SELECT 语句,该语句在列列表中包含一个表达式及一个文字值。

第一个 INSERT 语句使用 SELECT 语句直接从源表(EmployeeSalesPersonContact)中检索数据,并将结果集存储在 EmployeeSales 表中。第二个 INSERT 执行一个包含 SELECT 语句的存储过程,而第三个 INSERTSELECT 语句作为一个字符串执行。


         
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;
GO

H. 通过使用 TOP 子句插入数据

下面的示例创建 NewEmployee 表,并将 Employee 表中前 10 名雇员的地址数据插入到该表中。然后执行 SELECT 语句以验证 NewEmployee 表的内容。

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;
GO

I. 使用带 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;
GO

J. 使用带 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;
GO

K. 将 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

 

根据表格数据批量生成Insert Into语句 本人在登陆优快云论坛的数据库板块时,常看到很多网友提关于数据库的各种问题。而这些问题中有很多是要使用范例数据的。但是很多提问的朋友却没有把这些范例数据库INSERT INTO语句写出来,只是以这种方式提供:id dates num1 num2---------------------------------------------------------0001 2004-4-5 2000 3000 0002 2004-4-5 1000 5000 0003 2005-6-7 1500 3000 0004 2006-5-6 1200 3000 0005 2005-6-7 1300 3400 对于回答问题网友来说,见表和构建INSERT INTO语句是很费时间的,很多时候用于这里的时间比写出要求的SQL语句用的时间还多,其不是对答题网友时间的及大浪费。现在这种状况可以得到改善了。本人利用空余时间写了个小程序strfmt.exe,它可以批量将上面或类似的数据一次性生成INSERT INTO # VALUES语句,如INSERT INTO # VALUES ('0001','2004-4-5','2000','3000')INSERT INTO # VALUES ('0002','2004-4-5','1000','5000')INSERT INTO # VALUES ('0003','2005-6-7','1500','3000')INSERT INTO # VALUES ('0004','2006-5-6','1200','3000')INSERT INTO # VALUES ('0005','2005-6-7','1300','3400')或者生成INSERT INTO # SELECT语句,如INSERT INTO # SELECT '0001','2004-4-5','2000','3000'INSERT INTO # SELECT '0002','2004-4-5','1000','5000'INSERT INTO # SELECT '0003','2005-6-7','1500','3000'INSERT INTO # SELECT '0004','2006-5-6','1200','3000'INSERT INTO # SELECT '0005','2005-6-7','1300','3400'有了strfmt.exe,广大答题者就能大大提高答题效率,不必浪费时间在范例数据的构建上了。 本程序只是本人业余之作,没有进行系统性的测试,希望用户能反馈出现的问题。程序存在已知问题如不能区分形如2007-11-13 12:12:00:564这种日期和时间中间有空格的字段,程序会把它们当成两个字段。在未来的改进版本中将处理这个问题。希望用户提出本程序的改进建议,本人不胜感激!联系邮箱:internetroot@hotmail.com
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值