UPDATE语句原来还有许多种写法,有的还很复杂,孤陋寡闻的我甚至闻所未闻。幸甚至哉,记而志之。

0、UPDATE 表名 SET 字段。。。 FROM 。。。的方式

USE AdventureWorks2012;
GO
UPDATE Production.ScrapReason
SET Name += ' - tool malfunction'
FROM Production.ScrapReason AS sr
JOIN Production.WorkOrder AS wo 
     ON sr.ScrapReasonID = wo.ScrapReasonID
     AND wo.ScrappedQty > 300;

就是需要联合其他表进行一些条件过滤的时候,可以采用这种方式。删除语句更厉害,有delete from ... from ... 的格式。第一个from是delete语句必须的,第二个from是用于联合其他表进行条件过滤。
WITH w AS(        
        SELECT Id,ROW_NUMBER() OVER(ORDER BY Id DESC) AS [Row]
        FROM [t1]
        WHERE Code=@Code
    )
    DELETE FROM t1 FROM t1 s INNER JOIN w ON s.Id=w.Id
    WHERE w.Row>100;

这种格式中,表名也可以采用别名:
USE AdventureWorks2012;
GO
UPDATE sr
SET sr.Name += ' - tool malfunction'
FROM Production.ScrapReason AS sr
JOIN Production.WorkOrder AS wo 
     ON sr.ScrapReasonID = wo.ScrapReasonID
     AND wo.ScrappedQty > 300;

1、使用TOP语句
USE AdventureWorks2012;
GO
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25 ;
GO

2、使用 WITH common_table_expression 子句
USE AdventureWorks2012;
GO
WITH Parts(AssemblyID, ComponentID, PerAssemblyQty, EndDate, ComponentLevel) AS
(
    SELECT b.ProductAssemblyID, b.ComponentID, b.PerAssemblyQty,
        b.EndDate, 0 AS ComponentLevel
    FROM Production.BillOfMaterials AS b
    WHERE b.ProductAssemblyID = 800
          AND b.EndDate IS NULL
    UNION ALL
    SELECT bom.ProductAssemblyID, bom.ComponentID, p.PerAssemblyQty,
        bom.EndDate, ComponentLevel + 1
    FROM Production.BillOfMaterials AS bom 
        INNER JOIN Parts AS p
        ON bom.ProductAssemblyID = p.ComponentID
        AND bom.EndDate IS NULL
)
UPDATE Production.BillOfMaterials
SET PerAssemblyQty = c.PerAssemblyQty * 2
FROM Production.BillOfMaterials AS c
JOIN Parts AS d ON c.ProductAssemblyID = d.AssemblyID
WHERE d.ComponentLevel = 0; 
parts是这个公用表表达式里的表名,括号里的是字段别名。

3、使用包含 .WRITE 的 UPDATE
USE AdventureWorks2012;
GO
UPDATE Production.Document
SET DocumentSummary .WRITE(N'Carefully inspect and maintain the tires and crank arms.',0,NULL)
WHERE Title = N'Crank Arm and Tire Maintenance';

.WRITE (expression,@Offset,@Length)
指定修改 column_name 值的一部分。 expression 替换 @Length 单位(从 column_name 的 @Offset 开始)。 只有varchar(max)、nvarchar(max) 或 varbinary(max) 列才能使用此子句来指定。 column_name 不能为 NULL,也不能由表名或表别名限定。
expression 是复制到 column_name 的值。 expression 必须运算或隐式转换为 column_name 类型。 如果将 expression 设置为 NULL,则忽略@Length,并将 column_name 中的值按指定的 @Offset 截断。
@Offset 是 column_name 值中的起点,从该点开始编写 expression。 @Offset 是基于零的序号位置,数据类型为 bigint,不能为负数。 如果@Offset 为 NULL,则更新操作将在现有 column_name 值的结尾追加 expression,并忽略 @Length。 如果 @Offset 大于 column_name 值的长度,则数据库引擎将返回错误。 如果 @Offset 加上 @Length 超出了列中基础值的限度,则将删除到值的最后一个字符。 如果 @Offset 加上 LEN(expression) 大于声明的基础大小,则将出现错误。
@Length 是指列中某个部分的长度,从 @Offset 开始,该长度由 expression 替换。 @Length 是 bigint 并且不能为负数。 如果 @Length 为 NULL,则更新操作将删除从 @Offset 到 column_name 值的结尾的所有数据。

