مسعود سلطانی راد
مسعود سلطانی راد
خواندن ۸ دقیقه·۱ سال پیش

بررسی کامل Boolean Type در Oracle 23c

با وجود تمام قابلیت‌های جدید و عالی که در نسخه پایگاه داده Oracle 23c معرفی شده‌اند، گاهی اوقات این چیزهای ساده و کوچک هستند که بیشترین سر و صدا را ایجاد می‌کنند.معرفی انواع داده های Boolean در SQL ممکن است یکی از بزرگترین ها باشد.

برای سال‌ها در نسخه‌های قبلی، استدلال علیه نوع SQL Boolean این بود که به آن نیازی نبود. و صادقانه بگویم، این یک ضرورت فنی نبود. توسعه دهندگان در سراسر جهان، از Flag های مختلفی از انواع داده های دیگر مانند Y/N، ۱/۰، یا T/F استفاده کردند و برنامه های ما کار کردند.
با این حال، هر کسی که با زبان های برنامه نویسی دیگر آشنا باشد، اغلب این کد را ناخوشایند و مصنوعی می داند که چیزی که به سادگی درست یا نادرست است باید با متن یا انواع عددی به جای بولین بومی ارزیابی شود. Oracle 23cاز استاندارد SQL پیروی می کند و Booleans را به زبان Oracle SQL می آورد.

مستند آموزش نصب پایگاه داده Oracle 23

ستون های بولی

برای شروع، ما یک جدول ایجاد می کنیم که دو Boolean را اعلام می کند، که یکی از آنها NOT NULL است.

Oracle Database 23c Free, Release 23.0.0.0.0 – Developer-Release

Version 23.2.0.0.0

SQL> create table testtable(b boolean, bnn boolean not null);

Table created.

SQL> insert into testtable(b,bnn) values (true,true);

۱ row created.

SQL> insert into testtable(b,bnn) values (false,false);

۱ row created.

SQL> insert into testtable(b,bnn) values (null,true);

۱ row created.

SQL> insert into testtable(b,bnn) values (null,false);

۱ row created.

SQL> insert into testtable(b,bnn) values (null,null);

insert into testtable(b,bnn) values (null,null)

*

ERROR at line 1:

ORA-01400: cannot insert NULL into (“SDS”.”TESTTABLE”.”BNN”)

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

SQL> select * from testtable;

B BNN

———– ———–

TRUE TRUE

FALSE FALSE

TRUE

FALSE

۴ rows selected.

توجه داشته باشید، حروف بولی TRUE و FALSE به حروف بزرگ و کوچک حساس نیستند. در مثال های بالا از حروف کوچک استفاده کردم، اما حروف بزرگ و مختلط به یک اندازه معتبر هستند.

SQL> insert into testtable(b,bnn) values (TRUE,True);

۱ row created.

SQL> insert into testtable(b,bnn) values (FALSE,False);

۱ row created.

SQL> insert into testtable(b,bnn) values (TRUE,TruE);

۱ row created.

SQL> insert into testtable(b,bnn) values (FALSE,FaLSe);

۱ row created.

SQL> select * from testtable;

B BNN

———– ———–

TRUE TRUE

FALSE FALSE

TRUE

FALSE

TRUE TRUE

FALSE FALSE

TRUE TRUE

FALSE FALSE

۸ rows selected.

تبدیل نوع داده

۲۳c از بسیاری از literals های رایج برای تبدیل ضمنی به مقادیر بولی پشتیبانی می کند.
‘true’، ‘false’، ‘yes’، ‘no’، ‘on’، ‘off’، ‘۱’، ‘۰’، ‘t’، ‘f’، ‘y’، ‘n’ قابل تبدیل هستند به مقادیر Boolean True/False. تمام حروف تحت literals متن به حروف بزرگ و کوچک حساس نیستند و بر اساس کلمات انگلیسی هستند. هیچ معادلی برای زبان های دیگر مانند فرانسوی ‘oui’، ‘non’ وجود ندارد.
همچنین توجه داشته باشید، مقادیر عددی نیز ممکن است به طور ضمنی به مقادیر بولی تبدیل شوند. ۰ تبدیل به FALSE و مقادیر غیر صفر True است.

SQL> truncate table testtable;

Table truncated.

SQL> insert into testtable(b,bnn) values (‘true’,’False’);

۱ row created.

SQL> insert into testtable(b,bnn) values (‘YES’,’NO’);

۱ row created.

SQL> insert into testtable(b,bnn) values (‘on’,’off’);

۱ row created.

SQL> insert into testtable(b,bnn) values (‘1′,’0’);

۱ row created.

SQL> insert into testtable(b,bnn) values (‘t’,’f’);

۱ row created.

SQL> insert into testtable(b,bnn) values (‘y’,’n’);

۱ row created.

SQL> insert into testtable(b,bnn) values (12345,0);

