امکان استفاده از عبارت if [not] exists در هنگام ایجاد و یا حذف یک object

در زمان ساخت یک object، اگر آن object از قبل موجود باشد، با خطای already exist مواجه خواهیم شد همچنین اگر قصد حذف کردن شی ای که موجود نیست را داشته باشیم، خطای does not exist رخ خواهد داد. برای جلوگیری از این دو خطا می توان از عبارت if [not] exists استفاده کرد.

برای مثال، جدول TB از قبل وجود دارد اگر از این مسئله مطمئن نیستیم، می توانیم دستور ساخت این جدول را با استفاده از عبارت if not exists اجرا کرده تا از خطای احتمالی ORA-00955 جلوگیری کنیم:

SQL> create table tb (c1 number(10));
ORA-00955: name is already used by an existing object
SQL> create table if not exists tb (c1 number(10));
Table created
SQL> create table if not exists tb (c1 number(10));
Table created

این عبارت برای دستورات DDLای دیگر هم کاربرد دارد:

SQL> drop sequence ss;
ORA-02289: sequence does not exist
SQL> drop sequence if exists ss;
Sequence dropped

(بیشتر…)

استفاده از Column Alias در قسمت Group by  و Having در اوراکل 23ai

در نسخه 23c می توان از Column Alias در قسمت GROUP BY و HAVING استفاده کرد. این امکان تا قبل از نسخه 23c وجود نداشت:

Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
SQL> select lower(owner) as Malek, sum(bytes / 1024 / 1024) as SIZE_MB
  2    from dba_segments
  3   group by Malek
  4  having SIZE_MB>100;
ERROR at line 4:
ORA-00904: "SIZE_MB": invalid identifier

در نسخه 21c برای جلوگیری از خطای invalid identifier فوق، می بایست Alias ستون را حذف و کوئری را به صورت زیر بازنویسی کرد:

select lower(owner) as Malek, sum(bytes / 1024 / 1024) as SIZE_MB
  from dba_segments
 group by owner
having sum(bytes / 1024 / 1024) > 10;

(بیشتر…)

نوع داده Boolean در اوراکل 23ai

اوراکل در نسخه 23c دیتا تایپ Boolean را در SQL معرفی کرده است(البته این نوع داده قبلا در PLSQL وجود داشته است) و با این قابلیت، در هنگام ساخت جدول می توان نوع داده ستونها را به Boolean تنظیم کرد.

SQL> CREATE TABLE jadval1 (id NUMBER, is_accept BOOLEAN);
Table created

از کلمه BOOL هم می توان به جای Boolean استفاده کرد.

SQL> CREATE TABLE jadval1 (id NUMBER, is_accept BOOL);
Table created

برای ستونهای از نوع Boolean میتوان مقدار پیش فرض تنظیم نمود:

SQL> CREATE TABLE jadval1 (id NUMBER, is_accept BOOL DEFAULT FALSE);
Table created

برای مقداردهی ستون is_accept می توانیم از سه کلمه کلیدی TRUE، FALSE و NULL استفاده کنیم:

SQL> insert into jadval1 values(1,true);
1 row inserted
SQL> insert into jadval1 values(2,null);
1 row inserted
SQL> insert into jadval1 values(3,false);
1 row inserted

SQL> select * from jadval1;
        ID    IS_ACCEPT
---------- ----------
         1          1
         2 
         3          0

(بیشتر…)

اهدای مجوز به فانکشن، پکیج و پروسیجر

زمانی که یک program unit(فانکشن، پکیج، پروسیجر) به صورت invoker right ایجاد می شود، کاربر صدا زننده برنامه، با مجوز خودش این برنامه را اجرا خواهد کرد بنابرین اگر جدولی در برنامه موجود باشد که این کاربر به آن دسترسی نداشته باشد، کارش با خطا متوقف خواهد شد(بررسی Invoker’s Rights و Definer’s Rights). برای مثال، تابع زیر را در نظر بگیرید:

SQL> CREATE FUNCTION sys.Tabe(name_malek in varchar2,name_jadval in varchar2)
   RETURN VARCHAR2
   AUTHID CURRENT_USER
AS
V_bytes varchar2(1000);
BEGIN
  select bytes into V_bytes from dba_segments where owner=name_malek and segment_name=name_jadval;
   RETURN V_bytes;
END;
/
Function created.

این تابع که با یوزر sys ایجاد شده، قرار است نام segment را دریافت و حجم آن را بر اساس بایت برگرداند. عبارت AUTHID CURRENT_USER بیانگر invoker right است.

کاربری با نام vahid را با حداقل دسترسی ایجاد کرده و بررسی می کنیم که آیا این کاربر می تواند تابع فوق را اجرا کند؟

SQL> create user vahid  identified by a;
User created.
SQL> grant create session to vahid; 
Grant succeeded.

(بیشتر…)

