`

T-SQL查询学习笔记——数据修改

阅读更多
一、插入数据

包括:select into、insert exec、插入新行、带有output的insert、序列机制

1、select into
select into 语句不向调用者返回结果集,而是创建一个包含查询结果集的新表。新表的列沿用查询结果集的列名称、数据类型、可空性以及identity属性。select into 不从查询的源表复制约束、索引、触发器。如果你希望在表中包含与查询的源相同的索引、约束和触发器,你必须在执行完该语句以后再添加

如果源列包含identity属性,目标列中也会包含该属性.如果不想向目标列复制identity属性,对源列做些修改即可。
例如:OrderID+0 as OrderID

SELECT OrderID+0 AS OrderID, CustomerID, EmployeeID, OrderDate,
  RequiredDate, ShippedDate, ShipVia, Freight, ShipName,
  ShipAddress, ShipCity, ShipRegion, ShipPostalCode, ShipCountry
INTO dbo.MyOrders
FROM Northwind.dbo.Orders
WHERE 1 = 2;
GO

提示:假设你要把存储过程或动态批处理的结果集插入到新表,但又不知道它的架构。这时,你可以在select into 语句的from子句中指定openquery,并把自己的服务器看作是一个链接服务器:
exec sp_serveroption <your_server>,'data access',true;
select * into <target_table>
from openquery(<your_server>,'exec{<proc_name>|(<dynamic_batch>)}')

2、insert exec

insert into <target_table> exec{<proc_name>|(<dynamic_batch>)}

3、插入新行
此处只讨论从源表向目标表插入数据,但只筛选目标表不包含其键值得行
--方案一: Insert New Rows From StageCusts
INSERT INTO dbo.MyCustomers(CustomerID, CompanyName, ContactName,
    ContactTitle, Address, City, Region, PostalCode, Country, Phone, Fax)
  SELECT CustomerID, CompanyName, ContactName,
    ContactTitle, Address, City, Region, PostalCode, Country, Phone, Fax
  FROM dbo.StageCusts AS S
  WHERE NOT EXISTS
    (SELECT * FROM dbo.MyCustomers AS T
     WHERE T.CustomerID = S.CustomerID);

--方案二: Insert New Customers From StageOrders using DISTINCT
INSERT INTO dbo.MyCustomers(CustomerID, CompanyName, ContactName,
    ContactTitle, Address, City, Region, PostalCode, Country, Phone, Fax)
  SELECT DISTINCT CustomerID, CompanyName, ContactName,
    ContactTitle, Address, City, Region, PostalCode, Country, Phone, Fax
  FROM dbo.StageOrders AS S
  WHERE NOT EXISTS
    (SELECT * FROM dbo.MyCustomers AS T
     WHERE T.CustomerID = S.CustomerID);

--方案三: Insert New Customers From StageOrders using MIN
INSERT INTO dbo.MyCustomers(CustomerID, CompanyName, ContactName,
    ContactTitle, Address, City, Region, PostalCode, Country, Phone, Fax)
  SELECT CustomerID, CompanyName, ContactName,
    ContactTitle, Address, City, Region, PostalCode, Country, Phone, Fax
  FROM dbo.StageOrders AS S
  WHERE NOT EXISTS
    (SELECT * FROM dbo.MyCustomers AS T
     WHERE T.CustomerID = S.CustomerID)
    AND S.OrderID = (SELECT MIN(OrderID) FROM dbo.StageOrders AS S2
                     WHERE S2.CustomerID = S.CustomerID);

--方案四: Insert New Customers From StageOrders using Row Numbers
INSERT INTO dbo.MyCustomers(CustomerID, CompanyName, ContactName,
    ContactTitle, Address, City, Region, PostalCode, Country, Phone, Fax)
  SELECT CustomerID, CompanyName, ContactName,
    ContactTitle, Address, City, Region, PostalCode, Country, Phone, Fax
  FROM (SELECT
          ROW_NUMBER() OVER(PARTITION BY CustomerID ORDER BY OrderID) AS rn,
          CustomerID, CompanyName, ContactName, ContactTitle, Address, City,
          Region, PostalCode, Country, Phone, Fax
        FROM dbo.StageOrders) AS S
  WHERE NOT EXISTS
    (SELECT * FROM dbo.MyCustomers AS T
     WHERE T.CustomerID = S.CustomerID)
    AND rn = 1;
GO

4、带有output的insert
通过使用新的output子句,Sql Server 2005支持从数据修改语句中返回输出
例子:
IF OBJECT_ID('dbo.CustomersDim') IS NOT NULL
  DROP TABLE dbo.CustomersDim;
GO

CREATE TABLE dbo.CustomersDim
(
  KeyCol      INT          NOT NULL IDENTITY PRIMARY KEY,
  CustomerID  NCHAR(5)     NOT NULL,
  CompanyName NVARCHAR(40) NOT NULL,
  /* ... other columns ... */
);

-- Insert New Customers and Get their Surrogate Keys
DECLARE @NewCusts TABLE
(
  CustomerID NCHAR(5) NOT NULL PRIMARY KEY,
  KeyCol     INT      NOT NULL UNIQUE
);

INSERT INTO dbo.CustomersDim(CustomerID, CompanyName)
    OUTPUT inserted.CustomerID, inserted.KeyCol
    INTO @NewCusts
    --OUTPUT inserted.CustomerID, inserted.KeyCol
  SELECT CustomerID, CompanyName
  FROM Northwind.dbo.Customers
  WHERE Country = N'UK';

SELECT CustomerID, KeyCol FROM @NewCusts;
GO

二、删除数据
1、truncate 和 delete
如果你要从表中移除所有行,应该使用truncate table,而不应该使用不带where子句的delete。delete总是被完整的记录到日志,而truncate table总是按最小方式被记录到日志

truncate table 和 delete 除了在性能方面有巨大差异外,它们对identity属性的处理方式也不同.truncate table 把identity属性重置为最初的种子,而delete则不会
2、移除包含重复数据的行

解决方案一:要求整行都重复
SELECT DISTINCT * INTO dbo.OrdersTmp FROM dbo.OrdersDups;
DROP TABLE dbo.OrdersDups;
EXEC sp_rename 'dbo.OrdersTmp', 'OrdersDups';

解决方案二:要求表中有唯一标识符
DELETE FROM dbo.OrdersDups
WHERE EXISTS
  (SELECT *
   FROM dbo.OrdersDups AS O2
   WHERE O2.OrderID = dbo.OrdersDups.OrderID
     AND O2.KeyCol > dbo.OrdersDups.KeyCol);
GO

解决方案三:要求表中有唯一标识符
SELECT O.OrderID, CustomerID, EmployeeID, OrderDate, RequiredDate,
  ShippedDate, ShipVia, Freight, ShipName, ShipAddress, ShipCity,
  ShipRegion, ShipPostalCode, ShipCountry
INTO dbo.OrdersTmp
FROM dbo.OrdersDups AS O
  JOIN (SELECT OrderID, MAX(KeyCol) AS mx
        FROM dbo.OrdersDups
        GROUP BY OrderID) AS U
    ON O.OrderID = U.OrderID
    AND O.KeyCol = U.mx;

DROP TABLE dbo.OrdersDups;
EXEC sp_rename 'dbo.OrdersTmp', 'OrdersDups';

解决方案四:用cte和row_number函数实现一种快速的解决方案

WITH Dups AS
(
  SELECT *,
    ROW_NUMBER() OVER(PARTITION BY OrderID ORDER BY OrderID) AS rn
  FROM dbo.OrdersDups
)
DELETE FROM Dups WHERE rn > 1;
GO
3、基于联接的delete

--非标准查询
BEGIN TRAN

DELETE FROM OD
FROM dbo.[Order Details] AS OD
  JOIN dbo.Orders AS O
    ON OD.OrderID = O.OrderID
WHERE O.OrderDate >= '19980506';

ROLLBACK TRAN

--标准查询
BEGIN TRAN

DELETE FROM dbo.[Order Details]
WHERE EXISTS
  (SELECT *
   FROM dbo.Orders AS O
   WHERE O.OrderID = dbo.[Order Details].OrderID
     AND O.OrderDate >= '19980506');

ROLLBACK TRAN
GO
4、带有output的delete

例子:
WHILE 1=1
BEGIN
  BEGIN TRAN
    DELETE TOP(5000) FROM dbo.LargeOrders
      OUTPUT deleted.* INTO dbo.OrdersArchive
    WHERE OrderDate < '20010101';

    IF @@rowcount < 5000
    BEGIN
      COMMIT TRAN
      BREAK;
    END
  COMMIT TRAN
END
GO

三、更新数据
1、基于联接的update
例子:
方案一:
  UPDATE O
    SET ShipCountry = C.Country,
        ShipRegion = C.Region,
        ShipCity = C.City
  FROM dbo.Orders AS O
    JOIN dbo.Customers AS C
      ON O.CustomerID = C.CustomerID
  WHERE C.Country = 'USA';
方案二:
WITH UPD_CTE AS
(
  SELECT
    O.ShipCountry AS set_Country, C.Country AS get_Country,
    O.ShipRegion  AS set_Region,  C.Region  AS get_Region,
    O.ShipCity    AS set_City,    C.City    AS get_City
  FROM dbo.Orders AS O
    JOIN dbo.Customers AS C
      ON O.CustomerID = C.CustomerID
  WHERE C.Country = 'USA'
)
UPDATE UPD_CTE
  SET set_Country = get_Country,
      set_Region  = get_Country,
      set_City    = get_City;
2、select和update赋值语句
赋值select
如果表中没有记录则为null,如果有多条记录则为最后一跳记录的值
DECLARE @EmpID AS INT, @Pattern AS NVARCHAR(100);

SET @Pattern = N'Davolio'; -- Try also N'Ben-Gan', N'D%';
SET @EmpID = 999;

SET @EmpID = (SELECT EmployeeID
              FROM dbo.Employees
              WHERE LastName LIKE @Pattern);

SELECT @EmpID;
GO

赋值update
CREATE TABLE dbo.T1
(
  col1 INT        NOT NULL,
  col2 VARCHAR(5) NOT NULL
);

INSERT INTO dbo.T1(col1, col2) VALUES(0, 'A');
INSERT INTO dbo.T1(col1, col2) VALUES(0, 'B');
INSERT INTO dbo.T1(col1, col2) VALUES(0, 'C');
INSERT INTO dbo.T1(col1, col2) VALUES(0, 'C');
INSERT INTO dbo.T1(col1, col2) VALUES(0, 'C');
INSERT INTO dbo.T1(col1, col2) VALUES(0, 'B');
INSERT INTO dbo.T1(col1, col2) VALUES(0, 'A');
INSERT INTO dbo.T1(col1, col2) VALUES(0, 'A');
INSERT INTO dbo.T1(col1, col2) VALUES(0, 'C');
INSERT INTO dbo.T1(col1, col2) VALUES(0, 'C');
go
方案一:
DECLARE @i AS INT;
SET @i = 0;
UPDATE dbo.T1 SET @i = col1 = @i + 1;
逻辑上,这个set语句等价于set col1=@i+1,@i=@i+1
在update语句中,你无法控制T1中的行被扫描和修改的顺序
GO
方案二:
-- SQL Server 2005
WITH T1RN AS
(
  SELECT col1, ROW_NUMBER() OVER(ORDER BY col2) AS RowNum
  FROM dbo.T1
)
UPDATE T1RN SET col1 = RowNum;
GO
分享到:
评论

相关推荐

    Microsoft SQL Server 2008技术内幕:T-SQL查询

    主要内容包括SQL的基础理论、查询优化、查询算法及复杂度,以及在使用子查询、表表达式、排名函数、数据聚合和透视转换、TOP和APPLY、数据修改、分区表、特殊数据结构等实际应用时会遇到的各种高级查询问题和解决...

    Microsoft SQL Server 2008技术内幕:T-SQL查询.pdf

    《Microsoft SQL Server 2008技术内幕:T-SQL查询》是一本深入探讨SQL Server 2008中T-SQL(Transact-SQL)查询的权威指南。T-SQL是微软SQL Server数据库管理系统的核心语言,用于数据操作、查询、存储过程编写以及...

    Microsoft SQL Server 2008技术内幕:T-SQL查询_源代码及附录.zip

    《Microsoft SQL Server 2008技术内幕:T-SQL查询》是一本深入探讨SQL Server 2008中T-SQL(Transact-SQL)查询的权威书籍。T-SQL是SQL Server数据库管理系统的核心语言,用于数据操作、查询、存储过程编写以及...

    T-SQL性能调优秘笈 基于SQL Server2012窗口函数.rar

    1、处理常见业务问题,如总计、间隔、...3、T-SQL性能调优秘笈:基于SQL Server 2012窗口函数》基于SQLServer2012,讨论了SQL窗口、窗口函数、排序集合函数、窗口函数的优化以及利用窗口函数的T-SQL解决方案等内容。

    Microsoft SQL Server 2008技术内幕:T-SQL查询

    主要内容包括SQL的基础理论、查询优化、查询算法及复杂度,以及在使用子查询、表表达式、排名函数、数据聚合和透视转换、TOP和APPLY、数据修改、分区表、特殊数据结构等实际应用时会遇到的各种高级查询问题和解决...

    T-SQL性能调优秘笈 基于SQL Server 2012窗口函数 源码和示例数据库

    文件列表 Chapter 01 - SQL Windowing.sql Chapter 02 - A Detailed Look at Window Functions.sql Chapter 03 - Ordered Set Functions.sql ...Chapter 05 - T-SQL Solutions using Window Functions.sql TSQL2012.sql

    sql server 2012 T-SQl基础教程 源码和示例数据库

    5. **Chapter 08 - Data Modification**:这一部分聚焦于如何使用T-SQL修改数据,包括INSERT语句来插入新记录,UPDATE用于更新现有记录,以及DELETE语句用于删除数据。同时会涉及数据完整性与事务处理。 6. **...

    Inside Microsoft SQL Server 2008 T-SQL Programming.pdf

    ### 关于《Inside Microsoft SQL Server 2008 T-SQL Programming》的知识点解析 #### 一、SQL Server 2008概述 《Inside Microsoft SQL Server 2008 T-SQL Programming》这本书深入地介绍了SQL Server 2008的各项...

    t-sql学习笔记

    t-sql学习笔记,总结的挺好

    Microsoft SQL SERVER 2008技术内幕 T-SQL查询

    主要内容包括SQL 的基础理论、查询优化、查询算法及复杂度,以及在使用子查询、表表达式、排名函数、数据聚合和透视转换、TOP 和APPLY、数据修改、分区表、特殊数据结构等实际应用时会遇到的各种高级查询问题和解决...

    Microsoft+SQL+Server+2008技术内幕:T-SQL查询

    标题中提到的“Microsoft SQL Server 2008技术内幕:T-SQL查询”指向了两方面的知识内容:一是Microsoft SQL Server数据库管理系统,二是T-SQL(Transact-SQL)语言,这是SQL Server中用于数据操作和管理的专有扩展...

    T-SQL课件(介绍了T-SQL的一些基本知识)

    掌握T-SQL的基本知识对于任何需要与SQL Server交互的开发者来说都是至关重要的,无论是进行简单的数据查询还是构建复杂的业务应用程序。学习T-SQL的这些基础知识将有助于理解如何有效地管理和操作数据库,以及如何...

    T-SQL示例大全(全是T-SQL语句 )

    T-SQL,全称Transact-SQL,是SQL语言的一个扩展,主要用于Microsoft SQL Server数据库管理系统。它是数据库查询、数据更新、事务...通过学习和实践这些示例,你可以深入了解T-SQL的强大功能,并提升数据库管理技能。

    《Microsoft SQL Server 2005技术内幕:T-SQL查询》示例代码

    T-SQL(Transact-SQL)是微软对标准SQL的扩展,是SQL Server的核心组件,用于数据库管理、数据查询和程序开发。这本书的主要目标是帮助读者掌握T-SQL查询的各种技巧和最佳实践,以提升在SQL Server环境中的数据处理...

    Microsoft+SQL+Server+2008技术内幕:T-SQL查询_源代码及附录A

    通过深入学习《Microsoft SQL Server 2008技术内幕:T-SQL查询》这本书,读者将能够熟练地使用T-SQL进行数据查询、操作和分析,从而更好地应对实际工作中的挑战。书中的源代码和附录A提供了丰富的实践示例,进一步...

    T-SQL核对清单——13条卓有成效的T-SQL实践.pdf

    T-SQL核对清单提供了13条实践建议,旨在提升数据库开发人员使用T-SQL(Transact-SQL,SQL Server中的SQL语言版本)进行数据处理时的效率与代码质量。以下是这些实践知识点的详细说明: 1. 使用基于集的解决方案:T-...

    Inside Microsoft SQL Server 2008 T-SQL Programming

    T-SQL,即Transact-SQL,是SQL的一个扩展,主要用于微软的SQL Server系统中,用于数据查询、更新、插入和删除,以及复杂的存储过程和触发器的编写。 在SQL Server 2008版本中,T-SQL得到了许多增强和改进,这本书将...

    Transact-SQL元编程——用T-SQL生成T-SQL.pdf

    元数据函数可以将对象ID转换为名称,或由对象名称反查对象ID,大大简化了SQL查询的复杂性。比如,可以不必通过sys.tables视图,直接通过sys.key_constraints视图列出每个表的主键信息。 Transact-SQL元编程的实际...

    T-SQL用户指南&T-SQL用户手册打包下载

    这个压缩包文件“T-SQL”包含了全面的T-SQL用户指南和参考手册,是学习和深入理解T-SQL的重要资源。 T-SQL不仅仅是SQL的基础语法,它还提供了更丰富的功能,如流程控制、变量定义、函数使用、存储过程以及触发器等...

    T-SQL性能调优秘笈 基于SQL Server 2012窗口函数_PDF电子书

    T-SQL性能调优是一项复杂但重要的任务,尤其是在处理大量数据时。合理利用窗口函数可以极大地简化查询逻辑,而通过实施有效的性能调优策略,则能够确保查询执行的高效性。此外,持续监控系统性能并通过调整索引、...

Global site tag (gtag.js) - Google Analytics