עדכון עמודות בדירוג

03/02/2011

תגיות: , , ,
אין תגובות

נסתכל בסקריפט הבא:

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

image

הערך הראשון ב-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

image

עדכנו Sub Query בו מופיעה עמודה A המקורית ועמודה מחושבת A_new הכוללת את הערך המעודכן,

וכעת A ו-B יתעדכנו בו זמנית לפי הערך החדש של A.

בבעייה האמיתית החישובים היו כמובן מורכבים יותר והיו יותר שורות, אבל השיטה אותה שיטה.

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *