در نسخه 12c، اوراکل با ارائه تابع STANDARD_HASH، امکان محاسبه hash value را برای یک فیلد و یا عبارت فراهم کرده است:
SQL> select id,salary,substr(STANDARD_HASH(id||salary),1,20) hash_id_sal from tbl1; ID SALARY HASH_ID_SAL ---------- ---------- ---------------------- 1 10 5E796E48332AF4142B10 2 12 E2154FEA5DA2DD0D1732 3 17 F44A286F486D11990238 4 18 93AC1946CB917ABC4735
با این روش می توانیم از تغییر مقدار سطرهای جدول باخبر شویم. البته در نسخه های قبل از 12c هم می توانستیم از توابع دیگری نظیر ora_hash بدین منظور استفاده کنیم:
SQL> select id,salary,ora_hash(id||salary) hash_id_sal from tbl1; ID SALARY HASH_ID_SAL ---------- ---------- ----------- 1 10 3316966336 2 12 1402677848 3 17 3795753203 4 18 936769390
در نسخه 21c هم قابلیت جدیدی در این زمینه ارائه شد و اوراکل با معرفی تابع checksum، امکان شناسایی تغییر دیتا را در سطح ستون فراهم کرده است.
از طریق این تابع می توانیم برای هر ستون یک checksum ایجاد کنیم تا در صورت تغییر در هر یک از فیلدهای آن ستون، از طریق checksum ایجاد شده متوجه این تغییر شویم. البته با جابجایی مقادیر بین فیلدهای یک ستون، عدد checksum مربوط به آن ستون تغییر نخواهد کرد!
برای آشنایی بیشتر با این تابع، اطلاعات زیر را در نظر بگیرید:
SQL> select * from tbl1; ID NAME SALARY ---------- -------------- ---------- 1 vahid 10 2 ali 12 3 sima 17 4 nima 18
با دستور زیر checksum ستونهای id و salary را محاسبه می کنیم:
SQL> select checksum(id),checksum(salary) CH_SAL from tbl1; CHECKSUM(ID) CH_SAL ------------ ---------- 496078 567030
با کوچکترین تغییر در اطلاعات فوق، خروجی دستور checksum هم تغییر خواهد کرد:
SQL> update tbl1 set salary=25 where id=4; 1 row updated SQL> select checksum(salary) ch_id_sal from tbl1; CH_ID_SAL ---------- 131164
البته اگه دو مقدار در یک فیلد جابجا شوند، تغییری در خروجی checksum یک ستون ایجاد نخواهد شد:
SQL> select id,salary from tbl1; ID SALARY ---------- ---------- 1 10 2 12 3 17 4 25 SQL> declare 2 v_sal_1 number; 3 v_sal_2 number; 4 begin 5 select salary into v_sal_1 from tbl1 where id=1; 6 select salary into v_sal_2 from tbl1 where id=2; 7 update tbl1 set salary=v_sal_2 where id=1; 8 update tbl1 set salary=v_sal_1 where id=2; 9 commit; 10 end; 11 / PL/SQL procedure successfully completed SQL> select id,salary from tbl1; ID SALARY ---------- ---------- 1 12 2 10 3 17 4 25 SQL> select checksum(salary) ch_id_sal from tbl1; CH_ID_SAL ---------- 131164
اگر برای هر مقدار در یک ستون مقدار مشابه ای در همان ستون وجود داشته باشد، خروجی تابع checksum برای ان ستون برابر با 0 خواهد شد برای مثال اگه ستونی شامل چهار عدد 1 و چهار عدد 2 باشد، تابع Checksum عدد 0 را بر می گرداند و اگر تعداد عدد 1 فرد باشد، checksum عددی غیر از 0 را برمیگرداند:
SQL> select salary from tbl1; SALARY ---------- 1 2 1 2 1 2 6 rows selected SQL> select checksum(salary) from tbl1; CHECKSUM(SALARY) ---------------- 778195 SQL> insert into tbl1 values(7,'reza',1); 1 row inserted SQL> insert into tbl1 values(8,'darush',2); 1 row inserted SQL> select salary from tbl1; SALARY ---------- 1 2 1 2 1 2 1 2 8 rows selected SQL> select checksum(salary) from tbl1; CHECKSUM(SALARY) ---------------- 0
برای این موارد می توان از عبارت distinct کمک گرفت:
SQL> select checksum(salary),checksum(distinct salary) from tbl1; CHECKSUM(SALARY) CHECKSUM(DISTINCTSALARY) ---------------- ------------------------ 0 778195