۱ row created.

SQL> insert into testtable(b,bnn) values (-0.234,-0.0000);

۱ row created.

SQL> select * from testtable;

B BNN

———– ———–

TRUE FALSE

TRUE FALSE

TRUE FALSE

TRUE FALSE

TRUE FALSE

TRUE FALSE

TRUE FALSE

TRUE FALSE

به جای استفاده از تبدیل ضمنی، می‌توانید با استفاده از تابع TO_BOOLEAN با literals‌ها صریح باشید.

SQL> truncate table testtable;

Table truncated.

SQL> insert into testtable(b,bnn) values (to_boolean(‘true’),to_boolean(‘False’));

۱ row created.

SQL> insert into testtable(b,bnn) values (to_boolean(‘YES’),to_boolean(‘NO’));

۱ row created.

SQL> insert into testtable(b,bnn) values (to_boolean(‘on’),to_boolean(‘off’));

۱ row creeated.

SQL> insert into testtable(b,bnn) values (to_boolean(-0.234),to_boolean(-0.0ated.

SQL> insert into testtable(b,bnn) values (to_boolean(‘1’),to_boolean(‘0’));

۱ row created.

SQL> insert into testtable(b,bnn) values (to_boolean(‘t’),to_boolean(‘f’));

۱ row created.

SQL> insert into testtable(b,bnn) values (to_boolean(‘y’),to_boolean(‘n’));

۱ row created.

SQL> insert into testtable(b,bnn) values (to_boolean(12345),to_boolean(0));

۱ row cr000));

۱ row created.

SQL> select * from testtable;

B BNN

———– ———–

TRUE FALSE

TRUE FALSE

TRUE FALSE

TRUE FALSE

TRUE FALSE

TRUE FALSE

TRUE FALSE

TRUE FALSE

تابع TO_BOOLEAN فقط از literals های بالا پشتیبانی می کند. اگر بخواهید یک مقدار غیرقانونی را تبدیل کنید، یک خطای بولی نامعتبر دریافت خواهید کرد.

SQL> insert into testtable(b,bnn) values (to_boolean(‘oui’),to_boolean(‘non’));

insert into testtable(b,bnn) values (to_boolean(‘oui’),to_boolean(‘non’))

*

ERROR at line 1:

ORA-61800: invalid boolean literal: oui

منطق بولی

منطق بولی همیشه در عبارات Where یک پرس و جو پشتیبانی می شود و این به نوع داده جدید گسترش می یابد. علاوه بر این، نتایج منطقی را می توان به عنوان یک عبارت SQL نیز برگرداند.

SQL> select * from testtable where b and bnn;

B BNN

———– ———–

TRUE TRUE

TRUE TRUE

TRUE TRUE

SQL> select * from testtable where b or bnn;

B BNN

———– ———–

TRUE TRUE

TRUE

TRUE TRUE

TRUE TRUE

SQL> select b, bnn, b and bnn, b or bnn from testtable;

B BNN BANDBNN BORBNN

———– ———– ———– ———–

TRUE TRUE TRUE TRUE

FALSE FALSE FALSE FALSE

TRUE TRUE

FALSE FALSE

TRUE TRUE TRUE TRUE

FALSE FALSE FALSE FALSE

TRUE TRUE TRUE TRUE

FALSE FALSE FALSE FALSE

در این مرحله مهم است که توجه داشته باشید که چگونه مقادیر NULL با عملگرها ارزیابی می شوند. همانطور که در بالا می بینیم، (NULL و TRUE) NULL را برمی گرداند، اما (NULL و FALSE) FALSE را برمی گرداند. این ممکن است در مقایسه با عملگرهای NULL که با انواع داده های دیگر استفاده می شود، عجیب به نظر برسد. به عنوان مثال، افزودن، ضرب، تفریق، تقسیم مقادیر NULL با مقدار غیر NULL بدون در نظر گرفتن مقدار غیر NULL منجر به NULL می شود. اما با یک Boolean، عبارت FALSE باقی می ماند . به طور مشابه، (NULL یا TRUE) به TRUE تبدیل می شود، نه NULL. بنابراین، باز هم، انتشار تهی در مقایسه با اپراتورهایی با انواع داده های دیگر، متفاوت از آنچه انتظار می رود عمل می کند.
متأسفانه در ارزیابی ها خلأهایی وجود دارد. در حالی که می‌توانید دو ستون بولی را با AND یا OR همانطور که در بالا نشان داده شده است، یا دو حرف بولی یا یک ستون با یک حرف literalsی ارزیابی کنید، نمی‌توانید از یک literals تبدیل شده به طور ضمنی یا صریح در یک عبارت بولی AND/OR استفاده کنید. حتی تلاش برای قرار دادن عبارت در پرانتز برای اطمینان از ارزیابی آن قبل از سایر عبارات یا شرایط کار نمی کند.

