ORA_ROWSCN היא עמודה ווירטואלית (Pseudocolumn) אשר מייצגת את נקודת הזמן האחרונה בה נעשה שינוי מסויים לשורה. עמודה זו היא חלופה נהדרת לפקודת ה ,SELECT FOR UPDATE בצורה זו ניתן לשמור על עקביות מבלי לנעול את השורה. לדוגמא – נוכל להשתמש בה כאשר נרצה להבטיח כי עדכונים על שורה מסויימת יבוצעו על ערכה הנוכחי בלבד, אם ערכה השתנה כתוצאה מפעילות של סשן אחר – שורה זו כבר לא רלוונטית עבורנו.
נייצר טבלה ונתשאל אותה יחד עם עמודת ה ORA_ROWSCN –
HR >CREATE TABLE emp_test AS SELECT * FROM employees WHERE rownum <= 5 ; Table created. HR >SELECT ora_rowscn, employee_id , last_name , first_name , salary , department_id FROM emp_test ; ORA_ROWSCN EMPLOYEE_ID LAST_NAME FIRST_NAME SALARY DEPARTMENT_ID ---------- ----------- ------------- -------------------- ---------- ------------- 2521095 119 Colmenares Karen 2503 30 2521095 120 Weiss Matthew 8003 50 2521095 121 Fripp Adam 8203 50 2521095 122 Kaufling Payam 7903 50 2521095 123 Vollman Shanta 6503 50
נבצע עדכון על אחת השורות ונצפה ב ORA_ROWSCN החדש :
HR >UPDATE emp_test SET salary = salary + 1 WHERE employee_id = 119; 1 row updated. HR >COMMIT ; Commit complete. HR >SELECT ora_rowscn, employee_id , last_name , first_name , salary , department_id FROM emp_test ;
ORA_ROWSCN EMPLOYEE_ID LAST_NAME FIRST_NAME SALARY DEPARTMENT_ID ---------- ----------- ------------ -------------------- ---------- ------------- 2521095 119 Colmenares Karen 2504 30 2521095 120 Weiss Matthew 8003 50 2521095 121 Fripp Adam 8203 50 2521095 122 Kaufling Payam 7903 50 2521095 123 Vollman Shanta 6503 50
שימו לב כי ערך ה ORA_ROWSCN לא השתנה, באופן דיפולטיבי אורקל לא עוקב אחרי שינויי SCN עבור טרנסאקציות שנעשה להם COMMIT ברמת השורה. כדי לשנות זאת, נבנה את הטבלה מחדש יחד עם הפקודה ROWDEPENDENCIES
HR >DROP TABLE emp_test ; Table dropped. HR >CREATE TABLE emp_test ROWDEPENDENCIES AS SELECT * FROM employees WHERE rownum <= 5 ; Table created. HR >SELECT ora_rowscn, employee_id , last_name , first_name , salary , department_id FROM emp_test ; ORA_ROWSCN EMPLOYEE_ID LAST_NAME FIRST_NAME SALARY DEPARTMENT_ID ---------- ----------- ------------- -------------------- ---------- ------------- 2521141 119 Colmenares Karen 2503 30 2521141 120 Weiss Matthew 8003 50 2521141 121 Fripp Adam 8203 50 2521141 122 Kaufling Payam 7903 50 2521141 123 Vollman Shanta 6503 50 HR >UPDATE emp_test SET salary = salary + 1 WHERE employee_id = 119; 1 row updated. HR >COMMIT ; Commit complete. HR >SELECT ora_rowscn, employee_id , last_name , first_name , salary , department_id FROM emp_test ; ORA_ROWSCN EMPLOYEE_ID LAST_NAME FIRST_NAME SALARY DEPARTMENT_ID ---------- ----------- ------------ -------------------- ---------- ------------- 2521155 119 Colmenares Karen 2504 30 2521141 120 Weiss Matthew 8003 50 2521141 121 Fripp Adam 8203 50 2521141 122 Kaufling Payam 7903 50 2521141 123 Vollman Shanta 6503 50
הפעם ניתן לראות כי ערך ה ORA_ROWSCN השתנה עבור אותה שורה.
להלן דוגמא בסיסית של קוד PLSQL אשר משתמש ביכולת ה ORA_ROWSCN על מנת לא לעדכן שורות אשר עודכנו כתוצאה מפעילות של סשן אחר.
DECLARE TYPE emp_rec_type IS RECORD (emp_id employees.employee_id%type, emp_rowscn number); TYPE emp_tab_type IS TABLE OF emp_rec_type INDEX BY binary_integer ; emp_tab emp_tab_type ; BEGIN SELECT employee_id , ora_rowscn BULK COLLECT INTO emp_tab FROM employees WHERE department_id = 50 ; FOR i IN 1..emp_tab.count LOOP UPDATE employees SET salary = salary + 1 WHERE employee_id = emp_tab(i).emp_id AND ora_rowscn = emp_tab(i).emp_rowscn ; IF sql%rowcount = 1 THEN DBMS_OUTPUT.PUT_LINE ('Update Successful - ' || emp_tab(i).emp_id); ELSE DBMS_OUTPUT.PUT_LINE('Update Failed - ' || emp_tab(i).emp_id || ' row updated by another user'); END IF; END LOOP ; COMMIT ; END ;