4、使用包含 OPENROWSET 的 UPDATE 修改 varbinary(max) 列
以下示例将 varbinary(max) 列中存储的现有图像替换为新图像。 将 OPENROWSET 函数和 BULK 选项一起使用以将图像加载到列中。 此示例假定指定的文件路径中存在名为 Tires.jpg 的文件。
USE AdventureWorks2012;
GO
UPDATE Production.ProductPhoto
SET ThumbNailPhoto = (
    SELECT *
    FROM OPENROWSET(BULK 'c:\Tires.jpg', SINGLE_BLOB) AS x )
WHERE ProductPhotoID = 1;
GO

5、捕获 UPDATE 语句的结果
USE AdventureWorks2012;
GO
DECLARE @MyTableVar table(
    EmpID int NOT NULL,
    OldVacationHours int,
    NewVacationHours int,
    ModifiedDate datetime);
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25,
    ModifiedDate = GETDATE() 
OUTPUT inserted.BusinessEntityID,
       deleted.VacationHours,
       inserted.VacationHours,
       inserted.ModifiedDate
INTO @MyTableVar;

--Display the result set of the table variable.
SELECT EmpID, OldVacationHours, NewVacationHours, ModifiedDate
FROM @MyTableVar;
GO

--Display the result set of the table.
SELECT TOP (10) BusinessEntityID, VacationHours, ModifiedDate
FROM HumanResources.Employee;
GO

inserted、deleted都是触发器中常用到的系统表。
inserted:当有新记录被INSERT,或原表中有记录被UPDATE,那么这些新记录会拷贝一份到inserted;
deleted:当记录被update、delete,那么会从原表中拷贝一份到deleted表,然后原表中的记录被修改、删除;

6、UPDATE使用CASE语句
UPDATE [Table1]
        SET [StatuID] = CASE WHEN  [StatuID] - 1 < 0 THEN 0 ELSE [StatuID] - 1 END
        WHERE [IndexId] = @IndexId;

7、在 TRY…CATCH 块中使用 UPDATE
以下示例在 TRY…CATCH 块中使用 UPDATE 语句来处理在执行更新操作期间可能遇到的执行错误。
USE AdventureWorks2012;
GO
BEGIN TRANSACTION;
BEGIN TRY
    -- Intentionally generate a constraint violation error.
    UPDATE HumanResources.Department
    SET Name = N'MyNewName'
    WHERE DepartmentID BETWEEN 1 AND 2;
END TRY
BEGIN CATCH
    SELECT 
         ERROR_NUMBER() AS ErrorNumber
        ,ERROR_SEVERITY() AS ErrorSeverity
        ,ERROR_STATE() AS ErrorState
        ,ERROR_PROCEDURE() AS ErrorProcedure
        ,ERROR_LINE() AS ErrorLine
        ,ERROR_MESSAGE() AS ErrorMessage;
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;
END CATCH;
IF @@TRANCOUNT > 0
    COMMIT TRANSACTION;
GO

这种语句,主要是看看里面这些系统函数的用法。

8、使用 WHERE CURRENT OF 子句

以下示例使用 WHERE CURRENT OF 子句来只更新游标位于其上的行。 如果游标基于某个联接,则只修改 UPDATE 语句中指定的 table_name。 其他参与该游标的表不会受到影响。

USE AdventureWorks2012;
GO
DECLARE complex_cursor CURSOR FOR
SELECT a.BusinessEntityID
FROM HumanResources.EmployeePayHistory AS a
WHERE RateChangeDate <>
(SELECT MAX(RateChangeDate)
FROM HumanResources.EmployeePayHistory AS b
WHERE a.BusinessEntityID = b.BusinessEntityID) ;
OPEN complex_cursor;
FETCH FROM complex_cursor;
UPDATE HumanResources.EmployeePayHistory
SET PayFrequency = 2
WHERE CURRENT OF complex_cursor;
CLOSE complex_cursor;
DEALLOCATE complex_cursor;
GO

按我的理解,游标相当于DataReader,逐行读取,并且保持数据库连接。针对游标中的行进行修改,会直接投射到数据库中,改游标其实就相当于改数据库。

