Sql server 当所有更新都被删除时,更新是否触发插入事件;(re)在SQL Server中插入
据我所知,在SQL Server中更新一行或多行时,记录将被删除并用新值重新插入。因此,这是否意味着会触发INSERT事件,或者只是在更新行时触发更新 编辑:突出显示懒惰读者的主要信息(尽管我建议您阅读下面davek答案中的完整链接详细信息): SQL是否将所有更新都作为拆分更新执行 简言之,答案是: 没有 稍长的回答: 对于更改键值的更新,SQL不会按如下方式执行 就地更新 我认为(拆分为delete+insert)只有在更新需要更新索引时才是正确的。请参阅此链接: 特别是最后一段: 现在我们有一个分割更新。我们有一个删除行和一个 在日志中插入\u行操作。这并不是作为一个到位的解决方案来完成的 那么我们在这里可以得出什么结论呢?SQL是否将所有更新都拆分 更新?应该清楚的是,对于索引键不可用的情况 更改后,SQL可以作为就地更新进行更新。我不打算尝试 并声称它总是会,那将是愚蠢的,有很多 我没有看过的场景(页面拆分和转发行) 这是最明显的),但它可以也将在适当的地方发挥作用 更新。对于更改键值的更新,SQL不会执行这些操作 就地更新。保罗在他的一篇揭穿文章中解释了这一点 不久前—— 我认为(拆分为delete+insert)只有在更新需要更新索引时才是正确的。请参阅此链接: 特别是最后一段: 现在我们有一个分割更新。我们有一个删除行和一个 在日志中插入\u行操作。这并不是作为一个到位的解决方案来完成的 那么我们在这里可以得出什么结论呢?SQL是否将所有更新都拆分 更新?应该清楚的是,对于索引键不可用的情况 更改后,SQL可以作为就地更新进行更新。我不打算尝试 并声称它总是会,那将是愚蠢的,有很多 我没有看过的场景(页面拆分和转发行) 这是最明显的),但它可以也将在适当的地方发挥作用 更新。对于更改键值的更新,SQL不会执行这些操作 就地更新。保罗在他的一篇揭穿文章中解释了这一点 不久前——Sql server 当所有更新都被删除时,更新是否触发插入事件;(re)在SQL Server中插入,sql-server,sql-server-2008,triggers,Sql Server,Sql Server 2008,Triggers,据我所知,在SQL Server中更新一行或多行时,记录将被删除并用新值重新插入。因此,这是否意味着会触发INSERT事件,或者只是在更新行时触发更新 编辑:突出显示懒惰读者的主要信息(尽管我建议您阅读下面davek答案中的完整链接详细信息): SQL是否将所有更新都作为拆分更新执行 简言之,答案是: 没有 稍长的回答: 对于更改键值的更新,SQL不会按如下方式执行 就地更新 我认为(拆分为delete+insert)只有在更新需要更新索引时才是正确的。请参阅此链接: 特别是最后一段: 现在我
更新不会触发插入事件,即使在物理上它是作为插入/删除实现的,因为逻辑上操作仍然是
更新
在被接受的答案中有一个短语,如果被认为是关于键列的逻辑更新,那么它就不太正确
对于更改键值的更新,SQL不会按如下方式执行
就地更新
对于针对唯一索引的多行更新,情况并非如此。对于这些问题,SQL Server提供了一个带有操作员的计划。因此,在下面的示例中,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 |
+-----------------+--------------------+---------------------------+
更新不会触发插入事件,即使在物理上它是作为插入/删除实现的,因为逻辑上操作仍然是
更新
在被接受的答案中有一个短语,如果被认为是关于键列的逻辑更新,那么它就不太正确
对于更改键值的更新,SQL不会按如下方式执行
就地更新
对于针对唯一索引的多行更新,情况并非如此。对于这些问题,SQL Server提供了一个带有操作员的计划。因此,在下面的示例中,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 |
+-----------------+--------------------+---------------------------+
SQL Server有时会设法仍然执行就地更新,即使在逻辑上通过转换操作更改了键列,使键列保持不变,而非键列得到更新。SQL Server有时会设法仍然执行就地更新,即使在逻辑上通过转换操作更改了键列使键列保持不变而非键列更新的操作。