تابع checksum در اوراکل 21c

در نسخه 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، امکان شناسایی تغییر دیتا را در سطح ستون فراهم کرده است.

(بیشتر…)

قابلیتهای جدید اوراکل 21c در زمینه عملگرهای مجموعه ای

تا قبل از نسخه 21c، صرفا می توانستیم از سه عملگر مجموعه ای INTERSECT، MINUS و UNION [ALL] در اوراکل استفاده کنیم اما در نسخه 21c دو عملگر جدید EXCEPT و EXCEPT ALL به این مجموعه اضافه شدند که این دو عملگر معادل عملگرهای MINUS و MINUS ALL هستند و صرفا به دلیل استفاده از عبارتهای EXCEPT و EXCEPT ALL در دیتابیسهای دیگر، اوراکل هم این دو عملگر را به مجموعه عملگرهای خود اضافه کرده است.

مجددا تاکید می شود که در عمل تفاوتی بین EXCEPT و MINUS وجود ندارد و حتی در صورت استفاده از عملگر EXCEPT، اوراکل در زمان اجرای پرس و جو، در مرحله Query Transformation، عملگر EXCEPT را به MINUS تبدیل می کند.

با این توضیحات، در شرایط زیر، برای برگرداندن رکوردهایی که در t1.c1 وجود دارند اما در t2.c1 وجود ندارد(با حذف رکوردهای تکراری!!) دو انتخاب داریم، عملگرEXCEPT و عملگر MINUS:

select t1.c1 from t1
MINUS
select t2.c1 from t2;
D
Z
select t1.c1 from t1
EXCEPT
select t2.c1 from t2;
D
Z

(بیشتر…)

بهبودهای حلقه تکرار FOR در اوراکل 21c

با فرمت حلقه FOR آشنا هستید:

FOR loop_counter IN [REVERSE] lowest_number..highest_number
LOOP
   {...statements...}
END LOOP;

مطابق این syntax، قرار است شمارنده(loop_counter) به صورت ترتیبی(با گام یک) از نقطه lowest_number به نقطه highest_number برسد. برای مثال، با اجرای قطعه کد زیر، اعداد 4 تا 8 نمایش داده می شوند:

SQL> set serveroutput on
begin
  for i in 4 .. 8 loop
    dbms_output.put_line(i);
  end loop;
end;
/
4
5
6
7
8
PL/SQL procedure successfully completed.


(بیشتر…)

تابع ANY_VALUE در اوراکل 21c

ANY_VALUE تابع جدیدی است که در اوراکل 21c معرفی شده و البته در Release Updateهای انتهایی اوراکل نسخه 19c(یعنی از 19.8 به بالا) هم قابل استفاده است. در متن پیش رو با این تابع آشنا خواهیم شد.

*پرس و جوی زیر در pdb1 اجرا می شود و قرار است مشخص کند هر tablespace چند دیتافایل دارد:

select t.ts#, t.name, count(*) "Tedad_DataFile"
  from v$datafile d, v$tablespace t
 where t.ts# = d.ts#
 group by t.ts#, t.name;

همانطور که مشاهده می کنید، در پرس و جوی فوق هر دو ستون ts# و name در قسمت group by قید شده اند در صورتی که عدم درج ستون name در قسمت group by، تغییری در خروجی ایجاد نمی کند اما اوراکل اجازه این کار را به ما نمی دهد:

ORA-00979: not a GROUP BY expression

(بیشتر…)

SQL Macros در اوراکل 21c

همانطور که می دانید فراخوانی تابع در یک کوئری، context switch بین SQL engine و PL/SQL engine را در پی دارد این context switch به لحاظ پرفورمنسی اثر منفی را به دنبال خواهد داشت. برای مثال، دو دستور زیر خروجی یکسانی دارند اما مدت زمان اجرای آنها بسیار متفاوت است.

اجرای دستور بدون استفاده از function:

SQL> select sum(sal) from(select salary+60 as sal from person);

  SUM(SAL)

———-

8891924480

Elapsed: 00:00:00.81

اجرای دستور با استفاده از function:

SQL> select sum(sal) from(select sal_func(salary) as sal from person);

  SUM(SAL)

———-

8891924480

Elapsed: 00:00:10.91

(بیشتر…)

REBUILD کردن ایندکسها

یکی از روش های بهبود پرفورمنس در دیتابیس اوراکل استفاده از قابلیت REBUILD کردن ایندکس ها است. REBUILD کردن ایندکس هایی که با روشی مناسب انتخاب می شوند می تواند پرفورمنس دیتابیس را به طور قابل ملاحظه ای بهبود دهد. البته عملیات آنالیز و REBUILD ایندکس زمانبر بوده و سربار ایجاد می کند. در این متن REBUILD ایندکس ها و روش استفاده مناسب از آن توضیح داده می شود.

(بیشتر…)