Sql-Server
如果在更新或刪除之前存在?
- 在我寫一個更新語句之前,我應該檢查它是否存在?
有人告訴我這樣做
- 因此它避免了無用地寫入事務日誌以獲取已經存在的值,
- 並且只需要一個允許其他讀取的共享鎖而不是排他鎖。
他們說想像一個事務像這樣針對不同的值多次執行,你將一直使用排他鎖而不是共享鎖。 3. 同事提到,看鎖兼容性圖表,搜尋時不能有兩個更新鎖,但是可以有兩個共享鎖。因此,當“搜尋要更新的行”沒有要更新的值時,虛假的更新鎖可能會阻止真正的更新。有人可以使此聲明無效嗎?
if not exists ( select FavoriteColor from dbo.Person where Name = 'Bob' and FavoriteColor = 'Green' ) update dbo.Person set FavoriteColor = 'Green' where Name = 'Bob'
2. 同樣的問題,除了現在刪除,我應該檢查它是否存在嗎?
if exists ( select FavoriteColor from dbo.Person where Name = ‘Bob’ and FavoriteColor = ‘Green’ ) delete dbo.Person where Name = ‘Bob’ and FavoriteColor = ‘Green’
我們使用 SQL Server 2016。
通常,這種模式效率更高,並且不太可能導致死鎖或其他並發問題:
UPDATE dbo.Person SET FavoriteColor = 'Green' WHERE Name = 'Bob' AND COALESCE(FavoriteColor, '') <> 'Green'; DELETE dbo.Person WHERE Name = 'Bob' AND FavoriteColor = 'Green';
…僅僅是因為您只需檢查該行一次。你也可以這樣寫
UPDATE
:UPDATE dbo.Person SET FavoriteColor = 'Green' WHERE Name = 'Bob' AND (FavoriteColor IS NULL OR FavoriteColor <> 'Green');
…在某些情況下可能對索引更友好。
直到實際更新要修改的行之前,才會使用寫操作的排他鎖。當 SQL Server搜尋要更新的行時,它使用更新鎖,這與並發讀取不衝突。如果 SQL Server 確定正在檢查的行不符合更新條件,則會立即釋放更新鎖。
我能想到使用該
if exists
方法的唯一原因是UPDATE/DELETE
表中是否存在您希望避免被觸發的觸發器,特別是如果您有INSTEAD OF
觸發器可以在實際嘗試任何更新或刪除之前採取一些操作。通常最好編寫 DML,以便只影響需要更改的行。