נסתכל בסקריפט הבא:
Create Table #Tbl(A Int, B Int);
Go
Insert Into #Tbl Values(2,5);
Go
Update #Tbl
Set A=10,
B=A*B;
Go
Select *
From #Tbl;
Go
הערך הראשון ב-B היה 5,
ובפקודת ה-Update הוא התעדכן ל-A*B כאשר מדובר בשני הערכים שלפני העדכון.
מה קורה אם רוצים לעדכן את B לפי ערכו החדש של A (הישן היה 2 והחדש 10)?
ברור שכך זה לא יעבוד- בנקודת זמן שלפני העדכון הערכים היו 2 ו-5, ובנקודת הזמן שלאחר העדכון 10 ו-10;
כאשר אין נקודת ביניים בה A כבר התעדכן ו-B טרם..
גם אם ננסה להתחכם ולהשתמש באופרטור NoLock המאפשר לשלוף Dirty Reads לפני שבוצע Commit לטרנזקציה- עדיין לא תהיה נקודת זמן בה A כבר התעדכן ו-B לא.
מה בכל זאת ניתן לעשות, חוץ מאשר לבצע שתי פעולות עדכון?
Drop Table #Tbl;
Go
Create Table #Tbl(A Int, B Int);
Go
Insert Into #Tbl Values(2,5);
Go
Update T
Set A=A_new,
B=A_new*B
From (Select A,
10 A_new,
B
From #Tbl) T;
Go
Select *
From #Tbl;
Go
עדכנו Sub Query בו מופיעה עמודה A המקורית ועמודה מחושבת A_new הכוללת את הערך המעודכן,
וכעת A ו-B יתעדכנו בו זמנית לפי הערך החדש של A.
בבעייה האמיתית החישובים היו כמובן מורכבים יותר והיו יותר שורות, אבל השיטה אותה שיטה.