اوراکل 23ai- امکان استفاده از ماژولهای JavaScript در دیتابیس اوراکل

در نسخه 21c، اوراکل امکان اجرای کد JavaScript در داخل دیتابیس را فراهم کرده است. این کار با کمک بسته DBMS_MLE امکان پذیر است:

DECLARE
   ctx varchar2(50) ;
BEGIN
   ctx := DBMS_MLE.create_context();
   DBMS_MLE.eval(ctx, 'JAVASCRIPT', q'~console.log("www.usefzadeh.com");~');
   DBMS_MLE.drop_context(ctx);
END;
/
www.usefzadeh.com

در نسخه 23c قابلیتهای دیگری هم در این زمینه ارائه شد که یکی از آنها، امکان بارگذاری و استفاده از ماژولهای JavaScript در دیتابیس اوراکل است این قابلیت می تواند در زمینه های مختلفی راهگشا باشد و حجم کدنویسی را کاهش دهد.

به عنوان مثال، در مطلب “قابلیت SQL domain در اوراکل 23c” در مورد محدود کردن فرمت ورودی ها از طریق check constraint، trigger و sql domain نکاتی را ارائه کردیم و توضیح دادیم که چگونه می توانیم ورودی های ستونی مثل email را کنترل کنیم تا در قالبی مشخص درج شوند.

در این قبیل چالشها، ماژولهای JavaScript هم می توانند به کمک ما بیایند و با استفاده از آنها هم می توانیم بسیاری از این دست نیازمندیها را در دیتابیس مرتفع کنیم. برای مثال، ماژول validator در مورد کنترل ساختار ورودی ها می تواند مورد استفاده قرار بگیرد.

(بیشتر…)

اوراکل 23ai-قابلیت Automatic Transaction Rollback(تنظیم اولویت برای تراکنشها)

در صورتی که دو کاربر قصد ویرایش یک رکورد را داشته باشند، کاربری که دیرتر دستور update را اجرا کرده Block خواهد شد و تا زمانی که کاربر اول(کاربری که زودتر رکورد را در اختیار گرفته) به تراکنش خاتمه ندهد، کاربر دوم در حالت Block باقی خواهد ماند.

--session 1:
SQL> select sid from v$mystat where rownum=1;
       SID
----------
      2190
SQL> update USEF.TBL1 set  id=1;
1 row updated
--session 2:
SQL> select sid from v$mystat where rownum=1;
       SID
----------
       944

SQL> update USEF.TBL1 set id=1;
Executing…

بلاک شدن session دوم را می توانیم از طریق دستور زیر ببینیم:

SQL>  select SID,ID1,ID2,LMODE,block,request from v$lock where type='TX';
       SID        ID1        ID2      LMODE      BLOCK    REQUEST
---------- ---------- ---------- ---------- ---------- ----------
       944     458766       2511          0          0          6
      2190     458766       2511          6          1          0

ممکن است کاربر دوم که تراکنشش در حالت انتظار قرار دارد، برای ما اولویت بیشتری داشته باشد. در این حالت چه راهکاری وجود دارد؟

(بیشتر…)

اوراکل 23ai– خواناتر شدن متن خطاها

در نسخه 23c، اوراکل متن بعضی از خطاها را به شکل خواناتری تغییر داده تا در شناسایی علت آن و همچنین رفع سریع تر این خطاها به Developer و یا DBA کمک کرده باشد.

برای مثال متن خطای معروف ORA-00979 تا قبل از نسخه 23c به صورت زیر بوده است:

SQL> select owner,object_type,count(*) from dba_objects group by  owner;

ORA-00979: not a GROUP BY expression

اما این متن در نسخه 23c به صورت زیر تغییر کرده است:

SQL> select owner,object_type,count(*) from dba_objects group by  owner;

ORA-00979: “OBJECT_TYPE”: must appear in the GROUP BY clause or be used in an aggregate function

در ادامه نمونه های دیگری از خطاهای معروفی که متن آنها تغییر کرده است را مشاهده می کنید.

(بیشتر…)

فعالسازی مجدد Traditional Audit در اوراکل 23ai

قبلا در مطلبی توضیح دادیم که Traditional Audit در نسخه 23c پشتیبانی نمی شود به این معنی که auditهای قدیمی امکان اعمال شدن دارند ولی نمی توان audit جدیدی را ایجاد کرد.

برای مثال می توانیم auditای که از قبل تنظیم شده را noaudit کنیم:

SQL>  noaudit all on DVSYS."REALM_AUTH$";
Noaudit succeeded.