SQL> truncate table testtable;

Table truncated.

SQL> insert into testtable(b,bnn) values (true,true);

۱ row created.

SQL> insert into testtable(b,bnn) values (false,false);

۱ row created.

SQL> insert into testtable(b,bnn) values (null,true);

۱ row created.

SQL> select b and true from testtable;

BANDTRUE

———–

TRUE

FALSE

SQL> select b or true from testtable;

BORTRUE

———–

TRUE

TRUE

TRUE

SQL> select true and false from dual;

TRUEANDFALS

———–

FALSE

این عبارات با literals های تبدیل شده، ضمنی یا صریح شکست می خورند.

SQL> select true and ‘true’ from dual; — expression on implicit conversion fails

select true and ‘true’ from dual

*

ERROR at line 1:

ORA-00920: invalid relational operator

SQL> select true and to_boolean(‘true’) from dual; — expression on explicit conversion also fails

select true and to_boolean(‘true’) from dual

*

ERROR at line 1:

ORA-00920: invalid relational operator

SQL> select (true and to_boolean(‘true’)) from dual; — enclosing expression still fails

select (true and to_boolean(‘true’)) from dual

*

ERROR at line 1:

ORA-00907: missing right parenthesis

این محدودیت برای توابع pl/sql خود شما اعمال می شود که نتایج Boolean را برمی گرداند.

SQL> create or replace function are_equal(a in number, b in number) return boolean

۲ is

۳ begin

۴ return a=b;

۵ end;

۶ /

Function created.

SQL> select are_equal(1,2) f ,are_equal(1,1) t from dual;

F T

———– ———–

FALSE TRUE

SQL> select b and are_equal(1,1) from testtable;

select b and are_equal(1,1) from testtable

*

ERROR at line 1:

ORA-00920: invalid relational operator

ارزیابی بولی

در حالی که در بسیاری از موارد می توانید به سادگی از یک مقدار بولی به عنوان شرط خود استفاده کنید، می توانید صریح باشید و با شرط IS بررسی کنید که آیا یک مقدار درست یا نادرست است. بنابراین اگر B TRUE باشد، “B” و “B IS TRUE” باید عباراتی معادل باشند. به طور مشابه، اگر B FALSE باشد، “B” و “B IS TRUE” باید عبارات هم ارز باشند.

SQL> truncate table testtable;

Table truncated.

SQL> insert into testtable(b,bnn) values (true,true);

۱ row created.

SQL> insert into testtable(b,bnn) values (false,false);

۱ row created.

SQL> insert into testtable(b,bnn) values (null,true);

۱ row created.

SQL> select b from testtable where b;

B

———–

TRUE

SQL> select b from testtable where b is true;

B

———–

TRUE

SQL> select b from testtable where not b;

B

———–

FALSE

SQL> select b from testtable where b is false;

B

———–

FALSE

البته توجه داشته باشید، IS NOT، با مقادیر NULL متفاوت کار می کند.

SQL> select b, nvl2(b,to_char(b),’~null~’) b_text from testtable where b is not true;

B B_TEXT

———– ——

FALSE FALSE

~null~

SQL> select b, nvl2(b,to_char(b),’~null~’) b_text from testtable where b is not false;

B B_TEXT

———– ——

TRUE TRUE

~null~

این عملگرها با توابع PL/SQL و همچنین تبدیل صریح با استفاده از TO_BOOLEAN کار می کنند.

SQL> SELECT are_equal(1, 1) is true,

۲ to_boolean(‘yes’) is true,

۳ are_equal(1, 2) is true,

۴ to_boolean(‘no’) is true

۵ FROM DUAL;

ARE_EQUAL(1 TO_BOOLEAN( ARE_EQUAL(1 TO_BOOLEAN(

———– ———– ———– ———–

TRUE TRUE FALSE FALSE

آنها مستقیماً با literals کار نمی کنند، زیرا به طور ضمنی تبدیل نمی شوند.

SQL> select ‘yes’ is true from dual;

select ‘yes’ is true from dual

*

ERROR at line 1:

ORA-61803: argument of IS TRUE must be a column or an expression of boolean data type

امیدوارم این به شما کمک کند تا با کار با مقادیر Boolean در SQL با Oracle 23cو فراتر از آن آشنا شوید

جهت خدمات مشاوره، آموزش و نگهداری پایگاه داده اوراکل با ما در تماس باشید.

oracle databaseمشاوره اوراکلخدمات اوراکلآموزش پایگاه داده اوراکلمسعود سلطانی راد
چند سالی هست در حوزه داده ها ( نگهداری و تحلیل آنها) فعالیت دارم و همیشه سعی کردم آموخته هایم رو به اشتراک بگذارم soltanirad@artarad.ir www.artarad.ir
شاید از این پست‌ها خوشتان بیاید