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. xcode常用的快捷键

    按键 描述 command+[ 左移代码块 command+] 右移代码块 Tab键 接受代码自动完成提示 Esc键 显示代码提示菜单 command+方向left键 移动光标到本行行首 comman ...

  2. [Codeforces]Codeforces Round #490 (Div. 3)

    Mishka and Contest #pragma comment(linker, "/STACK:102400000,102400000") #ifndef ONLINE_JU ...

  3. bindColumn、bindParam与bindValue的区别

    bindColumn:绑定一列到一个 PHP 变量(类似于list()函数为变量赋值) <?php //连接数据库函数 functionconnect() { try { $dbh = new ...

  4. ionic2 打包时报错 file-opener2

    在app自动更新过程中,有用到ionic-native插件:cordova-plugin-file-openner2    添加插件后,打包时有错: FAILURE: Build failed wit ...

  5. Android基础TOP3:Activity的线性,相对,帧和表格布局的概括

    线性布局 LinearLayout: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&q ...

  6. Ajax——异步基础知识(三)

    封装异步请求 1.将函数作为参数进行使用 2.因为获取数据是在一个注册事件中获取的,所以只有事件触发的时候才会调用此函数 <!DOCTYPE html> <html lang=&qu ...

  7. Ubuntu 18.04 安装chrome浏览器

    参考 https://blog.csdn.net/cyem1/article/details/86297197 一分钟安装教程! 1.将下载源加入到系统的源列表(添加依赖) sudo wget htt ...

  8. 00 python基础知识

    ''' ''' print('hello world!') ''' 变量 ''' # 变量的:‘tank’,会在内存中产生一份内存地址 #变量名:相当于一个门牌号,用于与变量进行绑定 # = :用来把 ...

  9. linu下nginx的安装

    这里用到的环境是nginx-1.8.0,linux用的是CentOS-7-x86_64-DVD-1804.iso版本 1   什么是nginx Nginx ("engine x") ...

  10. ES6学习历程(变量的解构赋值)

    一.数组的解构赋值 1.举几个例子足以理解 let [a, b, c] = [1, 2, 3]; a:1;  b:2;  c:3; let [x, , y] = [1, 2, 3];  x:1   y ...