ولی امکان تنظیم مجدد این audit و یا auditهای دیگر وجود ندارد و در صورت تلاش برای این کار با خطای ORA-46401 مواجه خواهیم شد:

SQL> audit all on DVSYS."REALM_AUTH$";
ORA-46401: No new traditional AUDIT configuration is allowed. Traditional
auditing is desupported, and you should use unified auditing in its place.

آقای Pete Finnigan که در موضوع oracle security مطالب خوبی دارند، پارامتر مخفی ای(Hidden Parameter)  را معرفی کردند که امکان فعالسازی مجدد Traditional Audit را در این نسخه فراهم می کند:

SQL> alter system set "_allow_traditional_audit_configuration"=true;
System altered.

پس از تنظیم این پارامتر به مقدار TRUE، مجددا دستور audit فوق را اجرا می کنیم:

SQL> audit all on DVSYS."REALM_AUTH$";
Audit succeeded.

این نوع از  audit بدون هیچ محدودیتی، در سطوح دیگر هم قابل انجام است:

SQL> audit drop any table;
Audit succeeded.
SQL> audit all statements;
Audit succeeded.

 

اوراکل 23ai- قابلیت DEFAULT ON NULL برای update و insert

از نسخه های قدیمی اوراکل این امکان را داشتیم که برای ستونهای جداول، مقدار پیش فرض و یا همان Default Value تعریف کنیم.

با تنظیم Default Value برای یک ستون، اگر در زمان اجرای دستور insert مقداری را برای آن ستون لحاظ نکرده باشیم، Default Value برای آن ستون اعمال خواهد شد:

SQL*Plus: Release 10.1.0.4.2 - Production on Sat Aug 5 16:28:29 2023
SQL> create table tbl1(id number,tarikh date default sysdate+1);
Table created.
SQL> insert into tbl1(id) values(1);
1 row created.
SQL> select * from tbl1;
        ID TARIKH
---------- ---------
         1 06-AUG-23

در این شرایط اگر به صراحت مقدار NULL را برای ستون tarikh در نظر بگیریم چه اتفاقی می افتد؟

SQL> insert into tbl1 values(2,null); 
1 row created.
SQL> select * from tbl1;
        ID TARIKH
---------- ---------
         1 06-AUG-23
         2

همانطور که می بینید، Default value در این حالت اعمال نشده است!

اوراکل در نسخه 12cR1 قابلیتی را اضافه کرده تا بتوان در این حالت هم مقدار Default Value به جای NULL برای ستون مورد نظر اعمال شود:

(بیشتر…)

اوراکل 23ai- امکان ذخیره کردن Flashback Logها خارج از FRA

تا قبل از اوراکل 23c،ء Flashback Logها الزاما باید در FRA ذخیره می شدند و در صورت عدم تنظیم FRA، امکان فعال کردن قابلیت Flashback Database وجود نداشت:

Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
SQL> alter database flashback on;
ORA-38706: Cannot turn on FLASHBACK DATABASE logging.
ORA-38709: Recovery Area is not enabled.

در نسخه 23c دو پارامتر جدید در این زمینه معرفی شدند که می توان از طریق آنها Flashback Logها را در مسیری غیر از FRA ذخیره کرد. این پارامترها، db_flashback_log_dest_size و db_flashback_log_dest هستند. قبل از تنظیم این دو پارامتر، وضعیت پارامترهای مربوط به FRA را بررسی می کنیم:

SQL> show parameter db_recovery_file_dest
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest                string
db_recovery_file_dest_size           big integer 0

با تنظیم دو پارامتر مذکور، قابلیت Flashback Database را فعال می کنیم:

SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------
NO
SQL> alter system set db_flashback_log_dest_size=800m;
System altered.
SQL> alter system set db_flashback_log_dest='/oracle23c/FlashbackLog';
System altered.
SQL> alter database flashback on;
Database altered.
SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------
YES

(بیشتر…)

قابلیت SQL History در اوراکل 23ai

قابلیت SQL History در نسخه 23c امکان مشاهده آخرین دستورات اجرا شده توسط sessionها را فراهم می کند(حدودا 50 دستور برای هر session) اوراکل بر اساس این قابلیت، دستوراتی که اجرای آنها به خطا خورده را هم نمایش می دهد.

برای فعال کردن قابلیت SQL History باید پارامتر SQL_HISTORY_ENABLED را به مقدار TRUE تنظیم کرد مقدار پیش فرض این پارامتر برابر با False است:

SQL> show parameter  SQL_HISTORY_ENABLED
NAME                 TYPE   	 VALUE
-------------------- --------- ------- 
sql_history_enabled  boolean 	FALSE

این پارامتر در دو سطح session و system قابل تنظیم است:

SQL> alter system set sql_history_enabled=true;
System altered

(بیشتر…)

افزایش حداکثر اندازه Inline LOBها به 8000

در دیتابیس اوراکل LOBها همیشه در LOB segment ذخیره نمی شوند! زمانی که حجم یک LOB از مقدار مشخصی کمتر باشد، این LOB در segment متعلق به خود جدول و در کنار فیلدهای non-LOB ذخیره خواهد شد:

SQL> create table tbl_asnad( id number, doc clob);
Table created
SQL> alter table tbl_asnad rename lob(doc) "SYS_LOB0000136146C00002$$" to lob_asnad_doc;
Table altered
SQL> insert into TBL_ASNAD values(1,'usefzadeh.com');
1 row inserted
SQL> select segment_name,bytes from user_segments where segment_name in ('LOB_ASNAD_DOC','TBL_ASNAD');
SEGMENT_NAME               	  BYTES
----------------------  	----------
TBL_ASNAD                        65536
LOB_ASNAD_DOC                    65536
SQL> begin
  2  for i in 1.. 100000 loop
  3  insert into TBL_ASNAD values(1,'usefzadeh.com');
  4  end loop;
  5  end;
  6  /
PL/SQL procedure successfully completed
SQL> select segment_name,bytes from user_segments where segment_name in ('LOB_ASNAD_DOC','TBL_ASNAD');
SEGMENT_NAME              BYTES
--------------------		 ----------
TBL_ASNAD                	8388608
LOB_ASNAD_DOC             65536

این محدودیت در نسخه 21c برابر 4000 بود و در نسخه 23c به 8000 افزایش یافته است. به ادعای اوراکل، با این قابلیت می توان در زمان عملیاتهایی نظیر Full table scan، Index range scan و DML کارایی بهتری داشت.

اوراکل 23ai- تغییر نام LOB segment

همانطور که می دانید اوراکل برای هر LOB segment یک نام خودکار با پیشوند SYS_LOB ایجاد می کند:

SQL> create table asnad( id number, doc clob);
Table created

SQL> select segment_name from dba_lobs where table_name='ASNAD';
SEGMENT_NAME
------------------------------
SYS_LOB0000136126C00002$$

در نسخه 21c برای تغییر نام SYS_LOBها می بایست LOB segment را move داد که این کار بسیار پرهزینه بود و چالشهایی نظیر بازسازی ایندکسهای جدول را به همراه داشت:

SQL> insert into ASNAD values(1,'my name is vahid');
1 row inserted
SQL> commit;
Commit complete
SQL> create index ind on asnad(id);
Index created
SQL> alter table asnad move lob(doc) store as asnad_doc;
Table altered
SQL> select segment_name from dba_lobs where table_name='ASNAD';
SEGMENT_NAME
----------------
ASNAD_DOC

SQL> select index_name from user_indexes where status='UNUSABLE';
INDEX_NAME
---------------
IND

(بیشتر…)

قابلیت SQL domain در اوراکل 23ai

دیتابیس اوراکل در نسخه 23c سعی کرده تا بسیاری از قابلیتهای موجود در دیتابیسهای رابطه ای دیگر را در این version ارائه کند قابلیتهای ساده ای نظیر «Schema level privilege» – «Boolean data type» – «Direct Joins for UPDATE and DELETE» -«SELECT without FROM» و …

یکی دیگر از این قابلیتها که موضوع بحث این مستند هم هست، SQL domain می باشد که می تواند شامل مجموعه ای از محدودیتها و خصوصیتها باشد و با تخصیص آن به یک ستون، می توان محدودیتهایی را برای آن ستون اعمال کرد به عبارت دیگر، SQL domain امکان توسعه Data type را متناسب با Business فراهم می کند.

یکی از کاربردهای مهم این قابلیت به زمانی برمی گردد که بخواهیم برای مقادیر ورودی یک ستون، شرطهای به خصوصی را اعمال کنیم. مثلا برای ستون Age با نوع داده number، با شرط Age>=18، از ثبت مقادیر کمتر از 18 جلوگیری کنیم و یا به عنوان مثالی کاربردی تر، برای ستونی که قرار است آدرس Email در آن ذخیره شود، شرطی را اعمال کنیم تا این ستون، صرفا اطلاعات ورودی با فرمت text@text.text را بپذیرد.

(بیشتر…)