UPDATE语句的写法还有很多,以上只是摘录一二而已。

学习笔记—— 一些UPDATE语句的更多相关文章

  1. 【SQL Server学习笔记】Delete 语句、Output 子句、Merge语句

    原文:[SQL Server学习笔记]Delete 语句.Output 子句.Merge语句 DELETE语句 --建表 select * into distribution from sys.obj ...

  2. CUBRID学习笔记 44 UPDATE 触发器 更新多表 教程

    cubrid的中sql查询语法UPDATE c#,net,cubrid,教程,学习,笔记欢迎转载 ,转载时请保留作者信息.本文版权归本人所有,如有任何问题,请与我联系wang2650@sohu.com ...

  3. 【初学Java学习笔记】SQL语句调优

    1, 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2,应尽量避免在 where 子句中对字段进行 null 值判断,创建表时NULL是默认 ...

  4. mysql学习笔记—常用sql语句

    sql注意事项: SQL 对大小写不敏感:SELECT 与 select 是相同的 某些数据库系统要求在每条 SQL 语句的末端使用分号. CREATE DATABASE CREATE DATABAS ...

  5. MongoDB学习笔记~使用原生语句实现三层集合关系的更新

    回到目录 MongoDB的文档型数据结构使得它在存储数据上很像JSON,在可读性方面很强,然而这种复杂的结构在update时相对麻烦一些,而对于官方给出的文档说的也不够细致,有些东西也是模棱两可的态度 ...

  6. MySQL语法大全_自己整理的学习笔记(MySQL语句 整理二)

    select * from emp; #注释 #--------------------------- #----命令行连接MySql--------- #启动mysql服务器 net start m ...

  7. Java 学习笔记(2)——基本语句、控制结构

    上一篇中简单谈了一下自己对Java的一些看法并起了一个头,现在继续总结java的相关语法.java语法总体上与C/C++一样,所以对于一个C/C++程序员来说,天生就能看懂Java代码.在学习java ...

  8. python 2.7 学习笔记--day1--基础语句和语法

    1. 用户交互 鉴于本小节十分的基础,变不多做赘述啦! 1.1 输出第一个程序:"Hello World !" 1.2 输出字符串,重点是去除字符串中的前后的空格,使用strip( ...

  9. linQ学习笔记之三高级语句

    linq语句查询执行的时机 第一步获取数据源 int [] obejct = new int[]{1,2,3,4,5,6,7,8,9} 第二步定义查询 var even = numbers.where ...

随机推荐

  1. 转 方法区(method) )、栈区(stack)和堆区(heap)之JVM 内存初学

    JAVA的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method) 堆区: 1.存储的全部是对象,每个对象都包含一个与之对应的class的信息.(class的目的是得到操作指 ...

  2. P2871 [USACO07DEC]手链Charm Bracelet

    题目描述 Bessie has gone to the mall's jewelry store and spies a charm bracelet. Of course, she'd like t ...

  3. pd_ds 之 hash

    http://attack.cf/?post=23 打个广告....

  4. Oracle12C用户创建、授权、登录

    Oracle12C用户创建.授权.登录 1.以系统用户登录 C:\Users\LEI>sqlplus sys/dwh as sysdba; SQL*Plus: Release 12.1.0.2. ...

  5. Android 将图片网址url转化为bitmap

    public Bitmap returnBitMap(final String url){ new Thread(new Runnable() { @Override public void run( ...

  6. 六时出行 App 隐私政策

    六时出行 App 隐私政策   本应用尊重并保护所有使用服务用户的个人隐私权.为了给您提供更准确.更有个性化的服务,本应用会按照本隐私权政策的规定使用和披露您的个人信息.但本应用将以高度的勤勉.审慎义 ...

  7. Resetting the SMC & PRAM

    Resetting the SMC & PRAM on portables with a battery you should not remove on your own 1. Shut d ...

  8. 微信小程序支付(JSAPI支付)

    开发环境:.NET MVC+ ORM框架(EF) 一.参考文档: 1.微信JSAPI支付官方文档:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api. ...

  9. ajax 禁用按钮防止重复提交

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  10. 二、Scrapy命令行工具

    本文转载自以下链接:https://scrapy-chs.readthedocs.io/zh_CN/latest/topics/commands.html Scrapy是通过 scrapy 命令行工具 ...