در این متن قصد داریم نحوه نصب Oracle APEX 22.1 را در دیتابیس نسخه 21c و در محیط لینوکس شرح دهیم. برای این کار نیاز است تا مراحل زیر را طی کنیم:
1.نصب اوراکل لینوکس(نسخه 8)
2.نصب و آماده سازی اوراکل(نسخه 21c)
3.نصب APEX
4.نصب ORDS
……….آموزش، مشاوره و پشتیبانی……….
در این متن قصد داریم نحوه نصب Oracle APEX 22.1 را در دیتابیس نسخه 21c و در محیط لینوکس شرح دهیم. برای این کار نیاز است تا مراحل زیر را طی کنیم:
1.نصب اوراکل لینوکس(نسخه 8)
2.نصب و آماده سازی اوراکل(نسخه 21c)
3.نصب APEX
4.نصب ORDS
مطابق با داکیومنتهای اوراکل در زمینه Backup/Recovery، برای برگرداندن یک PDB ابتدا باید بکاپ CDB مربوط به آن PDB را برگرداند در غیر این صورت امکان برگرداندن PDB وجود ندارد! اما در این متن با روش جدیدی آشنا خواهیم شد که امکان برگرداندن بکاپ PDB را در یک CDB جدید فراهم می کند. البته این روش همیشه جواب نمی دهد و بهتر است که در سناریو بکاپ و ریکاوری این موضوع را در نظر داشته باشیم.
در سناریوی پیش رو قرار است از PDBای به نام RmanPDB به صورت مستقل بکاپ گرفته و با انتقال آن به سرور جدید، سعی داریم این PDB را در یک CDB جدید برگردانیم.
بکاپ از RmanPDB:
Connected to: Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production Version 21.3.0.0.0 SQL> show pdbs CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NO 5 PDB1 READ WRITE NO 4 RMANPDB READ WRITE NO
RMAN> backup pluggable database RmanPDB format '/oracle21c/bkp_pdb/%U' current controlfile format '/oracle21c/bkp_pdb/control0000.bkp';
Starting backup at 16-OCT-21 using target database control file instead of recovery catalog allocated channel: ORA_DISK_1 channel ORA_DISK_1: SID=266 device type=DISK channel ORA_DISK_1: starting full datafile backup set channel ORA_DISK_1: specifying datafile(s) in backup set input datafile file number=00068 name=/oracle21c/base/oradata/DB21C/CE75C2880CCD2A3FE0530488200A29C8/datafile/o1_mf_sysaux_jpo62lhz_.dbf input datafile file number=00067 name=/oracle21c/base/oradata/DB21C/CE75C2880CCD2A3FE0530488200A29C8/datafile/o1_mf_system_jpo62lhv_.dbf input datafile file number=00069 name=/oracle21c/base/oradata/DB21C/CE75C2880CCD2A3FE0530488200A29C8/datafile/o1_mf_undotbs1_jpo62lj1_.dbf input datafile file number=00070 name=/oracle21c/base/oradata/DB21C/CE75C2880CCD2A3FE0530488200A29C8/datafile/o1_mf_tbs01_jpo66vjx_.dbf channel ORA_DISK_1: starting piece 1 at 16-OCT-21 channel ORA_DISK_1: finished piece 1 at 16-OCT-21 piece handle=/oracle21c/bkp_pdb/4p0bo4mu_153_1_1 tag=TAG20211016T052342 comment=NONE channel ORA_DISK_1: backup set complete, elapsed time: 00:00:03 channel ORA_DISK_1: starting full datafile backup set channel ORA_DISK_1: specifying datafile(s) in backup set including current control file in backup set channel ORA_DISK_1: starting piece 1 at 16-OCT-21 channel ORA_DISK_1: finished piece 1 at 16-OCT-21 piece handle=/oracle21c/bkp_pdb/control0000.bkp tag=TAG20211016T052342 comment=NONE channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01 Finished backup at 16-OCT-21
در متن “JSON و دیتابیس اوراکل” توضیح دادیم که چگونه اوراکل در نسخه 12c امکان ذخیره و کنترل اطلاعات JSON را در قالب دیتاتایپ CLOB، varchar و … فراهم کرده است و همچنین مطالبی را در مورد نحوه ایندکس گذاری کلیدهای JSON ارائه کرده ایم(برای مطالعه). در نسخه 21c بهبودهای دیگری نظیر نوع داده JSON، تابع JSON_TRANSFORM و … هم به این مجموعه قابلیتها اضافه شد که قبلا بعضی از آنها را مستند کرده ایم و در این متن قصد داریم در مورد یکی دیگر از این قابلیتها که JSON Multi value index است، نکاتی را بنویسیم.
می دانیم که قرار نیست ما به ازای هر کلید در JSON، صرفا یک مقدار ذخیره شود و در مواردی ممکن است مقدار یک کلید، یک آرایه(یا همان لیست) باشد. در این شرایط استفاده از روشهای قبلی ایندکس گذاری برای جستجو چندان کارآمد نخواهند بود و باید به دنبال روش جدیدی برای این حالت باشیم. در ادامه با ارائه مثالی، بیشتر این موضوع را توضیح خواهیم داد.
در نسخه 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، امکان شناسایی تغییر دیتا را در سطح ستون فراهم کرده است.
قابلیت auto indexing در اوراکل نسخه 19c شرط عدم تساوی را پشتیبانی نمی کند که قبلا در این مورد مطلبی را ارائه کرده ایم. نسخه 21c این قابلیت را فراهم کرده است که در ادامه این مسئله را می بینید.
برای نمایش این محدودیت، جدولی را همراه با حجم قابل توجهی از اطلاعات ایجاد می کنیم:
SQL> create table tb(id number,name varchar2(100),date_time date,c1 varchar2(4000),c2 varchar2(4000)); Table created SQL> insert into tb select rownum,'test'||’’||rownum,sysdate - rownum,rpad('test',400,'c1'),rpad('test',400,'c2') from dual connect by level <=666444; 666444 rows inserted SQL> commit; Commit complete SQL> exec dbms_stats.gather_table_stats(ownname => user,tabname => 'TB'); PL/SQL procedure successfully completed
بعد از ایجاد جدول، پرس و جوی زیر را که شرط عدم تساوی در آن استفاده شده است را در دیتابیس اجرا می کنیم:
Select count(*) from tb where id between 1 and 10;
همچنین با اجرای بلاک plsql زیر، سعی در مجاب کردن اوراکل برای بررسی این پرس و جو داریم:
declare temp number; begin for a in 1 .. 1000 loop select count(*) into temp from tb where id between 1 and 10; end loop; end;
پس از گذشت interval پانزده دقیقه ای، گزارشی از آخرین اجرا را می بینیم:
select DBMS_AUTO_INDEX.REPORT_ACTIVITY(SYSTIMESTAMP-1,SYSTIMESTAMP,'HTML','ALL','ALL') from dual;
با اجرای دستور زیر خواهیم دید که بر روی ستون id ایندکسی ایجاد شده است:
select owner,index_name,table_name,auto from dba_indexes where AUTO='YES';
تا قبل از نسخه 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
اوراکل در نسخه 19c اجازه نمی دهد که یک pdb را به زمانی از یک ORPHAN incarnation برگردانیم:
SQL*Plus: Release 19.0.0.0.0 - Production on Thu Apr 21 08:28:57 2022 Version 19.3.0.0.0 SQL> SELECT con_id, status, pdb_incarnation# inc#, begin_resetlogs_scn, end_resetlogs_scn FROM v$pdb_incarnation ORDER BY 3; CON_ID STATUS INC# BEGIN_RESETLOGS_SCN END_RESETLOGS_SCN ---------- ------- ---------- ------------------- ----------------- 3 PARENT 0 1920977 1920977 3 ORPHAN 1 1963437 1963437 3 CURRENT 2 1964176 1964176 SQL> alter pluggable database pdb1401 close; Pluggable database altered. SQL> flashback pluggable database to scn 1962565; ORA-39889: Specified System Change Number (SCN) or timestamp is in the middle of a previous PDB RESETLOGS operation. SQL> flashback pluggable database PDB1401 to scn 1963437; ORA-39889: Specified System Change Number (SCN) or timestamp is in the middle of a previous PDB RESETLOGS operation. [oracle@stb ~]$ rman target sys/sys@192.168.1.20:1521/pdb1401 RMAN> reset pluggable database pdb1401 to incarnation 1; 'RMAN-07536: command not allowed when connected to a Pluggable Database'
اما در نسخه 21c این قابلیت به وجود آمد تا بتوان یک PDB را به هر زمانی در گذشته برگرداند(البته گذشته نزدیک). در ادامه با سناریوی زیر و با ایجاد یک ORPHAN incarnation بیشتر با این فیچر را آشنا خواهیم شد.
ستونهای DBUSERNAME و CURRENT_USER در ویوی unified_audit_trail شباهت زیادی به هم دارند و در بسیاری از مواقع، این دو ستون حاوی اطلاعات یکسانی هستند. معمولا در این ستونها نام کاربری که به دیتابیس لاگین کرده و دستور را اجرا نموده است ، ذخیره می شود.
مگر آنکه کاربر متصل به دیتابیس با حقوق definer(یا همان definer right)، دستوری را اجرا کند، که در این صورت، نام کاربر متصل به دیتابیس در ستون DBUSERNAME ثبت می شود و نام کاربر definer که مجری واقعی دستور بوده در ستون CURRENT_USER ذخیره می شود.
*برای آشنایی بیشتر با مفهوم definer right و invoker right پیشنهاد می شود مطلب بررسی Invoker’s Rights و Definer’s Rights را مطالعه کنید.
برای مثال، کاربر A پروسیجر زیر را به صورت definer right تعریف کرده است:
create or replace procedure prc1 authid definer as id_var number; begin select object_id into id_var from usef.tbl1 where object_name = ‘TB’; end; /
با فرمت حلقه 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 معرفی شده و البته در 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