SQL Server如何判断update语句中要更新的值和原值相同? 经过测试发现,如果update语句中新的值和原值相同,则不会做更新操作,问题是,SQL Serve判断新值和原值相同的机制是什么? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 update tb set col=@var where col!=@var 这个不难理解,scan时比较值就行了。 可是用update()测试还是true 1. UPDATE() 返回一个布尔值,指示是否对表或视图的指定列进行了 INSERT 或 UPDATE 尝试。UPDATE() 返回 TRUE,不考虑 INSERT 或 UPDATE 尝试是否成功。2. 如果一条被更新的记录的原值与要更新的值相同,即更新操作的前值与后值相同,则该更新操作不会记入日志,当事务提交时也不会写到磁盘中数据页中。换言之,只有数据发生变化,操作才会写入记录到日志文件并修改到数据页。(归纳出的结论,未找到明确的文档依据)3. 如果被修改的字段不是聚集索引键,或者是聚集索引键但修改后的记录不改变在聚集索引中的位置,则更新数据页的操作是覆盖更新,且只修改相关字段的对应字节;如果该字段是聚焦索引键,并且修改后的记录需要改变记录在聚集索引中的位置,则会删除原记录再添加新记录到新的位置。4. 只有数据发生变化,执行该操作的事务才会申请排他锁,并且默认是行级锁,当更新的记录数比较多的时候也可能是页级锁或表级锁。 又做了一次测试,发现如果表中有TimeStamp字段,则该字段依然会被自动更新,数据库日志中会记录改更新操作。如有一条记录ID Name TS1 ‘A' 0000ABCDUpdate Tset Name=’A'where ID=1执行后TS可能会变为0000CDEF同时数据库日志会记录该更新操作 我个人感觉,不论值等或不等,Updated里的set赋值是无论如何都要执行的,有新的log生成就是最好证明。至于内部机制而言,1,对update语句做先初步编译,判断语句有没有语法错误,做语法分解2,深入编译检查索引或约束,设定涉及的字段,以作备用(Update简单分解相当于先查询再赋值)3,然后是update动作分解先对目标表根据索引做整体扫描,当然输出只要深入编译时设定的字段4,再做默认排序(即使随便一个查询也是有默认排序的)5,根据条件匹配索引,检索出所要的记录数备用6,执行语句对表内数据更新,即使数据一样也是把一样的数据覆盖(至于物理上具体有没有先开辟一个空间存放一样的新值,把字段有效地指出指向新的数据位置还是直接覆盖就不得而知了)7,程序返回结束提示(可省略)这些应该都是在内存中进行的就是逻辑上的,只有执行更新过后才实际操作物理磁盘 关于数据按照时间排列(非查询之后) 请人帮忙改一个触发器 再发一贴:如何将某列值作为查询内容?期望高手现身~! 这样的sql语句应该怎样来写呢 用语句可以彻底删除xp_cmdshell? [求]SQL高手写个查询语句 请教 nolock和noholdlock的区别 关于执行计划的疑问 高手们在那?求一sql查询语句(比较复杂) 关于sql server中的事务 触发器问题,不插入重复数据 Declare @sql varchar(200) Set @sql='Select ID,Name from USER' 怎么在存储过程里循环结果,游标不行
可是用update()测试还是true
如有一条记录
ID Name TS
1 ‘A' 0000ABCDUpdate T
set Name=’A'
where ID=1执行后TS可能会变为0000CDEF同时数据库日志会记录该更新操作
至于内部机制而言,
1,对update语句做先初步编译,判断语句有没有语法错误,做语法分解
2,深入编译检查索引或约束,设定涉及的字段,以作备用(Update简单分解相当于先查询再赋值)
3,然后是update动作分解先对目标表根据索引做整体扫描,当然输出只要深入编译时设定的字段
4,再做默认排序(即使随便一个查询也是有默认排序的)
5,根据条件匹配索引,检索出所要的记录数备用
6,执行语句对表内数据更新,即使数据一样也是把一样的数据覆盖(至于物理上具体有没有先开辟一个空间存放一样的新值,把字段有效地指出指向新的数据位置还是直接覆盖就不得而知了)
7,程序返回结束提示(可省略)
这些应该都是在内存中进行的就是逻辑上的,只有执行更新过后才实际操作物理磁盘