更新永远不会触发插入事件,即使它在物理上被实现为插入/删除,因为逻辑上操作仍然是UPDATE。
如果被认为是在谈论键列的逻辑更新,则接受的答案中有一个短语并不完全正确。
对于更改键值的更新,SQL 不会将其作为
就地更新
这不是针对唯一索引的多行更新的情况。对于那些 SQL Server 提供了一个带有split/sort/collapse 运算符的计划。所以在下面的例子中,9 个更新操作被转换为 1 个删除、8 个更新和一个插入。
CREATE TABLE TestingUpdate7 (
ID INT,
SomeString CHAR(50)
)
CREATE UNIQUE CLUSTERED INDEX idx_ID ON TestingUpdate7 (ID)
INSERT INTO TestingUpdate7 (ID, SomeString)
VALUES
(1,'One'),(2,'Two'),(3,'Three'),(4,'Four'),
(5,'Five'),(6,'Six'),(7,'Seven'),(8,'Eight'),(9,'Nine')
CHECKPOINT -- truncate the log, DB is in simple recovery.
UPDATE TestingUpdate7
SET ID +=1
SELECT Operation, Context, AllocUnitName
FROM fn_dblog(NULL, NULL)
返回
+-----------------+--------------------+---------------------------+
| Operation | Context | AllocUnitName |
+-----------------+--------------------+---------------------------+
| LOP_BEGIN_CKPT | LCX_NULL | NULL |
| LOP_XACT_CKPT | LCX_BOOT_PAGE_CKPT | NULL |
| LOP_END_CKPT | LCX_NULL | NULL |
| LOP_BEGIN_XACT | LCX_NULL | NULL |
| LOP_DELETE_ROWS | LCX_MARK_AS_GHOST | dbo.TestingUpdate7.idx_ID |
| LOP_SET_BITS | LCX_PFS | dbo.TestingUpdate7.idx_ID |
| LOP_MODIFY_ROW | LCX_CLUSTERED | dbo.TestingUpdate7.idx_ID |
| LOP_MODIFY_ROW | LCX_CLUSTERED | dbo.TestingUpdate7.idx_ID |
| LOP_MODIFY_ROW | LCX_CLUSTERED | dbo.TestingUpdate7.idx_ID |
| LOP_MODIFY_ROW | LCX_CLUSTERED | dbo.TestingUpdate7.idx_ID |
| LOP_MODIFY_ROW | LCX_CLUSTERED | dbo.TestingUpdate7.idx_ID |
| LOP_MODIFY_ROW | LCX_CLUSTERED | dbo.TestingUpdate7.idx_ID |
| LOP_MODIFY_ROW | LCX_CLUSTERED | dbo.TestingUpdate7.idx_ID |
| LOP_MODIFY_ROW | LCX_CLUSTERED | dbo.TestingUpdate7.idx_ID |
| LOP_INSERT_ROWS | LCX_CLUSTERED | dbo.TestingUpdate7.idx_ID |
| LOP_COMMIT_XACT | LCX_NULL | NULL |
+-----------------+--------------------+---------------------------+