You are on page 1of 73

/* security system : -----------------1 - from system/manager : grant alter system to user_name; 2 - to know the sid and serial# and

other details use : SELECT sid, serial#,MODULE,TERMINAL FROM v$session WHERE username = 'SCOTT'; or CREATE OR REPLACE VIEW HAMDY_CONNECTED_USERS ( SID, SERIAL#, MODULE, TERMINAL, OSUSER, MACHINE, P2, PROGRAM, LOGON_TIME, STATUS ) AS SELECT ALL sid, serial#, module, terminal, osuser, substr(machine,instr(machine,'\',-1,1)+1)machine , upper(substr(program,instr(program,'\',-1,1)+1)) p2, decode(upper(substr(program,instr(program,'\',-1,1)+1)), upper('prime asset management.ln'),'Prime Assets Management', upper('prime asset manag'),'Prime Assets Management', upper('prime asset management.ln'),'Prime Assets Management', upper('form'),'Forms Builder', upper('repo'),'Reprots Builder', upper('sche'),'Schema Builder', upper('d'),'Query Builder', upper('R30RBE32.exe'),'Reports Background', upper('F50dbg32.EXE'),'Forms Runtime Background', upper('TOAD.lnk'),'TOAD', upper('SQL%'),'SQL*PLUS', upper(substr(program,instr(program,'\',-1,1)+1)) ) program, logon_time, status FROM v$session WHERE username = USER -- order by terminal

3 - to stop any connected user from using oracle : alter system kill session '18,2161'; where - 18 is the SID and - 2161 is SERIAL# 4 - form builder : forms_ddl('alter system kill session '''||:sid||','||:serial#||''''); do_key('execute_query'); */ report with many distination ----------------------PROCEDURE Run_Report(P_destination varchar default 'screen') IS PL_ID Paramlist; Where_Clause Varchar2(250); BEGIN

pl_id := Get_Parameter_List('Report'); IF NOT Id_Null(pl_id) THEN Destroy_Parameter_List( pl_id ); END IF; pl_ID := Create_Parameter_List('Report'); Add_Parameter(pl_id,'Paramform',Text_PARAMETER,'NO'); If User_Can_Print(:parameter.P_User_ID,:System.Current_Form) Then Add_Parameter(pl_id,'DISABLEPRINT',Text_PARAMETER,'NO'); Add_Parameter(pl_id,'DISABLEMAIL',Text_PARAMETER,'NO'); Add_Parameter(pl_id,'DISABLEFILE',Text_PARAMETER,'NO'); Add_Parameter(pl_id,'DISABLENEW',Text_PARAMETER,'NO'); Else Add_Parameter(pl_id,'DISABLEPRINT',Text_PARAMETER,'YES'); Add_Parameter(pl_id,'DISABLEMAIL',Text_PARAMETER,'YES'); Add_Parameter(pl_id,'DISABLEFILE',Text_PARAMETER,'YES'); Add_Parameter(pl_id,'DISABLENEW',Text_PARAMETER,'YES'); End If; /*hamdy*/ if P_destination ='xls' then Add_Parameter(pl_id,'DESFORMAT',Text_PARAMETER,'csv'); Add_Parameter(pl_id,'DESTYPE',Text_PARAMETER,'FILE'); Add_Parameter(pl_id,'MODE',Text_PARAMETER,'BITMAP'); Add_Parameter(pl_id,'DESNAME',Text_PARAMETER,'C:\TEMP\EXCEL.csv'); ELSif P_destination ='pdf' then Add_Parameter(pl_id,'DESFORMAT',Text_PARAMETER,'pdf'); Add_Parameter(pl_id,'DESTYPE',Text_PARAMETER,'FILE'); Add_Parameter(pl_id,'MODE',Text_PARAMETER,'BITMAP'); Add_Parameter(pl_id,'DESNAME',Text_PARAMETER,'C:\TEMP\pdf.pdf'); ELSif P_destination ='rtf' then Add_Parameter(pl_id,'DESFORMAT',Text_PARAMETER,'RTF'); Add_Parameter(pl_id,'DESTYPE',Text_PARAMETER,'FILE'); Add_Parameter(pl_id,'MODE',Text_PARAMETER,'BITMAP'); Add_Parameter(pl_id,'DESNAME',Text_PARAMETER,'C:\TEMP\word.rtf'); end if; /*hamdy*/ Add_Parameter(pl_id,'P_Company_ID',Text_PARAMETER,:Params.level); Where_Clause := ' and e.level_id='||:Params.level; If :Params.Employee is not Null Then Where_Clause :=Where_Clause||' And E.Emp_ID = '|| :Params.Employee ; message ('i will add the emp_id'||Where_Clause); message ('i will add the emp_id'||Where_Clause); End If; Add_Parameter(pl_id,'Where_Clause',Text_PARAMETER,Where_Clause); Run_Product(REPORTS, 'HR_EMP_DTL', SYNCHRONOUS, RunTime,FILESYSTEM, pl_id, N ULL); DESTROY_PARAMETER_LIST(pl_id); END; -------------------------------------------------------------------------------------PROCEDURE Open_application(app varchar2 default 'xls') IS -- app_Path Varchar2(500):= Win_API_Environment.Read_Registry('HKEY_LOCAL_MACH INE\SOFTWARE\Microsoft\Office\8.0\Excel\InstallRoot', 'path', TRUE); File_Name Varchar2(150); AppID PLS_INTEGER; Begin

if app = 'xls' then File_Name := 'D:\Program Files\Microsoft Office\Office\Excel C:\temp\excel.xl s'; Elsif app = 'rtf' then File_Name := 'D:\Program Files\Microsoft Office\Office\winword C:\temp\word .rtf'; Elsif app = 'pdf' then File_Name := 'D:\Program Files\Adobe\Acrobat 5.0\Reader\acrord32 C:\temp\pdf. pdf'; End If; if not file_name is null then AppID := DDE.App_Begin(File_Name,DDE.App_Mode_Maximized); end if; Exception when others then Message(SQLCode||'-'||SQLErrm); End; -------------------------------------------------------------------------------calling the preceding 2 procedures: --------------------------create a button labeld "Excel" with a when_button_pressed trigger: RUN_Report('xls'); if form_success then Open_application('xls'); end if; -----------------------------------------------------------------------------------------------how to encrypt/decrypt passwords --------------------------CREATE OR REPLACE FUNCTION hamdy_encrypt( p_psw varchar2) RETURN varchar2 AS v_return varchar2(50); BEGIN if p_psw is not null then v_return := translate(p_psw,' 0123456789abcdefghijklmnopqrstuvw xyz','-9876543210zyxwvutsrqponmlkjihgfedcba'); RETURN v_return; else return null; end if; END; / -------------------------------CREATE OR REPLACE FUNCTION hamdy_decode( p_psw varchar2) RETURN varchar2 AS v_return varchar2(50); BEGIN if p_psw is not null then v_return := translate(p_psw,'-9876543210zyxwvutsrqponmlkjihgfed cba',' 0123456789abcdefghijklmnopqrstuvwxyz'); RETURN v_return;

else return null; end if; END; / ---------------------------------------------------------------------------------------------------------------------------how to unify all symobles of a text to a unique symoble ---------------------------------------------------------CREATE OR REPLACE FUNCTION nosymbols ( p_text VARCHAR2 ,p_length NUMBER ) RETURN VARCHAR2 IS v_clean VARCHAR2 (2000); BEGIN v_clean := TRANSLATE ( p_text ,'~`!@#$%^&*()_-+={}|[]\:";''<>?,./' ,';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;' ); RETURN (v_clean); END nosymbols; /

SQL> select nosymbols ( 2 'jdhfd;d,~,;kj#mm@lll$plk*' 3 ,length('jdhfd;d,~,;kj#mm@lll$plk*') 4 ) x 5 from dual; X --------------------------jdhfd;d;;;;kj;mm;lll;plk; ---------------------------------------------------------------------------------------------------------------------------extract a block to an excel file ------------------------------declare fle varchar2(200); begin fle:= get_file_name('D:\'/*default directory*/,'hm.csv'/*default file name*/,fi le_filter =>'Excel Files (*.csv)/*.csv',dialog_type => SAVE_FILE); CREATE_FLAT_FILE(fle); end; ----------------------------------------------------------------------------------------------------------------------------PROCEDURE CREATE_FLAT_FILE(Save_To VARCHAR2) IS

in_file TEXT_IO.FILE_TYPE; linebuf VARCHAR2(80); --(50) := 'C:\dept.doc'; text_line VARCHAR2(400); BEGIN in_file := TEXT_IO.FOPEN(Save_To, 'W'); GO_BLOCK('dept'); FIRST_RECORD; LOOP text_line := :deptno||';'||:dname||';'||:loc; TEXT_IO.PUT_LINE(in_file, text_line); exit when :SYSTEM.LAST_RECORD = 'TRUE'; NEXT_RECORD; END LOOP; TEXT_IO.FCLOSE(in_file); DECLARE AppID BEGIN PLS_INTEGER;

AppID := DDE.App_Begin('"C:\Program Files\Microsoft Office\Office\EXCEL. EXE" '||Save_To, DDE.APP_MODE_Maximized); END; EXCEPTION WHEN NO_DATA_FOUND THEN TEXT_IO.FCLOSE(in_file); END; ------------------------------------------------------------------------------------------------to automaticaly resize the items when the window is resized -----------------------------------------------------------WHEN-WINDOW-RESIZED (form - level) ------------------set_item_property('block.item_name',width,round(get_window_property('window1',wi dth)/3)); -----------------------------------------------------------------------------------------------time differential : ------------------FUNCTION HAMDY_TIME_DIFF(P_DATE1 DATE ,P_DATE2 DATE ) RETURN NUMBER IS V_RETURN NUMBER; BEGIN IF P_DATE1 >= P_DATE2 THEN V_RETURN := ((P_DATE1 - P_DATE2)*1440)/60; END IF; RETURN V_RETURN; END; -----------------------------------------------------------------------------------------------to look for a word in a stored procedure : --------------------------------------------select * from user_source where upper(text) like '%PORTFOLIO_TRANS%' -----------------------------------------------------------------------------------------------Arabic spell numbers : ------------------------

create or replace function Hmdy_Spell_num(P_inp_num in NUmber,v_ce in varchar2 D EFAULT '',v_de in varchar2 DEFAULT '',v_det in number DEFAULT 0,v_lan in varchar2 DEF AULT 'AR') return Varchar2 as -- -- Functions called : D3_To_Word -- Maded By Naif Salim Al hamed In 8-7-2002 email u4_13@hotmail.com -- Modified by Hamdy M. Mahmoud hamdy2001@hotmail.com L_Return Varchar2(1000) ; -m Number := 0 ; -V_inp_Num Number := 0 ; V_inp_Int Number := 0 ; V_inp_dec Number := 0 ; V_Char Varchar2(100) ; V_Temp Number := 0 ; -Type LionArray is table of Varchar2(500) ; In_str LionArray := LionArray ( '', ' ', ' ' , ' ' , ' ' ,' ' , ' ' , ' ' , ' --- ENGLSH VARIBLE eL_Return Varchar2(1000) ; -em Number := 0 ; -eV_inp_Num Number := 0 ; eV_inp_Int Number := 0 ; eV_inp_dec Number := 0 ; eV_Char Varchar2(100) ; eV_Temp Number := 0 ; -Type eLionArray is table of Varchar2(500) ; eIn_str eLionArray := eLionArray ( '', 'Thousand ' , 'Million ' , 'Billion ' , 'Trillion ' , 'Quadrillion ' , 'Quintillion ' , 'Sextillion ' , 'Septillion ' , 'Octillion ' , 'Nonillion ' , 'Decillion ' , 'Undecillion ' , 'Duodecillion '); --- Function function D3_To_Wordar (P1_number in number) return varchar2 as -- Pass only three digits -- This function return word equivalent to its number -- Accepted values are 0 to 999 -L1_Return2 varchar2(500) := NULL ; --

n1 Number := 0 ; i1 Number := 0 ; j1 Number := 0 ; k1 Number := 0 ; V1_inp_Number Number := 0 ; V1_temp Varchar2(50) := NULL; --type OneArray is table of varchar2(50); type TenArray is table of varchar2(50); type hanArray is table of varchar2(50); --

OneStr OneArray := OneArray('', ' ', '', '', '', '', '' TenStr TenArray := TenArray('', '', '', '' , '', '', ' hanStr hanArray := hanArray('', '', '' , '', '', ' -BEGIN -V1_inp_Number := P1_Number ; if V1_inp_number > 999 then V1_inp_number := 0 ; end if ; -V1_temp := LPAD(to_char(V1_inp_number),3,0) ; ---- Find Hundredth position n1 := to_number(substr(V1_temp,1,1)); -if n1 > 0 then L1_Return2 := hanStr(n1) ; end if ; ---i1 := to_number(substr(V1_temp,2,2)); j1 := to_number(substr(V1_temp,2,1)); k1 := to_number(substr(V1_temp,3,1)); -if n1>0 AND (j1>0 OR k1>0) then L1_Return2 := L1_Return2 ||' '; End if; -if i1 > 0 and i1 < 20 then L1_Return2 :=L1_Return2 || OneStr(i1) ; END IF; ---if j1 >= 2 then if k1 > 0 then L1_Return2 := L1_Return2|| OneStr(k1)|| ' ' ; end if; -L1_Return2 := L1_Return2 || TenStr(j1) ; -end if; if V1_inp_number=0 Then L1_Return2:=''; End If; -Return L1_Return2 ; ---

END D3_To_Wordar; -- another function -function Digits3_To_Word (P_number in number) return varchar2 as -- Pass only three digits -- This function return word equivalent to its number -- Accepted values are 0 to 999 -L_Return2 varchar2(500) := NULL ; -i Number := 0 ; j Number := 0 ; k Number := 0 ; -V_inp_Number Number := 0 ; V_temp Varchar2(50) := NULL; -type OneArray is table of varchar2(50); type TenArray is table of varchar2(50); OneStr OneArray := OneArray('One ', 'Two ', 'Three ', 'Four ', 'Five ', 'Six ', 'Seven ', 'Eight ', 'Nine ', 'Ten ', 'Eleven ', 'Twelve ', 'Thirteen ', 'Fourteen ', 'Fifteen ', 'Sixteen ', 'Seventeen ', 'Eighteen ', 'Nineteen '); TenStr TenArray := TenArray('', 'Twenty ', 'Thirty ', 'Forty ' , 'Fifty ', 'Sixty ', 'Seventy ', 'Eighty ', 'Ninety '); -BEGIN -V_inp_Number := P_Number ; if V_inp_number > 999 then V_inp_number := 0 ; end if ; -V_temp := LPAD(to_char(V_inp_number),3,0) ; --- Find Hundredth position i := to_number(substr(V_temp,1,1));

if i > 0 then L_Return2 := OneStr(i)||'Hundred ' ; end if ; --- Find last 2 digits i := to_number(substr(V_temp,2,2)); j := to_number(substr(V_temp,2,1)); k := to_number(substr(V_temp,3,1)); if i > 0 and i < 20 then L_Return2 := L_Return2 || OneStr(i) ; end if ; if j >= 2 then L_Return2 := L_Return2 || TenStr(j) ; if k > 0 then L_Return2 := L_Return2|| OneStr(k) ; end if; end if; -Return L_Return2 ; -END Digits3_To_Word; ---Begin -IF v_lan ='AR' Then V_inp_Num := ABS(P_inp_Num) ; V_inp_Int := Trunc(V_inp_Num) ; V_inp_Dec := V_inp_Num - V_inp_Int ; --- To abort to 100 if V_inp_Dec > 0 then V_inp_dec := V_inp_dec * 100 ; V_inp_Dec := to_number(substr(to_char(V_inp_Dec),1,2)) ; end if ; --V_char := to_char(V_inp_Int) ; -for m in 1..In_Str.Count Loop Exit when V_char is NULL ; -V_Temp := To_Number(Substr(V_char,(Length(V_char)-2), 3)); -if V_temp > 0 then L_Return := D3_To_WordAR(V_Temp) || In_str(m)||' ' || L_Return ; end if ; -V_char := Substr(V_char,1,(Length(V_Char)-3)); -End Loop ; -L_return :=Substr(L_return,1,(Length(L_return)-1)); -IF P_inp_num>=1000 and P_inp_num<2000 Then L_return:=Substr(L_return,5,Length(L _return)); End if ; -IF P_inp_num>=2000 and P_inp_num<3000 Then L_return:=''||Substr(L_return,11,Length(L _return));

End if ; -IF P_inp_num>=3000 and P_inp_num<=10000 Then -L_return:=Substr(L_return,1,(INSTR(L_return,'')-1)) || '' || Substr(L_return,(INSTR(L_ eturn,'')+3),Length(L_return)); -End if ; -if v_det=1 then if V_inp_Dec > 0 then L_return := L_return ||v_ce||' ' || to_char(V_inp_Dec)||v_de; ELSE L_return := L_return ||' '||v_ce; end if; Else if V_inp_Dec > 0 then L_return := L_return ||v_ce||' ' ||D3_To_WordAR(V_inp_Dec)||' '||v_de; ELSE L_return := L_return ||' '||v_ce; end if; End if; -if V_inp_Int > 0 then L_Return := L_Return; elsif V_inp_Int = 0 then L_return := '===' ; end if ; Return L_return; -ELSE if P_inp_num < 0 then eV_inp_Num := (P_inp_Num * -1) ; else eV_inp_Num := P_inp_Num; end if; eV_inp_Int := Trunc(eV_inp_Num) ; eV_inp_Dec := eV_inp_Num - eV_inp_Int ; if eV_inp_Dec > 0 then eV_inp_dec := eV_inp_dec * 100 ; eV_inp_Dec := to_number(substr(to_char(eV_inp_Dec),1,2)) ; end if ; -eV_char := to_char(eV_inp_Int) ; -for em in 1..eIn_Str.Count Loop exit when eV_char is NULL ; eV_Temp := To_Number(Substr(eV_char,(Length(eV_char)-2), 3)); -if eV_temp > 0 then eL_Return := Digits3_To_Word(eV_Temp) || eIn_str(em) || eL_Return ; end if ; -eV_char := Substr(V_char,1,(Length(eV_Char)-3)); -End Loop ; -if eV_inp_Int > 0 then eL_Return := v_ce||' '||eL_Return ||' and '; elsif eV_inp_Int = 0 then eL_return := v_ce||' Zero and ' ; end if ;

--- Concatenate the word for decimal digits if v_det=1 then if eV_inp_Dec > 0 then eL_return := eL_return || Digits3_To_Word(eV_inp_Dec) ||' '||v_de; elsif eV_inp_Dec = 0 then eL_Return := eL_return ||' Zero '||v_de; End if ; ELSE if eV_inp_Dec > 0 then eL_return := eL_return || to_char(eV_inp_Dec) ||' '||v_de; elsif eV_inp_Dec = 0 then eL_Return := eL_return ||' Zero '||v_de; End if ; END if; Return eL_return; End IF; END ; / --------------------------------------------------------------------------------------------declare v_empno employees.employee_id%type := 100; begin merge into copy_emp c using employees e on (e.employee-id = v_emono) when matched then update set c.first_name = e.first_name, c.last_name = e.last_name, c.email = e.email, .... when not matched then insert values(e.employee_id,e.first_name,e.last_name...); end; ---------------------------------------------------------------------------begin delete from emp; dbms_output.put_line('count of rows deleted ='||sql%rowcount); end; / ---------------------------------------------------------------------------sql%rowcount sql%found sql%notfound sql%isopen ---------------------------------------------------------------------------CASE (LIKE IF) ---------------SET SERVEROUTPUT ON DECLARE V_GRADE char(1) := upper('&p_grade');

v_appraisal begin

varchar2(20);

v_appraisal := case v_grade when 'A' then 'Excellent' when 'B' then 'very Good' when 'C' then 'Good' Else 'No such grade' end; dbms_output.put_line('Grade: '||v_grade||' Appraisal '||v_appraisal'); end; / -------------------------------------------------------reverse loop -------------begin for i in reverse 1..100 loop dbms_output.put_line(i); end loop; end; / -------------------------------------------------------idea --------set serveroutput on begin for i in (select * from emp) loop dbms_output.put_line(i.ename||' with salary of'||i.sal); end loop; end; / -------------------------------------------------------index by tables --------------EX 1: ---declare type dept_table_type is table of dept%rowtype index by binary_integer; dept_table dept_table_type; x number; c number; begin x:=10; select count(*) into c from dept; for i in 1..c loop select * into dept_table(i) from dept where deptno = x; x := x+10; end loop; x := 1; for m in dept_table.first..dept_table.last loop dbms_output.put_line(dept_table(m).dname||' '||dept_table(m).loc); end loop; exception when no_data_found then dbms_output.put_line(dept_table.count);

end; / --------------------------------Ex 2: ----declare type numlist is table of number; mgrs numlist := numlist(100,101,102,103,..); -- managers numbers begin forall i in mgrs.first..mgrs.last loop delete from employees where manager_id = mgrs(i); end loop; end;

------------------------------------------------------------to know the monitor settings (800x600 ...) -----------------------------------------message('display height = '||get_application_property(display_height)/.75||' and width = '|| get_application_property(display_width)/.75); -----------------------------------------------------------------------------------current of in a cursor ----------------------declare cursor sal_cursor is select e.deptno,empno,ename,sal from emp e,dept d where d.deptno=e.deptno and d.deptno=30 for update of sal nowait; begin for emp_record in sal_cursor loop if emp_record.sal<5000 then update emp set sal= emp_record.sal * 1.1 where currenct of sal_cursor; end if; end loop; end; / note: you have to include the for update clause in the curosr in order to be abl e to use where current of clause. ------------------------------------------------------Exception handling ---------------------trap for oracle server error number -2292,an integrity constraint biolation. ------------------------------------------define p_deptno = 10

declare e_emps_remaining exception; pragma exception_init (e_emps_remaining,-2292); begin delete from dept where deptno = &p_deptno; commit; exception when e_emps_remaining then dbms_output.put_line('cannot remove dept '|| to_char(&p_deptno)||'. Employees exist. '); end; -------------------------------------------------------------------SQLCODE SQLERRM ----------------------------------------------user-defined exceptions ----------------------define p_dnm = 'Information Technology' define p_dept_no = 300 declare e-invalid_dept exception; begin update dept set dname = '&p_dnm' where deptno = &p_dept_no; if SQL%NOTFOUND THEN RAISE e_invalid_dept; end if; commit; exception when e_invalid_dept then dbms_output.put_line('No such deptno.'); end; --------------------------------------------------raise_application_error:-------------------------use within the stored program units either in: - the executable section or - the exception section Executable section: ------------------begin ..... delete from emp where mgr = 9000; if sql%notfound then raise_application_error(-20202, 'This is not a valid manager'); end if; ....... -----------------------

exception section ----------------..... exception when no_data_found then raise_application_error(-20201, 'Manager is not a valid employee.'); end; -------------------------------------------------------------------

create or replace procedure format_phone (p_phone_no in out varchar2) is begin p_phone_no :='('||substr(p_phone_no,1,3|| ')'||substr(p_phone_no,4,3)|| '-'||'('||substr(p_phone_no,7); end format_phone; / ----------------------------------------------------------------------------HOW TO PASS PARAMETERS TO PROCEDURES WHICH HAS DEFAULT VALUES: --------------------------------------------------procedure add_dept (p_nm in varchar2 default 'unknown', p_loc in number default 'cairo') is begin insert into dept values(dept_seq.next_val,p_nm,p_loc); end; / examles of how to pass parameters to this procedure: ----------------------------------------------------------------------begin add_dept; add_dept('training','Giza'); add_dept(p_loc => 'Giza',p_nm =>'Education'); add_dept(p_loc =>'Alex'); end; / --------------------------------------------------------------------------Extract the source code from the database: --------------------------------------------------------VARIABLE SRC VARCHAR2(2000); BEGIN FOR I IN (SELECT TEXT FROM USER_SOURCE WHERE NAME ='GET_HOLIDAYS' ORDER BY LINE ) LOOP IF :SRC IS NULL THEN :SRC := I.TEXT; ELSE

:SRC :=:SRC||CHR(13)||I.TEXT; END IF; END LOOP; END; / ----------------------------------------------------------------------------------------------------------declaring a bodiless package ---------------------------------------create or replace package global_consts is mile_2_kilo constant number := 1.6093; kilo_2_mile constant number := 0.6214; yard_2_meter constant number := 0.9144; meter_2_yard constant number := 1.0936; mile_2_kilo constant number := 1.6093; end global_consts; / to try the package: -------------------------execute dbs_output.put_line('20 miles = '||20* global.consts.mile_2_kilo||' km'); -----------------------------------------------------------------------------------PL/SQL TABLES AND RECORDS IN PACKAGES ------------------------------------------------------------------------create or replace package emp_package is type emp_table_type is table of emp%rowtype index by binary_integer; procedure read_emp_table (p_emp_table out emp_table_type); end emp_package; / create or replace package body emp_package is procedure read_emp_table (p_emp_table out emp_table_type) is i binary_integer := 0; begin for emp_record in (select * from emp) loop p_emp_table(i) := emp_record; i := i + 1; end loop; end read_emp_table; end emp_package; / --------------------------------------------------------------------------------------------how to use the preceding package: _------------------------------------------declare v_emp_table emp_package.emp_table_type; begin emp_package.read_emp_table (v_emp_table); dbms_output.put_line('an example'||v_emp_table(4).last_name); end; /

------------------------------------------------------------------------------------------------DYNAMIC SQL -----------------------forms_ddl('create or replace function get_data return varchar2 is'|| ' rslt varchar2(100); begin select '||:tt||' into rslt from dept where deptno=10 ; RETURN RSLT; end;'); :tt := get_data; -------------------------------------------------------------------------------------------------------------------------dynamic insert statement -------------------------------------select 'insert into dept values(' ||deptno||','''||dname||''','''||loc||''');' from dept; 'INSERTINTODEPTVALUES('||DEPTNO||','||DNAME||','||LOC||');' ----------------------------------------------------------------------------------------insert into dept values(10,ACCOUNTING,NEW YORK); insert into dept values(20,RESEARCH,DALLAS); insert into dept values(30,SALES,CHICAGO); insert into dept values(40,OPERATIONS,BOSTON); -----------------------------------------------------scripts for hr ---------------------C:\oracle\ora92\demo\schema\human_resources -------------------------------------------------------------------------------------------------------------------------------------------tab pages --------------when-tab-page-changed (form level) ----------------------------------begin if :system.tab_new_page = 'ADDRESS' then go_item('s_customer.name'); else if :system.tab_new_page = 'BILLING' then go_item('s_customer.credit_rating'); else go_item('s_customer.comments'); end if; end if; end; ------------------------------------------------------------------------------when-new-record-instance (block level) -------------------------------------Declare tb_pg_id TAB_PAGE; Begin

tb_pg_id := FIND_TAB_PAGE('COMMENTS'); if :s_customer.comments is null then SET_TAB_PAGE_PROPERTY(tb_pg_id, enabled, propert y_false); else SET_TAB_PAGE_PROPERTY(tb_pg_id, enabled, property_true); End If; :global.custid := :s_customer.id; End; ---------------------------------------------------------------------------------when-checkbox-changed ======================= IF NVL(:CONTROL.case_sensitive, 'Y') = 'Y' THEN SET_ITEM_PROPERTY('S_CUSTOMER.name', CASE_INSENSITIVE_QUERY, PROPERTY_FALSE); ELSE SET_ITEM_PROPERTY('S_CUSTOMER.name',CASE_INSENSITIVE_QUERY, PROPERTY_TRUE); END IF; ================================================================================ ===== dynamic sorting ============== 1 - create on top of every column item a button as a label of the column but wit h the same name of the column ending by ( _btn) 2 - when-button-pressed (block level of the buttons) type the following code: set_block_property('emp',order_by,substr(:system.cursor_item,1,instr(:syst em.cursor_item,'_',1)-1) ); go_block('emp'); execute_query; ================================================================================ ===== hide and show tab pages ===================== DECLARE tb_pg_id TAB_PAGE; BEGIN tb_pg_id := FIND_TAB_PAGE('P2'); IF GET_TAB_PAGE_PROPERTY(tb_pg_id, visible) = 'FALSE' THEN SET_TAB_PAGE_PROPERTY(tb_pg_id, visible, property_true); set_item_property('btn',label,'Hide'); else SET_TAB_PAGE_PROPERTY(tb_pg_id, visible, property_false); set_item_property('btn',label,'Show'); END IF; END; ================================================================================ ==== synchronize ============= go_block('emp'); execute_query;

first_record; loop :tt := 'currently processing Employee -who works as "'||:job||'"'; for i in 1..20000 loop synchronize; end loop; exit when :System.Last_Record = 'TRUE'; next_record; end loop; first_record; ================================================================================ ==== size window in motion ================= IF GET_ITEM_PROPERTY('BTN',LABEL) = 'VIEW' THEN for i in 1..125 loop SET_ITEM_PROPERTY('BTN',LABEL,'HIDE'); for i in 1 .. 200 loop null; synchronize; end loop; SET_WINDOW_PROPERTY('WINDOW1',HEIGHT,get_window_property('WINDOW1',HEIGHT)+1) ; end loop; ELSE SET_ITEM_PROPERTY('BTN',LABEL,'VIEW'); SET_WINDOW_PROPERTY('WINDOW1',HEIGHT,175); END IF; ================================================================================ ===== extracting the date of a tabular datablock to a text file: =========================================== 1 - create a procedure in the program unit like that : ======================================= PROCEDURE CREATE_FLAT_FILE(Save_To VARCHAR2) IS in_file TEXT_IO.FILE_TYPE; text_line VARCHAR2(400); AppID PLS_INTEGER; BEGIN in_file := TEXT_IO.FOPEN(Save_To, 'W'); GO_BLOCK('dept'); FIRST_RECORD; LOOP text_line := :deptno||';'||:dname||';'||:loc; TEXT_IO.PUT_LINE(in_file, text_line); exit when :SYSTEM.LAST_RECORD = 'TRUE'; NEXT_RECORD; END LOOP;

TEXT_IO.FCLOSE(in_file); AppID := DDE.App_Begin('"C:\Program Files\Microsoft Office\Office\EXCEL. EXE" '||Save_To, DDE.APP_MODE_Maximized); EXCEPTION WHEN NO_DATA_FOUND THEN TEXT_IO.FCLOSE(in_file); END; ---------------------------------------2 - create a button with a when button pressed trigger : ======================================== declare fle varchar2(200); begin fle:= get_file_name('D:\'/*default directory*/,'hm.csv'/*default file name*/,fi le_filter =>'Excel Files (*.csv)/*.csv',dialog_type => SAVE_FILE); CREATE_FLAT_FILE(fle); end; ================================================================================ ==== moving and copying system files : ---------------------------------------------1- we need to attach the d2kwutil.pll to the form 2 - a button with this trigger: ('c:\test.doc'/*the file Win_Api_Utility.Move_Filewhich is needed to be moved*/,'d:\hamdy.doc' /*this is the new file name and location*/); ================================================================================ ===== to cancel a report if the ouput is null -------------------------------------------------befor report trigger: ================== Function BEF_REP_TRG return boolean is count_inv number; begin select count(*) into count_inv from EMP where DEPTNO= :P_DEPTNO ; if count_inv = 0 then srw.message (0, 'No DATA found for printing'); --return false; /* or use SRW.PRORAM_ABORT; RAise srw.program_abort; end if; return true; End; ================================================================================ ===== to dynamically show only the number of records specified in a group filter: --------------in the data model: -----------------select the group then F11 and put the following code:

*/

function G_CUSTOMER_IDGroupFilter return boolean is begin :P_COUNT_CUST/* a parameter */ := nvl(:P_COUNT_CUST,0) + 1; IF :P_COUNT_CUST <= :P_CUTOFF /*this the parameter that's showed for the user so he can enter the number of records he needs to desplay*/ THEN return (TRUE); ELSE return(FALSE); END IF; end; ----------------------------------------------------------------------------------------------to run a drill - down report : --------------------------------in the master report create a button and set its type to pl/sql then put the fol lowing code : -------------------------------------------------------------procedure U_1ButtonAction is begin srw.run_report ('report=s18q2c.rep p_customer=' ||to_char(:customer_id)|| ' paramform=no'); -- The paramform argument is optional, default=no, but it -- shows how to enter multiple arguments in this command end; -- srw.run_report -- ('report=p2q8_det.rep p_custid=' ||to_char(:id)|| ' paramform=no'); ---------------------------------------------------------------------------------------------ddl and dml in reports before_report ------------function BeforeReport return boolean is begin BEGIN srw.do_sql('CREATE TABLE RUNREPORT(DATE_RUN DATE,USER_RUN VARCHAR2(20), COMMENTS VARCHAR2(80))'); exception when srw.do_sql_failure then null; end; begin SRW.MESSAGE(10000,'INSERTING'); srw.do_sql('INSERT INTO RUNREPORT VALUES(SYSDATE,USER,''Starting Report'')'); return(TRUE); end; end; -------------------------------------------------------------------------------------To know the size of tables in a user: -------------------------------select round(sum(bytes)/1000000)||' MB' from user_segments where segment_type = 'TABLE' ; --------------------------------------------------------------------------------

----displaying the names of employees who gain the max(sal) in every department: ------------------------------------------------------------select ename,sal,deptno from emp where (deptno,sal) in ( select deptno,max(sal) from emp group by deptno); -----------------------------------------------------------------------------------to know the version of oracle products: ---------------------------------select * from product_component_version; -----------------------------------------------------------------------------------display the table structures: ---------------------select sys.user_tab_columns.table_name, sys.user_tab_columns.column_name, sys.user_tab_columns.data_type, sys.user_tab_columns.data_length, sys.user_tab_columns.data_precision, sys.user_tab_columns.data_scale/*, sys.user_tab_columns.table_type*/ from sys.user_tab_columns,sys.user_catalog where(sys.user_tab_columns.table_name=sys.user_catalog.table_name) and sys.user_tab_columns.table_name like upper('%&tab%') order by sys.user_tab_columns.table_name / ---------------------------------------------------------------------------------To import specific tables from a dmp file: ----------------------------------imp userid=xyz/xyz file=c:\scott.dmp fromuser=scott tables=('emp','dept') To import all tables from a dmp file: ----------------------------------imp userid=xyz/xyz file=c:\scott.dmp fromuser=scott tables=* ---------------------------------------------------------------------------------Dynamic List-Item ---------------------1 - create a group named rg with the following query: select dname,to_char(deptno) from dept 2 - create a list item called lst 3 - create a form level trigger (when-new-form-instance) with the following code : declare pg number; begin pg := populate_group('rg'); /*returns 0 if executed succefully */ populate_list('lst','rg'); end;

----------------------------------------------------------------------------------------------openning a report from within a form or a menu: ------------------------------------------------declare pl_id begin ParamList;

pl_id := Get_Parameter_List('emps'); IF NOT Id_Null(pl_id) THEN Destroy_Parameter_List( pl_id ); end if; pl_ID := Create_Parameter_List('emps'); Add_Parameter(pl_id,'Paramform',Text_PARAMETER,'NO'); Add_Parameter(pl_id,'MAXIMIZE',Text_PARAMETER,'Yes'); Run_Product(REPORTS, 'port_cash_available', SYNCHRONOUS, RunTime,FILESYSTEM, pl _id, NULL); end; --------------------------------------------------------------------------------------------dynamically select the first n rows from a query: ---------------------------------------------------1 - create a parameter called mx 2 - before report trigger function BeforeReport return boolean is begin srw.set_maxrow('Q_1'/*query name from the data model*/,:mx); return (TRUE); end; --------------------------------------------------------------------------------------------dynamic order by --------------------------------create a listitem with all the names of the table names then type the following trigger: when-list-changed ----------------------set_block_property('EMP', ORDER_BY, :control.sort_by); go_block('EMP'); execute_query; ----------------------------------------------------------------------------dynamic backup ------------* - create a form with a button. * - create a WHEN-BUTTON-PRESSED trigger with the following code: host('exp userid=system/manager file=c:\backup.dmp full=yes log=c:\backup.txt'); -----------------------------------------------------------------------------

to create an O'clock on your form : -----------------------------1 - when-new-form-instance -------------------DECLARE timer_id Timer; one_minute NUMBER(5) := 1000; BEGIN timer_id := CREATE_TIMER('HM', one_minute,REPEAT); END; 2 - when-timer-expired ------------------DECLARE time VARCHAR2(20); BEGIN SELECT TO_CHAR(SYSDATE,'HH:MI:SS AM') INTO :TOOLBAR.CLOCK FROM DUAL; END; ----------------------------------------------------------------------------what was affected by ur DML statement: -------------------------------begin ..... delete from emp where mgr = 9000; if sql%notfound then raise_application_error(-20202, 'This is not a valid manager'); end if; ....... ----------------------------------------------------------------------------DYNAMIC SQL in forms -----------------------forms_ddl('....'); ----------------------------------------------------------------------------dynamic insert statement -------------------select 'insert into dept values(' ||deptno||','''||dname||''','''||loc||''');' from dept; ----------------------------------------------------------------------------when-tab-page-changed (form level) ----------------------------------begin if :system.tab_new_page = 'ADDRESS' then go_item('s_customer.name'); else if :system.tab_new_page = 'BILLING' then go_item('s_customer.credit_rating'); else go_item('s_customer.comments'); end if;

end if; end; ----------------------------------------------------------------------------when-new-record-instance (block level) -------------------------------------Declare tb_pg_id TAB_PAGE; Begin tb_pg_id := FIND_TAB_PAGE('COMMENTS'); if :s_customer.comments is null then SET_TAB_PAGE_PROPERTY(tb_pg_id, enabled, propert y_false); else SET_TAB_PAGE_PROPERTY(tb_pg_id, enabled, property_true); End If; :global.custid := :s_customer.id; End; ----------------------------------------------------------------------------dynamic sorting ============== 1 - create on top of every column item a button as a label of the column but wit h the same name of the column ending by ( _btn) 2 - when-button-pressed (block level of the buttons) type the following code: set_block_property('emp',order_by,substr(:system.cursor_item,1,instr(:syst em.cursor_item,'_',1)-1) ); go_block('emp'); execute_query; ----------------------------------------------------------------------------PACKAGE emp_proc AS TYPE emp_t IS RECORD( NAME emp.ename%TYPE, ID emp.empno%TYPE); -- For SELECT TYPE rec_t IS TABLE OF emp_t INDEX BY BINARY_INTEGER ; PROCEDURE emp_rec( p_table IN OUT rec_t); END; ------------------------------PACKAGE BODY emp_proc AS PROCEDURE emp_rec( p_table IN OUT rec_t)

IS v_ct NUMBER := 1; BEGIN FOR emp_r IN (SELECT * FROM EMP) LOOP p_table(v_ct).name := emp_r.ename; p_table(v_ct).id := emp_r.empno; v_ct := v_ct + 1; END LOOP; END; END; --------------------------------------------------------------------------------------------to trace the execution of a form (extracting a log file to debug a form ) ------------------------------------------------------C:\orant\BIN\F50RUN32.EXE module=c:\emps.fmx userid=scott/tiger record=collect l og=c:\emps.log ----------------------------------------------------------------------------To know how many objects does the user have and its grand total: ------------------------------------------------------SELECT * FROM( SELECT 1 M,OBJECT_TYPE,COUNT(*) CNT FROM USER_OBJECTS GROUP BY OBJECT_TYPE UNION SELECT 2 M,' TOTAL' OBJECT_TYPE,COUNT(*) CNT FROM USER_OBJECTS ) ORDER BY M,OBJECT_TYPE ------------------------------------------------------------------------------TO COMPARE TWO DATABASES OBJECTS -------------------------------SELECT * FROM ( SELECT 1 XX,x.OBJECT_TYPE,COUNT(x.OBJECT_TYPE) LOCAL,COUNT(y.OBJECT_TYPE) SERVER FROM USER_OBJECTS x,USER_OBJECTS@ORACLE y WHERE Y.OBJECT_TYPE=X.OBJECT_TYPE GROUP BY X.OBJECT_TYPE UNION SELECT 2 XX,'TOTAL' OBJECT_TYPE,COUNT(x.OBJECT_TYPE) LOCAL,COUNT(y.OBJECT_TYPE) SERVER FROM USER_OBJECTS x,USER_OBJECTS@ORACLE y WHERE Y.OBJECT_TYPE=X.OBJECT_TYPE ) ORDER BY XX,OBJECT_TYPE -------------------------------------------------------------------------------- to create a user with its privileges in one command --------------------------------------------GRANT RESOURCE,DBA TO po IDENTIFIED BY po ------------------------------------------------------------------------------ tables structure ---------------------select sys.user_tab_columns.table_name, sys.user_tab_columns.column_name, sys.user_tab_columns.data_type, sys.user_tab_columns.data_length, sys.user_tab_columns.data_precision from sys.user_tab_columns,sys.user_catalog where(sys.user_tab_columns.table_name=sys.user_catalog.table_name)

and (sys.user_tab_columns.table_name like upper('%'||:tab||'%') or nvl(:tab,'x') = 'x') order by sys.user_tab_columns.table_name ----------------------------------------------------------------- dabase functions and procedures structures -- view structures ---------------------------------------------------------------to run a script from a batch file -------------------------* - create a batch file(*.bat) with the following code PLUS80W.exe scott/tiger @c:\tr.txt ------------------------------------------------------------------------- drill down report -- secuirty system -- tree item ------------------------------------------------------------------------ tree report ------------SELECT lpad('+ '||INITCAP(ename),level*5,' ') FROM emp START WITH mgr IS NULL CONNECT BY PRIOR empno = mgr --------------------------------------------------------------------------- bilingual interface -- dynamic change of the menu labels --------------------------------------------------------------------------to hide and unhide tab pages ------------------------when-button-pressed -----DECLARE tb_pg_id TAB_PAGE; BEGIN tb_pg_id := FIND_TAB_PAGE('P2'); IF GET_TAB_PAGE_PROPERTY(tb_pg_id, visible) = 'FALSE' THEN SET_TAB_PAGE_PROPERTY(tb_pg_id, visible, property_true); set_item_property('btn',label,'Hide'); else SET_TAB_PAGE_PROPERTY(tb_pg_id, visible, property_false); set_item_property('btn',label,'Show'); END IF; END; --------------------------------------------------------------------------------to show the progress of a specific action -------------------------------- suppose we have a tabulare form of emp table - we create non-database text item called :tt - we create a button with a when-button-pressed: begin go_block('emp'); execute_query; first_record; loop

:tt := 'currently processing Employee :('||:ename||') who works as "'||:job||'" '; for i in 1..20000 loop synchronize; end loop; exit when :System.Last_Record = 'TRUE'; next_record; end loop; first_record; end; ------------------------------------------------------------------------------ to create a dynamic sorting -1- create a tabular form based on emp table 2- above every column create a button with the same name of the database column + _btn 3- set the number of records displayed of the buttons to be 1 4- create a when-button-pressed trigger (block scope) : begin set_block_property('emp',order_by,substr(:system.cursor_item,1,instr(:system.cur sor_item,'_',1)-1) ); go_block('emp'); execute_query; end; ---------------------------------------------------------------------------------- resize window ----------------begin IF GET_ITEM_PROPERTY('BTN',LABEL) = 'VIEW' THEN SET_ITEM_PROPERTY('BTN',LABEL,'HIDE'); SET_WINDOW_PROPERTY('WINDOW1',HEIGHT,300); ELSE SET_ITEM_PROPERTY('BTN',LABEL,'VIEW'); SET_WINDOW_PROPERTY('WINDOW1',HEIGHT,175); END IF; end; ----------------------------------------------------------------------------------extract data to text file or excel ---------------------------------1- create a tabular form based on emp table 2- create a procedure with the following code in the program-units : PROCEDURE CREATE_FLAT_FILE(Save_To VARCHAR2) IS in_file TEXT_IO.FILE_TYPE; linebuf VARCHAR2(80); --(50) := 'C:\dept.doc'; text_line VARCHAR2(400); BEGIN in_file := TEXT_IO.FOPEN(Save_To, 'W'); GO_BLOCK('dept'); FIRST_RECORD; LOOP text_line := :deptno||';'||:dname||';'||:loc; TEXT_IO.PUT_LINE(in_file, text_line); exit when :SYSTEM.LAST_RECORD = 'TRUE'; NEXT_RECORD; END LOOP;

TEXT_IO.FCLOSE(in_file); DECLARE AppID BEGIN PLS_INTEGER;

AppID := DDE.App_Begin('"C:\Program Files\Microsoft Office\Office\EXCEL. EXE" '||Save_To, DDE.APP_MODE_Maximized); END; EXCEPTION WHEN NO_DATA_FOUND THEN TEXT_IO.FCLOSE(in_file); END; -----------------------------------------------------------------------------------3- create a button with a when-button-pressed: declare fle varchar2(200); begin fle:= get_file_name('D:\'/*default directory*/,'hm.csv'/*default file name*/,fi le_filter =>'Excel Files (*.csv)/*.csv',dialog_type => SAVE_FILE); CREATE_FLAT_FILE(fle); end; ------------------------------------------------------------------------------------ top_N ------------------------------------------------------------------------------------- creating a clock in the forms -----------------------------

-----------------------------------------------------------------------------------drilldown report -------------1- Create two reports DEPTS and EMPS - in the EMPS report create a parameter nam ed P_DEPTNO in the where clause of the report query (in the Data Model) 2- in the layout create a button 3- in the property pallete of that button set the (TYPE) property to be PL/SQL 4- in the property pallete of that button set the (PL/SQL TRIGGER) TO THE FOLLOW ING: function U_1ButtonAction return boolean is begin srw.run_report('report=c:\emps_rep '|| ' P_DEPTNO='||:DEPT_ID ); return true; EXCEPTION when srw.run_report_failure then srw.message(30, 'Error mailing reports.'); raise srw.program_abort; end; ------------------------------------------------------------------------------------

declare v_empno employees.employee_id%type := 100; begin merge into copy_emp c using employees e on (e.employee-id = v_emono) when matched then update set c.first_name = e.first_name, c.last_name = e.last_name, c.email = e.email, .... when not matched then insert values(e.employee_id,e.first_name,e.last_name...); end; ---------------------------------------------------------------------------begin delete from emp; dbms_output.put_line('count of rows deleted ='||sql%rowcount); ----------end; / ---------------------------------------------------------------------------sql%rowcount sql%found sql%notfound sql%isopen ---------------------------------------------------------------------------CASE (LIKE IF) ---------------SET SERVEROUTPUT ON DECLARE V_GRADE char(1) := upper('&p_grade'); v_appraisal varchar2(20); begin v_appraisal := case v_grade when 'A' then 'Excellent' when 'B' then 'very Good' when 'C' then 'Good' Else 'No such grade' end; dbms_output.put_line('Grade: '||v_grade||' Appraisal '||v_appraisal'); end; / -------------------------------------------------------reverse loop -------------begin for i in reverse 1..100 loop dbms_output.put_line(i); end loop;

end; / -------------------------------------------------------idea --------set serveroutput on begin for i in (select * from emp) loop dbms_output.put_line(i.ename||' with salary of'||i.sal); end loop; end; / -------------------------------------------------------labtop Emarats Ajman university 4500 acer karfour fe al-sharka 4500 acer ------------------------------------------------------------index by tables --------------EX 1: ---declare type dept_table_type is table of dept%rowtype index by binary_integer; dept_table dept_table_type; x number; c number; begin x:=10; select count(*) into c from dept; for i in 1..c loop select * into dept_table(i) from dept where deptno = x; x := x+10; end loop; x := 1; for m in dept_table.first..dept_table.last loop dbms_output.put_line(dept_table(m).dname||' '||dept_table(m).loc); end loop; exception when no_data_found then dbms_output.put_line(dept_table.count); end; / --------------------------------Ex 2: ----declare type numlist is table of number; mgrs numlist := numlist(100,101,102,103,..); -- managers numbers begin forall i in mgrs.first..mgrs.last loop delete from employees where manager_id = mgrs(i); end loop; end;

------------------------------------------------------------to know the monitor settings (800x600 ...) -----------------------------------------message('display height = '||get_application_property(display_height)/.75||' and width = '|| get_application_property(display_width)/.75); -----------------------------------------------------------------------------------current of in a cursor ----------------------declare cursor sal_cursor is select e.deptno,empno,ename,sal from emp e,dept d where d.deptno=e.deptno and d.deptno=30 for update of sal nowait; begin for emp_record in sal_cursor loop if emp_record.sal<5000 then update emp set sal= emp_record.sal * 1.1 where currenct of sal_cursor; end if; end loop; end; / note: you have to include the for update clause in the curosr in order to be abl e to use where current of clause. ------------------------------------------------------Exception handling ---------------------trap for oracle server error number -2292,an integrity constraint biolation. ------------------------------------------define p_deptno = 10 declare e_emps_remaining exception; pragma exception_init (e_emps_remaining,-2292); begin delete from dept where deptno = &p_deptno; commit; exception when e_emps_remaining then dbms_output.put_line('cannot remove dept '|| to_char(&p_deptno)||'. Employees exist. '); end; -------------------------------------------------------------------SQLCODE

SQLERRM ----------------------------------------------user-defined exceptions ----------------------define p_dnm = 'Information Technology' define p_dept_no = 300 declare e-invalid_dept exception; begin update dept set dname = '&p_dnm' where deptno = &p_dept_no; if SQL%NOTFOUND THEN RAISE e_invalid_dept; end if; commit; exception when e_invalid_dept then dbms_output.put_line('No such deptno.'); end; --------------------------------------------------raise_application_error:-------------------------use within the stored program units either in: - the executable section or - the exception section Executable section: ------------------begin ..... delete from emp where mgr = 9000; if sql%notfound then raise_application_error(-20202, 'This is not a valid manager'); end if; ....... ----------------------exception section ----------------..... exception when no_data_found then raise_application_error(-20201, 'Manager is not a valid employee.'); end; -------------------------------------------------------------------

create or replace procedure format_phone (p_phone_no in out varchar2) is begin p_phone_no :='('||substr(p_phone_no,1,3|| ')'||substr(p_phone_no,4,3)|| '-'||'('||substr(p_phone_no,7); end format_phone; / ----------------------------------------------------------------------------HOW TO PASS PARAMETERS TO PROCEDURES WHICH HAS DEFAULT VALUES: --------------------------------------------------procedure add_dept (p_nm in varchar2 default 'unknown', p_loc in number default 'cairo') is begin insert into dept values(dept_seq.next_val,p_nm,p_loc); end; / examles of how to pass parameters to this procedure: ----------------------------------------------------------------------begin add_dept; add_dept('training','Giza'); add_dept(p_loc => 'Giza',p_nm =>'Education'); add_dept(p_loc =>'Alex'); end; / --------------------------------------------------------------------------Extract the source code from the database: --------------------------------------------------------VARIABLE SRC VARCHAR2(2000); BEGIN FOR I IN (SELECT TEXT FROM USER_SOURCE WHERE NAME ='GET_HOLIDAYS' ORDER BY LINE ) LOOP IF :SRC IS NULL THEN :SRC := I.TEXT; ELSE :SRC :=:SRC||CHR(13)||I.TEXT; END IF; END LOOP; END; / ----------------------------------------------------------------------------------------------------------declaring a bodiless package ---------------------------------------create or replace package global_consts is mile_2_kilo constant number := kilo_2_mile constant number := yard_2_meter constant number := meter_2_yard constant number := mile_2_kilo constant number :=

1.6093; 0.6214; 0.9144; 1.0936; 1.6093;

end global_consts; / to try the package: -------------------------execute dbs_output.put_line('20 miles = '||20* global.consts.mile_2_kilo||' km'); -----------------------------------------------------------------------------------PL/SQL TABLES AND RECORDS IN PACKAGES ------------------------------------------------------------------------create or replace package emp_package is type emp_table_type is table of employees%rowtype index by binary_integer; procedure read_emp_table (p_emp_table out emp_table_type); end emp_package; / create or replace package body emp_package is procedure read_emp_table (p_emp_table out emp_table_type) is i binary_integer := 0; begin for emp_record in (select * from employees) loop p_emp_table(i) := emp_record; i := i + 1; end loop; end read_emp_table; end emp_package; / --------------------------------------------------------------------------------------------how to use the preceding package: _------------------------------------------declare v_emp_table emp_package.emp_table_type; begin emp_package.read_emp_table (v_emp_table); dbms_output.put_line('an example'||v_emp_table(4).last_name); end; / ------------------------------------------------------------------------------------------------DYNAMIC SQL -----------------------forms_ddl('create or replace function get_data return varchar2 is'|| ' rslt varchar2(100); begin select '||:tt||' into rslt from dept where deptno=10 ; RETURN RSLT; end;'); :tt := get_data; -------------------------------------------------------------------------------------------------------------------------dynamic insert statement -------------------------------------select 'insert into dept values(' ||deptno||','||dname||','||loc||');' from dept;

'INSERTINTODEPTVALUES('||DEPTNO||','||DNAME||','||LOC||');' ----------------------------------------------------------------------------------------insert into dept values(10,ACCOUNTING,NEW YORK); insert into dept values(20,RESEARCH,DALLAS); insert into dept values(30,SALES,CHICAGO); insert into dept values(40,OPERATIONS,BOSTON); -----------------------------------------------------scripts for hr ---------------------C:\oracle\ora92\demo\schema\human_resources -------------------------------------------------------------------------------------------------------------------------------------------Using DBMS_SQL ----------------------------create or replace procedure delete_all_rows (p_tab_name in varchar2,p_rows_del out number) is cursor_name integer; begin cursor_name := dbms_sql.open_cursor; dbms_sql.parse(cursor_name,'delete from 'p_tab_name,dbms_sql.native); p_rows_del := dbms_sql.execute(cursor_name); dbms_sql.close_cursor(cursor_name); end; / using the preceding procedure: ---------------------------------------variable deleted number execute delete_all-rows('emp',:deleted) print deleted deleted 14 ----------------------------------------------------------------------------------Dynamic sql using execute immediate ----------------------------------------------------create procedure del_rows (p_table_name in varchar2, p_rows_del out number) is begin execute immediate 'delete from '||p_table_name; p_rows_del :=sql%rowcount; end; / variable deleted number execute del_rows('emp',:deleted); print deleted deleted 14 --------------------------------------------------------------how to add jobs ----------------------

variable x number; begin dbms_job.submit(job >= :x, what >='delete from mx where empno=(select max(empno) from mx);', next_date >= trunc(sysdate + 1), interval >= 'trunc(sysdate+1)' ); commit; end; / ----------------variable x number; begin dbms_job.submit( job >= :x, -- this is to hold the job number in the job queue what >='over_pack.add_dept(''education'',80);', next_date >= trunc(sysdate + 1), interval >= 'trunc(sysdate+1)' -- to work every midnight ); end; / print x x 1 ----------------------------------------the following code changes job number 1 to execute on the following day at 6:00 a.m. and every four hours after that. begin dbms_job.change(1,null /*what*/,trunc(sysdate+1)+6/24,'sysdate+4/24'); end; / note : if the parameter what,next_date,or interval is null then the last values assigned to those parameters are used. ------------------------------------------------------------------------------------execute dbms_job.run(1) ; -- to run the job number 1 in the queue immediatly execute dbms_job.remove(1); -- to remove a job from the queue execute dbms_job.break(1,true); -- to stop temprarly this job to let working ag ain set the second parameter to false --------------------------------------------------------------------------------------------viewing information on submitted jobs ----------------------------------------------------select job,log_user,next_date,next_sec,brocken,what from dba_jobs; job log_user next_date next_sec broken what 1 plsql 28-sep-2003 06:00:00 N over_pack.add_dept('educ ation',80); * use the dba_jobs_running dictionary view to display jobs that are currently ru nning. --------------------------------------------------------------------------------------------procedure and functions

--------------------------SELECT ALL USER_SOURCE.NAME, USER_SOURCE.TYPE, USER_SOURCE.LINE, USER_SOURCE.TEX T FROM USER_SOURCE WHERE USER_SOURCE.NAME = :P_Name ----------------------------------dependencies ----------------SELECT ALL USER_DEPENDENCIES.NAME, USER_DEPENDENCIES.TYPE, USER_DEPENDENCIES.REFERENCED_OWNER, USER_DEPENDENCIES.REFERENCED_NAME, USER_DEPENDENCIES.REFERENCED_TYPE, USER_DEPENDENCIES.REFERENCED_LINK_NAME, USER_DEPENDENCIES.SCHEMAID, USER_DEPENDENCIES.DEPENDENCY_TYPE FROM USER_DEPENDENCIES Where Name = :P_Name ORDER BY REFERENCED_TYPE, USER_DEPENDENCIES.NAME ASC -------------------------------------Triggers -------------------------SELECT ALL USER_TRIGGERS.TRIGGER_NAME, USER_TRIGGERS.TRIGGER_BODY , USER_TRIGGER S.DESCRIPTION, Decode(WHEN_CLAUSE,null,'','When '|| USER_TRIGGERS.WHEN_CLAUSE )WHEN_CLAUSE FROM USER_TRIGGERS Where TRIGGER_NAME = :P_Name ---------------------------------views -------------SELECT TEXT FROM USER_VIEWS WHERE VIEW_NAME = :P_NAME ------------------------------------Excel: -----------Sub Update_Data() ' Create and initialize the necessary objects Dim OraSession As Object Dim OraDatabase As Object Dim EmpDynaset As Object Dim ColNames As Object Set OraSession = CreateObject("OracleInProcServer.XOraSession") Set OraDatabase = OraSession.OpenDatabase("2:", "scott/tiger", 0&) Set EmpDynaset = OraDatabase.DbCreateDynaset("select * from emp", 0&) Set ColNames = EmpDynaset.Fields i = 2

' the BeginTrans and CommitTrans are optional OraSession.BeginTrans While Worksheets("DataSheet").Cells(i, 1).Value <> "" EmpDynaset.dbedit For j = 1 To ColNames.Count ColNames(j - 1).Value = Worksheets("DataSheet").Cells(i, j).Value Next j EmpDynaset.dbupdate EmpDynaset.dbmovenext i = i + 1 Wend OraSession.CommitTrans End Sub

----------------------------------------------------excel2 -------Sub Get_Data() ' Create and initialize the necessary objects Dim OraSession As Object Dim OraDatabase As Object Dim EmpDynaset As Object Dim ColNames As Object Set OraSession = CreateObject("OracleInProcServer.XOraSession") Set OraDatabase = OraSession.OpenDatabase("2:", "scott/tiger", 0&) Set EmpDynaset = OraDatabase.DbCreateDynaset("select * from emp", 0&) ' Using field array, ie. ColNames("ename").value, is significantly faster than using ' field lookup, ie. EmpDynaset.fields("ename").value Set ColNames = EmpDynaset.Fields ' Place column headings on sheet For icols = 1 To ColNames.Count Worksheets("DataSheet").Cells(1, icols).Value = ColNames(icols - 1).Name Next ' Place data on sheet using CopyToClipboard EmpDynaset.CopyToClipboard -1 Sheets("DataSheet").Select Range("A2").Select ActiveSheet.Paste End Sub -----------------------------------------excel array -------------Sub Get_Array()

Const Const Const Const Dim Dim Dim Dim Dim Dim Dim Dim Set Set

ORAPARM_INPUT = 1 ORAPARM_OUTPUT = 2 ORATYPE_VARCHAR2 = 1 ORATYPE_NUMBER = 2

OraSession As Object OraDatabase As Object OraDynaset As Object OraPLSQLStmt As Object OraPArray1 As Object OraPArray2 As Object PLSQLStmt1 As String PLSQLStmt2 As String OraSession = CreateObject("OracleInProcServer.XOraSession") OraDatabase = OraSession.OpenDatabase("2:", "scott/tiger", 0&)

' PL/SQL procedure PLSQLStmt1 = "CREATE OR REPLACE PACKAGE Employee AS " & _ "TYPE numarray IS TABLE OF NUMBER INDEX by BINARY_INTEGER; " & _ "TYPE vchar2array IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER; " & _ "PROCEDURE GetEmpNamesInArray (ArraySize IN INTEGER, inEmpnos IN numarray, outE mpNames OUT vchar2array); " & _ "PROCEDURE GetEmpName (inEmpno IN NUMBER, outEmpName OUT VARCHAR2); " & _ "FUNCTION GetEmpSal (inEmpno IN NUMBER) RETURN NUMBER; " & _ "END Employee;" PLSQLStmt2 = "CREATE OR REPLACE PACKAGE BODY Employee AS " & _ "PROCEDURE GetEmpNamesInArray (ArraySize IN INTEGER, inEmpnos IN NUMARRAY, out EmpNames OUT VCHAR2ARRAY) IS " & _ "BEGIN FOR i in 1..ArraySize loop SELECT ename INTO outEmpNames(i) FROM emp WH ERE empno = inEmpNos(i); " & _ "END LOOP; END; " & _ "PROCEDURE GetEmpName (inEmpno IN NUMBER, outEmpName OUT VARCHAR2) IS BEGIN SE LECT ename INTO outEmpName " & _ "FROM EMP WHERE EMPNO = inEmpNo; END; FUNCTION GetEmpSal (inEmpno IN NUMBER) R ETURN NUMBER IS " & _ "outEmpsal NUMBER(7,2); BEGIN SELECT sal INTO outEmpsal FROM emp WHERE empno = inEmpno; RETURN (outEmpsal); " & _ "END; END Employee;" ' add the above procedure to the Server OraDatabase.dbexecutesql (PLSQLStmt1) OraDatabase.dbexecutesql (PLSQLStmt2) ' add the 2 parameters to the Server OraDatabase.Parameters.addtable "empno", ORAPARM_INPUT, ORATYPE_NUMBER, 3, 22 OraDatabase.Parameters.addtable "empname", ORAPARM_OUTPUT, ORATYPE_VARCHAR2, 3, 10 Set OraPArray1 = OraDatabase.Parameters("empno") Set OraPArray2 = OraDatabase.Parameters("empname") ' assign empno's to the array OraPArray1.put_Value 7698, 0 OraPArray1.put_Value 7782, 1 OraPArray1.put_Value 7654, 2 ' execute the procedure and retrieve the empname array Set OraPLSQLStmt = OraDatabase.createsql("Begin Employee.GetEmpNamesInArray(3, : EMPNO, :EmpNAME); End;", &O0)

' display to screen For j = 0 To 2 parm_value = OraPArray2.Get_Value(j) msgbox parm_value Next j End Sub ------------------------------------------------------excel cursor return -------------------Sub Cursor_Return() Const ORATYPE_NUMBER = 2 Const ORAPARM_INPUT = 1 Dim OraSession As Object Dim OraDatabase As Object Dim OraDynaset As Object 'Get deptno parameter from cell J2. If blank then use 10 as default If Val(Worksheets("DataSheet").Cells(2, 10).Value) = 0 Then dept = 10 Else dept = Worksheets("DataSheet").Cells(2, 10).Value End If 'Create the OraSession and connection objects Set OraSession = CreateObject("OracleInProcServer.XOraSession") Set OraDatabase = OraSession.OpenDatabase("ExampleDb", "scott/tiger", 0&) 'Create the Deptno parameter OraDatabase.Parameters.Add "DEPTNO", dept, ORAPARM_INPUT OraDatabase.Parameters("DEPTNO").ServerType = ORATYPE_NUMBER 'Create OraDynaset based on "EmpCursor" created in stored procedure. Set OraDynaset = OraDatabase.CreatePLSQLDynaset("Begin Employee.GetEmpData (:DE PTNO,:EmpCursor); end;", "EmpCursor", 0&) 'Copy cursor to clipboard OraDynaset.CopyToClipboard -1 'Erase range and paste clipboard Sheets("DataSheet").Select Range("A2:H50").Select Selection.Clear Range("A2").Select ActiveSheet.Paste 'NOTE: To vary deptno values you do not need to run this entire procedure. Si mply assign ' a new value to the parameter: OraDatabase.Parameters("DEPTNO").Value = 20 an d issue ' a OraDynaset.Refresh command End Sub

-----------------------------------------------block scope (when button pressed) ---------------------------------DECLARE v_block_item VARCHAR2(61) := :system.trigger_item; v_pos NUMBER := instr(v_block_item, '.'); v_item VARCHAR2(30) := substr(v_block_item, v_pos+1); BEGIN message(v_item); set_application_property(CURSOR_STYLE, v_item); END; ---------------------------------------------------------------find -------------------DECLARE v_where VARCHAR2(2000) := NULL; v_ename VARCHAR2(30) := :control.ename; v_deptno NUMBER := :control.deptno; BEGIN -IF v_deptno IS NOT NULL THEN v_where := 'DEPTNO = ' || v_deptno; END IF; -IF v_ename IS NOT NULL THEN IF v_where IS NOT NULL THEN v_where := v_where || ' AND '; END IF; -IF SUBSTR(v_ename, 1, -1) = '%' THEN v_where := v_where || 'ENAME LIKE ' || UPPER(v_ename) ; ELSE v_where := v_where || 'ENAME LIKE ''' || UPPER(v_ename) || '%''' ; END IF; END IF; -- Add conditions for other items set_block_property('EMP', DEFAULT_WHERE, v_where); -- Query go_block('EMP'); execute_query; EXCEPTION WHEN OTHERS THEN message(SQLERRM); END;

------------------basic a block on a procedure -------------------------------

PACKAGE emp_proc AS TYPE emp_t IS RECORD( NAME emp.ename%TYPE, ID emp.empno%TYPE); -- For SELECT TYPE rec_t IS TABLE OF emp_t INDEX BY BINARY_INTEGER ; PROCEDURE emp_rec( p_table IN OUT rec_t); END; ------------------------------PACKAGE BODY emp_proc AS PROCEDURE emp_rec( p_table IN OUT rec_t) IS v_ct NUMBER := 1; BEGIN FOR emp_r IN (SELECT * FROM EMP) LOOP p_table(v_ct).name := emp_r.ename; p_table(v_ct).id := emp_r.empno; v_ct := v_ct + 1; END LOOP; END; END; --------------------------------------query-procedure trigger on the datablock scope ---------------------------------------------------- Automatically generated trigger for procedure data source. -- Do not edit. -- If this trigger fails to compile, verify the block procedure data source is c orrect. DECLARE bk_data EMP_PROC.REC_T; BEGIN emp_proc.emp_rec(bk_data); PLSQL_TABLE.POPULATE_BLOCK(bk_data, 'BLOCK2'); END; -------------------------------------------------------

dynamic order by --------------------------------create a listitem with all the names of the table names then type the following trigger: when-list-changed ----------------------set_block_property('EMP', ORDER_BY, :control.sort_by); go_block('EMP'); execute_query; --------------------------------------------------------------------------------------------TREE QUERY (in the data_query property of the tree item -----------------------SELECT decode(level, 1, 1, -1), level, INITCAP(ename), 'tbrun', empno FROM emp START WITH mgr IS NULL CONNECT BY PRIOR empno = mgr --WHEN-NEW-FORM-INSTANCE ---------------------ftree.populate_tree('CONTROL.EMP_TREE'); --WHEN-TREE-NODE-SELECTED -------------------------go_block('EMP'); set_block_property('EMP', DEFAULT_WHERE, 'EMPNO='|| ftree.get_tree_node_property('CONTROL.EMP_TREE', :SYSTEM.TRIGGER_NODE, FTREE.NODE_VALUE)); execute_query; ---------------------------------------------------------------------------------------DYNAMIC TREE --------------------PRE-FORM --------ftree.populate_tree('CONTROL.EMP_TREE'); ftree.set_tree_property('CONTROL.EMP_TREE', FTREE.QUERY_TEXT, 'SELECT decode(level, 1, 1, -1), level, INITCAP(ename), ''tbrun'',' || 'empno FROM emp ' || 'START WITH mgr IS NULL CONNECT BY PRIOR empno = mgr'); -----------------WHEN-TREE-NODE-SELECTED (BLOCK SCOPE -----------------------------------go_block('EMP');

set_block_property('EMP', DEFAULT_WHERE, 'EMPNO='|| ftree.get_tree_node_property('CONTROL.EMP_TREE', :SYSTEM.TRIGGER_NODE, FTREE.NODE_VALUE)); execute_query; ----------------------------------------------------------------------------------------run report object --------------------DECLARE v_repid REPORT_OBJECT := find_report_object('dept_rep'); v_rep VARCHAR2(100); BEGIN IF :run_rep.destype = 'FILE' THEN set_report_object_property(v_repid, REPORT_DESFORMAT, 'PDF'); set_report_object_property(v_repid, REPORT_DESNAME, 'c:\dept_rep.pdf'); set_report_object_property(v_repid, REPORT_DESTYPE, FILE); -ELSE set_report_object_property(v_repid, REPORT_DESFORMAT, TO_CHAR(NULL)); set_report_object_property(v_repid, REPORT_DESNAME, TO_CHAR(NULL)); set_report_object_property(v_repid, REPORT_DESTYPE, PREVIEW); END IF; -v_rep := run_report_object(v_repid); -IF :run_rep.destype = 'FILE' THEN message('File has been written to C:\DEPT_REP.PDF'); message(' '); END IF; END; -- Other syntax that can be used if the Reports Server is running -v_rep_status VARCHAR2(20); -- v_rep_status := report_object_status(v_rep); -- IF v_rep_status = 'FINISHED' THEN -message('Report Completed'); -copy_report_object_output(v_rep, 'c:\dept_rep.pdf'); -- ELSE -message('Error when running report. '||rep_status); -- END IF;

---------------------------------------------------------------------------------what is the mouse button pressed and with what key (shift - ctrl) ---------------------------:control.shift_state := :system.mouse_button_shift_state; :control.mouse_button := :system.mouse_button_pressed; --------------------------------------------------------------------------------

-----to run a report from forms 1 - in the object navigator of the forms builder create a new report and specify an existing report path and name then change the properties of that report object execution mode = runtime - communication mode = synchronous report distination type = preview 2 - create a button with the following code : declare v_rep varchar2(100); v_rp_id report_object; begin v_rp_id := find_report_object('dept');--the name of the report object no t the report v_rep := run_report_object(v_rp_id); end; ---------------------------------------------------------------------------------------------to run a report against a remote server: repid := find_report_object('barcode'); v_rep := run_report_object(repid); rep_status := report_object_status(v_rep); if rep_status = 'FINISHED' then copy_report_object_output(v_rep,'c:\local.pdf'); host('netscape c:\local.pdf'); end if; ---------------------------------------------------------------------------------------------to run a report on the web:

web.show_document('url','target'); ex: web.show_docment('http://www.summit.com/repts/emps.pdf','_self'); ---------------------------------------------------------------------------------------------set_alert_property('myalert',mesage,'Are u sure u want to delete?'); if show_alert('myalert') = alert_button1 then delete_record; end if; ----------------------------------------------------------------------------------------------if the form has many windows but we want it to be closed only from the win_order window :when-window-closed if :system.event_window='WIN_ORDER' THEN DO_KEY('EXIT_FORM'); ELSE GO_BLOCK('S_ORDER'); END IF;

----------------------------------------------------------------------------------------------TO KNOW ALL THE NLS_PARAMETERS -----------------------------------SELECT * FROM NLS_SESSION_PARAMETERS ----------------------------------------------------------------------------------------------declare v_empno employees.employee_id%type := 100; begin merge into copy_emp c using employees e on (e.employee-id = v_emono) when matched then update set c.first_name = e.first_name, c.last_name = e.last_name, c.email = e.email, .... when not matched then insert values(e.employee_id,e.first_name,e.last_name...); end; ---------------------------------------------------------------------------begin delete from emp; dbms_output.put_line('count of rows deleted ='||sql%rowcount); end; / ---------------------------------------------------------------------------sql%rowcount sql%found sql%notfound sql%isopen ---------------------------------------------------------------------------CASE (LIKE IF) ---------------SET SERVEROUTPUT ON DECLARE V_GRADE char(1) := upper('&p_grade'); v_appraisal varchar2(20); begin v_appraisal := case v_grade when 'A' then 'Excellent' when 'B' then 'very Good' when 'C' then 'Good' Else 'No such grade' end; dbms_output.put_line('Grade: '||v_grade||' Appraisal '||v_appraisal'); end; / --------------------------------------------------------

reverse loop -------------begin for i in reverse 1..100 loop dbms_output.put_line(i); end loop; end; / -------------------------------------------------------idea --------set serveroutput on begin for i in (select * from emp) loop dbms_output.put_line(i.ename||' with salary of'||i.sal); end loop; end; / -------------------------------------------------------index by tables --------------EX 1: ---declare type dept_table_type is table of dept%rowtype index by binary_integer; dept_table dept_table_type; x number; c number; begin x:=10; select count(*) into c from dept; for i in 1..c loop select * into dept_table(i) from dept where deptno = x; x := x+10; end loop; x := 1; for m in dept_table.first..dept_table.last loop dbms_output.put_line(dept_table(m).dname||' '||dept_table(m).loc); end loop; exception when no_data_found then dbms_output.put_line(dept_table.count); end; / --------------------------------Ex 2: ----declare type numlist is table of number; mgrs numlist := numlist(100,101,102,103,..); -- managers numbers begin forall i in mgrs.first..mgrs.last loop delete from employees where manager_id = mgrs(i);

end loop; end;

------------------------------------------------------------to know the monitor settings (800x600 ...) -----------------------------------------message('display height = '||get_application_property(display_height)/.75||' and width = '|| get_application_property(display_width)/.75); -----------------------------------------------------------------------------------current of in a cursor ----------------------declare cursor sal_cursor is select e.deptno,empno,ename,sal from emp e,dept d where d.deptno=e.deptno and d.deptno=30 for update of sal nowait; begin for emp_record in sal_cursor loop if emp_record.sal<5000 then update emp set sal= emp_record.sal * 1.1 where currenct of sal_cursor; end if; end loop; end; / note: you have to include the for update clause in the curosr in order to be abl e to use where current of clause. ------------------------------------------------------Exception handling ---------------------trap for oracle server error number -2292,an integrity constraint biolation. ------------------------------------------define p_deptno = 10 declare e_emps_remaining exception; pragma exception_init (e_emps_remaining,-2292); begin delete from dept where deptno = &p_deptno; commit; exception when e_emps_remaining then dbms_output.put_line('cannot remove dept '|| to_char(&p_deptno)||'. Employees exist. '); end;

-------------------------------------------------------------------SQLCODE SQLERRM ----------------------------------------------user-defined exceptions ----------------------define p_dnm = 'Information Technology' define p_dept_no = 300 declare e-invalid_dept exception; begin update dept set dname = '&p_dnm' where deptno = &p_dept_no; if SQL%NOTFOUND THEN RAISE e_invalid_dept; end if; commit; exception when e_invalid_dept then dbms_output.put_line('No such deptno.'); end; --------------------------------------------------raise_application_error:-------------------------use within the stored program units either in: - the executable section or - the exception section Executable section: ------------------begin ..... delete from emp where mgr = 9000; if sql%notfound then raise_application_error(-20202, 'This is not a valid manager'); end if; ....... ----------------------exception section ----------------..... exception when no_data_found then raise_application_error(-20201, 'Manager is not a valid employee.'); end; -------------------------------------------------------------------

create or replace procedure format_phone (p_phone_no in out varchar2) is begin p_phone_no :='('||substr(p_phone_no,1,3|| ')'||substr(p_phone_no,4,3)|| '-'||'('||substr(p_phone_no,7); end format_phone; / ----------------------------------------------------------------------------HOW TO PASS PARAMETERS TO PROCEDURES WHICH HAS DEFAULT VALUES: --------------------------------------------------procedure add_dept (p_nm in varchar2 default 'unknown', p_loc in number default 'cairo') is begin insert into dept values(dept_seq.next_val,p_nm,p_loc); end; / examles of how to pass parameters to this procedure: ----------------------------------------------------------------------begin add_dept; add_dept('training','Giza'); add_dept(p_loc => 'Giza',p_nm =>'Education'); add_dept(p_loc =>'Alex'); end; / --------------------------------------------------------------------------Extract the source code from the database: --------------------------------------------------------VARIABLE SRC VARCHAR2(2000); BEGIN FOR I IN (SELECT TEXT FROM USER_SOURCE WHERE NAME ='GET_HOLIDAYS' ORDER BY LINE ) LOOP IF :SRC IS NULL THEN :SRC := I.TEXT; ELSE :SRC :=:SRC||CHR(13)||I.TEXT; END IF; END LOOP; END; / ----------------------------------------------------------------------------------------------------------declaring a bodiless package ---------------------------------------create or replace package global_consts is mile_2_kilo constant number := 1.6093; kilo_2_mile constant number := 0.6214; yard_2_meter constant number := 0.9144;

meter_2_yard constant number := 1.0936; mile_2_kilo constant number := 1.6093; end global_consts; / to try the package: -------------------------execute dbs_output.put_line('20 miles = '||20* global.consts.mile_2_kilo||' km'); -----------------------------------------------------------------------------------PL/SQL TABLES AND RECORDS IN PACKAGES ------------------------------------------------------------------------create or replace package emp_package is type emp_table_type is table of employees%rowtype index by binary_integer; procedure read_emp_table (p_emp_table out emp_table_type); end emp_package; / create or replace package body emp_package is procedure read_emp_table (p_emp_table out emp_table_type) is i binary_integer := 0; begin for emp_record in (select * from employees) loop p_emp_table(i) := emp_record; i := i + 1; end loop; end read_emp_table; end emp_package; / --------------------------------------------------------------------------------------------how to use the preceding package: _------------------------------------------declare v_emp_table emp_package.emp_table_type; begin emp_package.read_emp_table (v_emp_table); dbms_output.put_line('an example'||v_emp_table(4).last_name); end; / ------------------------------------------------------------------------------------------------DYNAMIC SQL -----------------------forms_ddl('create or replace function get_data return varchar2 is'|| ' rslt varchar2(100); begin select '||:tt||' into rslt from dept where deptno=10 ; RETURN RSLT; end;'); :tt := get_data; -------------------------------------------------------------------------------------------------------------------------dynamic insert statement --------------------------------------

select 'insert into dept values(' ||deptno||','''||dname||''','''||loc||''');' from dept; 'INSERTINTODEPTVALUES('||DEPTNO||','||DNAME||','||LOC||');' ----------------------------------------------------------------------------------------insert into dept values(10,ACCOUNTING,NEW YORK); insert into dept values(20,RESEARCH,DALLAS); insert into dept values(30,SALES,CHICAGO); insert into dept values(40,OPERATIONS,BOSTON); -----------------------------------------------------scripts for hr ---------------------C:\oracle\ora92\demo\schema\human_resources -------------------------------------------------------------------------------------------------------------------------------------------tab pages --------------when-tab-page-changed (form level) ----------------------------------begin if :system.tab_new_page = 'ADDRESS' then go_item('s_customer.name'); else if :system.tab_new_page = 'BILLING' then go_item('s_customer.credit_rating'); else go_item('s_customer.comments'); end if; end if; end; ------------------------------------------------------------------------------when-new-record-instance (block level) -------------------------------------Declare tb_pg_id TAB_PAGE; Begin tb_pg_id := FIND_TAB_PAGE('COMMENTS'); if :s_customer.comments is null then SET_TAB_PAGE_PROPERTY(tb_pg_id, enabled, propert y_false); else SET_TAB_PAGE_PROPERTY(tb_pg_id, enabled, property_true); End If; :global.custid := :s_customer.id; End;

---------------------------------------------------------------------------------when-checkbox-changed ======================= IF NVL(:CONTROL.case_sensitive, 'Y') = 'Y' THEN SET_ITEM_PROPERTY('S_CUSTOMER.name', CASE_INSENSITIVE_QUERY, PROPERTY_FALSE); ELSE SET_ITEM_PROPERTY('S_CUSTOMER.name',CASE_INSENSITIVE_QUERY, PROPERTY_TRUE); END IF; ================================================================================ ===== dynamic sorting ============== 1 - create on top of every column item a button as a label of the column but wit h the same name of the column ending by ( _btn) 2 - when-button-pressed (block level of the buttons) type the following code: set_block_property('emp',order_by,substr(:system.cursor_item,1,instr(:syst em.cursor_item,'_',1)-1) ); go_block('emp'); execute_query; ================================================================================ ===== hide and show tab pages ===================== DECLARE tb_pg_id TAB_PAGE; BEGIN tb_pg_id := FIND_TAB_PAGE('P2'); IF GET_TAB_PAGE_PROPERTY(tb_pg_id, visible) = 'FALSE' THEN SET_TAB_PAGE_PROPERTY(tb_pg_id, visible, property_true); set_item_property('btn',label,'Hide'); else SET_TAB_PAGE_PROPERTY(tb_pg_id, visible, property_false); set_item_property('btn',label,'Show'); END IF; END; ================================================================================ ==== synchronize ============= go_block('emp'); execute_query; first_record; loop :tt := 'currently processing Employee -who works as "'||:job||'"'; for i in 1..20000 loop synchronize; end loop; exit when :System.Last_Record = 'TRUE'; next_record;

end loop; first_record; ================================================================================ ==== size window in motion ================= IF GET_ITEM_PROPERTY('BTN',LABEL) = 'VIEW' THEN for i in 1..125 loop SET_ITEM_PROPERTY('BTN',LABEL,'HIDE'); for i in 1 .. 200 loop null; synchronize; end loop; SET_WINDOW_PROPERTY('WINDOW1',HEIGHT,get_window_property('WINDOW1',HEIGHT)+1) ; end loop; ELSE SET_ITEM_PROPERTY('BTN',LABEL,'VIEW'); SET_WINDOW_PROPERTY('WINDOW1',HEIGHT,175); END IF; ================================================================================ ===== extracting the date of a tabular datablock to a text file: =========================================== 1 - create a procedure in the program unit like that : ======================================= PROCEDURE CREATE_FLAT_FILE(Save_To VARCHAR2) IS in_file TEXT_IO.FILE_TYPE; text_line VARCHAR2(400); AppID PLS_INTEGER; BEGIN in_file := TEXT_IO.FOPEN(Save_To, 'W'); GO_BLOCK('dept'); FIRST_RECORD; LOOP text_line := :deptno||';'||:dname||';'||:loc; TEXT_IO.PUT_LINE(in_file, text_line); exit when :SYSTEM.LAST_RECORD = 'TRUE'; NEXT_RECORD; END LOOP; TEXT_IO.FCLOSE(in_file); AppID := DDE.App_Begin('"C:\Program Files\Microsoft Office\Office\EXCEL. EXE" '||Save_To, DDE.APP_MODE_Maximized); EXCEPTION WHEN NO_DATA_FOUND THEN TEXT_IO.FCLOSE(in_file); END; ---------------------------------------2 - create a button with a when button pressed trigger :

======================================== declare fle varchar2(200); begin fle:= get_file_name('D:\'/*default directory*/,'hm.csv'/*default file name*/,fi le_filter =>'Excel Files (*.csv)/*.csv',dialog_type => SAVE_FILE); CREATE_FLAT_FILE(fle); end; ================================================================================ ==== moving and copying system files : ---------------------------------------------1- we need to attach the d2kwutil.pll to the form 2 - a button with this trigger: ('c:\test.doc'/*the file Win_Api_Utility.Move_Filewhich is needed to be moved*/,'d:\hamdy.doc' /*this is the new file name and location*/); ================================================================================ ===== to cancel a report if the ouput is null -------------------------------------------------befor report trigger: ================== Function BEF_REP_TRG return boolean is count_inv number; begin select count(*) into count_inv from EMP where DEPTNO= :P_DEPTNO ; if count_inv = 0 then srw.message (0, 'No DATA found for printing'); --return false; /* or use SRW.PRORAM_ABORT; RAise srw.program_abort; end if; return true; End; ================================================================================ ===== to dynamically show only the number of records specified in a group filter: --------------in the data model: -----------------select the group then F11 and put the following code: function G_CUSTOMER_IDGroupFilter return boolean is begin :P_COUNT_CUST/* a parameter */ := nvl(:P_COUNT_CUST,0) + 1; IF :P_COUNT_CUST <= :P_CUTOFF /*this the parameter that's showed for the user so he can enter the number of records he needs to desplay*/ THEN return (TRUE); ELSE return(FALSE); END IF; end; ----------------------------------------------------------------------------------------------to run a drill - down report : ---------------------------------

*/

in the master report create a button and set its type to pl/sql then put the fol lowing code : -------------------------------------------------------------procedure U_1ButtonAction is begin srw.run_report ('report=s18q2c.rep p_customer=' ||to_char(:customer_id)|| ' paramform=no'); -- The paramform argument is optional, default=no, but it -- shows how to enter multiple arguments in this command end; -- srw.run_report -- ('report=p2q8_det.rep p_custid=' ||to_char(:id)|| ' paramform=no'); ---------------------------------------------------------------------------------------------ddl and dml in reports before_report ------------function BeforeReport return boolean is begin BEGIN srw.do_sql('CREATE TABLE RUNREPORT(DATE_RUN DATE,USER_RUN VARCHAR2(20), COMMENTS VARCHAR2(80))'); exception when srw.do_sql_failure then null; end; begin SRW.MESSAGE(10000,'INSERTING'); srw.do_sql('INSERT INTO RUNREPORT VALUES(SYSDATE,USER,''Starting Report'')'); return(TRUE); end; end; -------------------------------------------------------------------------------------To know the size of tables in a user: -------------------------------select round(sum(bytes)/1000000)||' MB' from user_segments where segment_type = 'TABLE' ; -----------------------------------------------------------------------------------displaying the names of employees who gain the max(sal) in every department: ------------------------------------------------------------select ename,sal,deptno from emp where (deptno,sal) in ( select deptno,max(sal) from emp group by deptno); -----------------------------------------------------------------------------------to know the version of oracle products: ---------------------------------select * from product_component_version; --------------------------------------------------------------------------------

----display the table structures: ---------------------select sys.user_tab_columns.table_name, sys.user_tab_columns.column_name, sys.user_tab_columns.data_type, sys.user_tab_columns.data_length, sys.user_tab_columns.data_precision, sys.user_tab_columns.data_scale/*, sys.user_tab_columns.table_type*/ from sys.user_tab_columns,sys.user_catalog where(sys.user_tab_columns.table_name=sys.user_catalog.table_name) and sys.user_tab_columns.table_name like upper('%&tab%') order by sys.user_tab_columns.table_name / ---------------------------------------------------------------------------------To import specific tables from a dmp file: ----------------------------------imp userid=xyz/xyz file=c:\scott.dmp fromuser=scott tables=('emp','dept') To import all tables from a dmp file: ----------------------------------imp userid=xyz/xyz file=c:\scott.dmp fromuser=scott tables=* ---------------------------------------------------------------------------------Dynamic List-Item ---------------------1 - create a group named rg with the following query: select dname,to_char(deptno) from dept 2 - create a list item called lst 3 - create a form level trigger (when-new-form-instance) with the following code : declare pg number; begin pg := populate_group('rg'); /*returns 0 if executed succefully */ populate_list('lst','rg'); end; ----------------------------------------------------------------------------------------------openning a report from within a form or a menu: ------------------------------------------------declare pl_id begin ParamList;

pl_id := Get_Parameter_List('emps'); IF NOT Id_Null(pl_id) THEN Destroy_Parameter_List( pl_id );

end if; pl_ID := Create_Parameter_List('emps'); Add_Parameter(pl_id,'Paramform',Text_PARAMETER,'NO'); Add_Parameter(pl_id,'MAXIMIZE',Text_PARAMETER,'Yes'); Run_Product(REPORTS, 'port_cash_available', SYNCHRONOUS, RunTime,FILESYSTEM, pl _id, NULL); end; --------------------------------------------------------------------------------------------dynamically select the first n rows from a query: ---------------------------------------------------1 - create a parameter called mx 2 - before report trigger function BeforeReport return boolean is begin srw.set_maxrow('Q_1'/*query name from the data model*/,:mx); return (TRUE); end; --------------------------------------------------------------------------------------------To output the report to many extensions -------------------------------1-create 3 buttons with the label of (excel - word - pdf - print) 2-create 2 procedures with the following code : PROCEDURE Open_application(app varchar2) IS File_Name Varchar2(150); AppID PLS_INTEGER; Begin if app = 'xls' then File_Name := 'D:\Program Files\Microsoft Office\Office\Excel C:\temp\excel.xl s'; Elsif app = 'rtf' then File_Name := 'D:\Program Files\Microsoft Office\Office\winword C:\temp\word .rtf'; Elsif app = 'pdf' then File_Name := 'D:\Program Files\Adobe\Acrobat 5.0\Reader\acrord32 C:\temp\pdf. pdf'; End If; if not file_name is null then AppID := DDE.App_Begin(File_Name,DDE.App_Mode_Maximized); end if; Exception when others then Message(SQLCode||'-'||SQLErrm); End;

--------------------------------------------------------------------------------PROCEDURE Run_Report(P_destination varchar2) IS PL_ID Paramlist; BEGIN pl_id := Get_Parameter_List('Report'); IF NOT Id_Null(pl_id) THEN Destroy_Parameter_List( pl_id ); END IF; pl_ID := Create_Parameter_List('Report'); Add_Parameter(pl_id,'Paramform',Text_PARAMETER,'NO'); if P_destination ='xls' then Add_Parameter(pl_id,'DESFORMAT',Text_PARAMETER,'csv'); Add_Parameter(pl_id,'DESTYPE',Text_PARAMETER,'FILE'); Add_Parameter(pl_id,'MODE',Text_PARAMETER,'BITMAP'); Add_Parameter(pl_id,'DESNAME',Text_PARAMETER,'C:\TEMP\EXCEL.csv'); ELSif P_destination ='pdf' then Add_Parameter(pl_id,'DESFORMAT',Text_PARAMETER,'pdf'); Add_Parameter(pl_id,'DESTYPE',Text_PARAMETER,'FILE'); Add_Parameter(pl_id,'MODE',Text_PARAMETER,'BITMAP'); Add_Parameter(pl_id,'DESNAME',Text_PARAMETER,'C:\TEMP\pdf.pdf'); ELSif P_destination ='rtf' then Add_Parameter(pl_id,'DESFORMAT',Text_PARAMETER,'RTF'); Add_Parameter(pl_id,'DESTYPE',Text_PARAMETER,'FILE'); Add_Parameter(pl_id,'MODE',Text_PARAMETER,'BITMAP'); Add_Parameter(pl_id,'DESNAME',Text_PARAMETER,'C:\TEMP\word.rtf'); end if; Run_Product(REPORTS, 'HR_Emp_Group_level', SYNCHRONOUS, RunTime,FILESYSTEM, pl_id, NULL); DESTROY_PARAMETER_LIST(pl_id); END; 3- create a when-button-pressed trigger for each of the 3 buttons with the follo wing code : RUN_Report('xls/*or rtf or pdf*/'); if form_success then Open_application('xls/*or rtf or pdf*/'); end if; -------------------------------------------------------------------------------------------If you know that the value in the WHERE clause of your query appears in a very s mall percentage of the rows, you can use the INDEX hint to force the optimizer t o choose an index scan. In this statement, the INDEX hint explicitly chooses an index scan on the SEX_INDEX, the index on the SEX column using index in a query ---------------------------SELECT /*+ INDEX(patients sex_index) Use SEX_INDEX, since there are few male patients */ name, height, weight FROM patients WHERE sex = 'M';

-----------------------------using full table scan ----------------For example, Oracle performs a full table scan on the ACCOUNTS table to execute this statement, even if there is an index on the ACCNO column that is made avail able by the condition in the WHERE clause: SELECT /*+ FULL(a) Don't use the index on ACCNO */ accno, bal FROM accounts a WHERE accno = 7086854; Note: Because the ACCOUNTS table has an alias, A, the hint must refer to the tab le by its alias, rather than by its name. Also, do not specify schema names in t he hint, even if they are specified in the FROM clause -------------------------------------------------------------------------------------------declare v_repid REPORT_OBJECT; vc_rep VARCHAR2(20); vc_rep_status VARCHAR2(20); vc_URL VARCHAR2(100); BEGIN v_repid := FIND_REPORT_OBJECT('RP2RRO'); SET_REPORT_OBJECT_PROPERTY(v_repid,REPORT_FILENAME,'order_invoice'); SET_REPORT_OBJECT_PROPERTY(v_repid, REPORT_OTHER, 'porder_id=' || :orders.ord er_id); vc_rep := RUN_REPORT_OBJECT(v_repid); vc_rep_status := REPORT_OBJECT_STATUS(vc_rep); WHILE vc_rep_status in ('RUNNING', 'OPENING_REPORT', 'ENQUEUED') LOOP vc_rep_status := report_object_status(vc_rep); END LOOP; if vc_rep_status = 'FINISHED' then

message('Report Completed'); vc_URL := '/reports/rwservlet/getjobid'||substr(vc_rep,8)||'?server=RepSRV'; Web.show_document(vc_URL,'_blank'); else message('Error when running report.'); end if;

END; -------------------------------------------------------------------------------------------declare mi_id MenuItem; Cursor menu_items is Select ITM_NM from ITEMS where itm_id in (select ITM_ID from USER_ITEMS where USR_ID=:global.u ser_id and OK = 'Y'); Begin For m_i in menu_items Loop mi_id := Find_Menu_Item(m_i.itm_id); If Not ID_Null(MI_ID) Then Set_Menu_Item_Property(mi_id,Enabled/*visible*/,PROPERTY_true); End If; End Loop; End; -------------------------------------------------------------------------------------------showing output in sql+.txt --------------------------in SQL*Plus add : -----------------SET SERVEROUTPUT ON SIZE 1000000 FORMAT WRAPPED SET ECHO ON -------------------------------------------------------------------------------------------TO KNOW IF THE NUMBER IS DOUBLE OR ODD SO WE CAN CONDITIONAL FORMAT THE LINES OF THE REPORT TO BE ON HILIGHTED AND THE NEXT IS NOT .. ---------------------------------------

1 - IN THE REPORT WE CREATE A SUMMARY COLUMN CALLED "CS_ROWNUM" TO SEQUENCE THE LINES (OR USE ROWNUM). 2 - CREATE A FORMULA COLUMN CALLED "CF_ODD_DOUBLE" WITH THE NEXT CODE : function CF_1Formula return Number is begin IF MOD(:CS_ROWNUM/2,1) = 0 THEN RETURN 0; -- IF IT'S DOUBLE NUMBER ELSE RETURN 1; -- IF IT'S ODD NUMBER END IF; end; 3 - USE THE CONDITIONAL FORMATING : CF_ODD_DOUBLE EQUALS 0 THEN BACKGROUND = GREY12 -------------------------------------------------------------------------------------------/*************************************************************************** ALTER SYSTEM COMMAND : ************************ Keywords and Parameters You can use the following options regardless of whether your instance has the da tabase dismounted or mounted, open or closed: RESTRICTED SESSION specifies whether logon to Oracle is restricted ENABLE allows only users with RESTRICTED SESSION system privilege to logon to Oracle. DISABLE reverses the effect of the ENABLE RESTRICTED SESSION option, allowing all users with CREATE SESSION system privilege to log on to Oracle. For more information, see "Restricting Logons". FLUSH SHARED_POOL clears all data from the shared pool in the system global area (SGA). For more information, see "Clearing the Shared Pool". You can use the following options when your instance has the database mounted, o pen or closed: CHECKPOINT performs a checkpoint. GLOBAL performs a checkpoint for all instances that have opened the database. LOCAL performs a checkpoint only for the thread of redo log file groups for your inst ance. You can use this option only when your instance has the database open.

If you omit both the GLOBAL and LOCAL options, Oracle performs a global checkpo int. For more information, see "Performing a Checkpoint". CHECK DATAFILES GLOBAL verifies that all instances that have opened the database can access all online datafiles. LOCAL verifies that your instance can access all online datafiles. If you omit both the GLOBAL and LOCAL options, Oracle uses GLOBAL by default. F or more information, see "Checking Datafiles". You can use the following parameters and options only when your instance has the database open: RESOURCE_LIMIT controls resource limits. TRUE enables resource limits; FALSE disables resource limits. See also "Using Resource Limits". GLOBAL_NAMES controls the enforcement of global name resolution for your session. TRUE enabl es the enforcement of global names; FALSE disables the enforcement of global nam es. For more information, see "Global Name Resolution". SCAN_INSTANCES in a parallel server, specifies the number of instances to participate in paral lelized operations. This syntax will be obsolete in the next major release. CACHE_INSTANCES in a parallel server, specifies the number of instances that will cache a table . This syntax will be obsolete in the next major release. For more information on parallel operations, see Oracle8 Tuning. For more information on the following multithreaded server parameters, see "Mana ging Processes for the Multithreaded Server". MTS_SERVERS specifies a new minimum number of shared server processes. MTS_DISPATCHERS specifies a new number of dispatcher processes: protocol is the network protocol of the dispatcher processes. integer is the new number of dispatcher processes of the specified protocol. You can specify multiple MTS_DISPATCHERS parameters in a single command for mul tiple network protocols.

For more information on the following licensing parameters, see "Using Licensing Limits". JOB_QUEUE_PROCESSES specifies the number of job queue processes per instance (SNPn, where n is 0 to 9 followed by A to Z). Set this parameter to 1 or higher if you wish to have yo ur snapshots updated automatically. One job queue process is usually sufficient unless you have many snapshots that refresh simultaneously. Oracle also uses job queue processes to process requests created by the DBMS_JOB package. For more information on managing table snapshots, see Oracle8 Replicat ion. LICENSE_MAX_SESSIONS limits the number OS sessions on your instance. A value of 0 disables the limit . LICENSE_SESSIONS_WARNING establishes a threshold of sessions over which Oracle writes warning messages t o the ALERT file for subsequent sessions. A value of 0 disables the warning thre shold. LICENSE_MAX_USERS limits number of concurrent users on your database. A value of 0 disables the l imit. REMOTE_DEPENDENCIES_MODE specifies how dependencies of remote stored procedures are handled by the serve r. For more information, refer to Oracle8 Application Developer's Guide.

SWITCH LOGFILE switches redo log file groups. For more information, see "Switching Redo Log Fi le Groups". DISTRIBUTED RECOVERY specifies whether or not distributed recovery is enabled. ENABLE enables distributed recovery. In a single-process environment, you must use thi s option to initiate distributed recovery. DISABLE switches redo log files. For more information, see "Enabling and Disabling Distributed Recovery". ARCHIVE LOG manually archives redo log files or enables or disables automatic archiving. Se e the "ARCHIVE LOG clause". KILL SESSION terminates a session and any ongoing transactions. You must identify the sessio n with both of the following values from the V$SESSION view:

integer1 is the value of the SID column. integer2 is the value of the SERIAL# column. For more information, see "Terminating a Session". DISCONNECT SESSION disconnects the current session by destroying the dedicated server process (or virtual circuit if the connection was made via MTS). If configured, application failover will take effect. For more information about application failover see O racle8 Tuning and Oracle8 Parallel Server Concepts and Administration. You must identify the session with both of the following values from the V$SESSION view: integer1 is the value of the SID column. integer2 is the value of the SERIAL# column. POST_TRANSACTION allows ongoing transactions to complete before the session is disconnected. Thi s keyword is required when DISCONNECT SESSION is specified. For more information , see "Disconnecting a Session". PLSQL_V2_COMPATIBILITY modifies the compile-time behavior of PL/SQL programs to allow language constru cts that are illegal in Oracle8 (PL/SQL V3), but were legal in Oracle7 (PL/SQL V 2). See the PL/SQL User's Guide and Reference and Oracle8 Reference for more inf ormation about this system parameter. TRUE enables Oracle8 PL/SQL V3 programs to execute Oracle7 PL/SQL V2 constructs. FALSE disallows illegal Oracle7 PL/SQL V2 constructs. This is the default. MAX_DUMP_FILE_SIZE specifies the trace dump file size upper limit for all user sessions. Specify t he maximum size as either a nonnegative integer that represents the number of bl ocks, or as 'UNLIMITED'. If you specify 'UNLIMITED', no upper limit is imposed. DEFERRED modifies the trace dump file size upper limit for future user sessions only.

Restricting Logons By default, any user granted CREATE SESSION system privilege can log on to Oracl e. The ENABLE RESTRICTED SESSION option of the ALTER SYSTEM command prevents log ons by all users except those having RESTRICTED SESSION system privilege. Existi

ng sessions are not terminated. You may want to restrict logons if you are performing application maintenance an d you want only application developers with RESTRICTED SESSION system privilege to log on. To restrict logons, issue the following statement: ALTER SYSTEM ENABLE RESTRICTED SESSION; You can then terminate any existing sessions using the KILL SESSION clause of th e ALTER SYSTEM command. After performing maintenance on your application, issue the following statement to allow any user with CREATE SESSION system privilege to log on: ALTER SYSTEM DISABLE RESTRICTED SESSION; Clearing the Shared Pool The FLUSH SHARED_POOL option of the ALTER SYSTEM command clears all information from the shared pool in the system global area (SGA). The shared pool stores thi s information: cached data dictionary information shared SQL and PL/SQL areas for SQL statements, stored procedures, functions, pa ckages, and triggers You might want to clear the shared pool before beginning performance analysis. T o clear the shared pool, issue the following statement: ALTER SYSTEM FLUSH SHARED_POOL; The above statement does not clear shared SQL and PL/SQL areas for SQL statement s, stored procedures, functions, packages, or triggers that are currently being executed, or for SQL SELECT statements for which all rows have not yet been fetc hed. Performing a Checkpoint The CHECKPOINT clause of the ALTER SYSTEM command explicitly forces Oracle to pe rform a checkpoint. You can force a checkpoint if you want to ensure that all ch anges made by committed transactions are written to the data files on disk. For more information on checkpoints, see the "Recovery Structures" chapter of Oracle 8 Concepts. If you are using Oracle with the Parallel Server option in parallel mode, you ca n specify either the GLOBAL option to perform a checkpoint on all instances that have opened the database or the LOCAL option to perform a checkpoint on only yo ur instance. The following statement forces a checkpoint: ALTER SYSTEM CHECKPOINT; Oracle does not return control to you until the checkpoint is complete.

Checking Datafiles The CHECK DATAFILES clause of the ALTER SYSTEM command verifies access to all on line datafiles. If any datafile is not accessible, Oracle writes a message to an ALERT file. You may want to perform this operation after fixing a hardware prob lem that prevented an instance from accessing a datafile. For more information o n using this clause, see Oracle8 Parallel Server Concepts and Administration. The following statement verifies that all instances that have opened the databas e can access all online datafiles: ALTER SYSTEM CHECK DATAFILES GLOBAL; Using Resource Limits When you start an instance, Oracle enables or disables resource limits based on the value of the initialization parameter RESOURCE_LIMIT. You can issue an ALTER SYSTEM statement with the RESOURCE_LIMIT option to enable or disable resource l imits for subsequent sessions. Enabling resource limits only causes Oracle to enforce the resource limits alrea dy assigned to users. To choose resource limit values for a user, you must creat e a profile, or a set of limits, and assign that profile to the user. For more i nformation on this process, see "CREATE PROFILE" and "CREATE USER". This ALTER SYSTEM statement dynamically enables resource limits: ALTER SYSTEM SET RESOURCE_LIMIT = TRUE; Global Name Resolution When you start an instance, Oracle determines whether to enforce global name res olution for remote objects accessed in SQL statements based on the value of the initialization parameter GLOBAL_NAMES. You can subsequently enable or disable gl obal name resolution while your instance is running with the GLOBAL_NAMES parame ter of the ALTER SYSTEM command. You can also enable or disable global name reso lution for your session with the GLOBAL_NAMES parameter of the ALTER SESSION com mand discussed earlier in this chapter. Oracle recommends that you enable global name resolution if you use or plan to u se distributed processing. For more information on global name resolution and ho w Oracle enforces it, see "Referring to Objects in Remote Databases" and Oracle8 Distributed Database Systems. Managing Processes for the Multithreaded Server When you start your instance, Oracle creates shared server processes and dispatc her processes for the multithreaded server architecture based on the values of t he following initialization parameters: MTS_SERVERS specifies the initial and minimum number of shared server processes. Oracle may automatically change the number of shared server processes if the load on the e xisting processes changes. While your instance is running, the number of shared server processes can vary between the values of the initialization parameters MT S_SERVERS and MTS_MAX_SERVERS. MTS_DISPATCHERS specifies one or more network protocols and the number of dispatcher processes for each protocol.

For more information on the multithreaded server architecture, see Oracle8 Conce pts. You can use the MTS_SERVERS and MTS_DISPATCHERS parameters of the ALTER SYSTEM c ommand to perform one of the following operations while the instance is running: To create additional shared server processes: You can cause Oracle to create add itional shared server processes by increasing the minimum number of shared serve r processes. To terminate existing shared server processes: Oracle terminates the shared serv er processes after it finishes processing their current calls, unless the load o n the server processes is so high that it cannot be managed by the remaining pro cesses. To create more dispatcher processes for a specific protocol: You can create addi tional dispatcher processes up to a maximum across all protocols specified by th e initialization parameter MTS_MAX_DISPATCHERS. You cannot use this command to create dispatcher processes for network protocols that are not specified by the initialization parameter MTS_DISPATCHERS. To crea te dispatcher processes for a new protocol, you must change the value of the ini tialization parameter. To terminate existing dispatcher processes for a specific protocol: Oracle termi nates the dispatcher processes only after their current user processes disconnec t from the instance. Example I The following statement changes the minimum number of shared server processes to 25: ALTER SYSTEM SET MTS_SERVERS = 25; If there are currently fewer than 25 shared server processes, Oracle creates mor e. If there are currently more than 25, Oracle terminates some of them when they are finished processing their current calls if the load could be managed by the remaining 25. Example II The following statement dynamically changes the number of dispatcher processes f or the TCP/IP protocol to 5 and the number of dispatcher processes for the DECNE T protocol to 10: ALTER SYSTEM SET MTS_DISPATCHERS = 'TCP, 5' MTS_DISPATCHERS = 'DECnet, 10'; If there are currently fewer than 5 dispatcher processes for TCP, Oracle creates new ones. If there are currently more than 5, Oracle terminates some of them af ter the connected users disconnect. If there are currently fewer than 10 dispatcher processes for DECnet, Oracle cre ates new ones. If there are currently more than 10, Oracle terminates some of th em after the connected users disconnect.

If there are currently existing dispatchers for another protocol, the above stat ement does not affect the number of dispatchers for that protocol. Using Licensing Limits Oracle enforces concurrent usage licensing and named user licensing limits speci fied by your Oracle license. When you start your instance, Oracle establishes th e licensing limits based on the values of the following initialization parameter s: LICENSE_MAX_SESSIONS establishes the concurrent usage licensing limit, or the limit for concurrent s essions. Once this limit is reached, only users with RESTRICTED SESSION system p rivilege can connect. LICENSE_SESSIONS_WARNING establishes a warning threshold for concurrent usage. Once this threshold is re ached, Oracle writes warning messages to the database ALERT file for each subseq uent session. Also, users with RESTRICTED SESSION system privilege receive warni ng messages when they begin subsequent sessions. LICENSE_MAX_USERS establishes the limit for users connected to your database. Once this limit is reached, more users cannot connect.

You can dynamically change or disable limits or thresholds while your instance i s running using the LICENSE_MAX_SESSIONS, LICENSE_SESSIONS_WARNING, and LICENSE_ MAX_USERS parameters of the ALTER SYSTEM command. Do not disable or raise sessio n or user limits unless you have appropriately upgraded your Oracle license. For information on upgrading your license, contact your Oracle sales representative . New limits apply only to future sessions and users: If you reduce the limit on sessions below the current number of sessions, Oracle does not end existing sessions to enforce the new limit. Users without RESTRICT ED SESSION system privilege can begin new sessions only when the number of sessi ons falls below the new limit. If you reduce the warning threshold for sessions below the current number of ses sions, Oracle writes a message to the ALERT file for all subsequent sessions. You cannot reduce the limit on users below the current number of users created f or the database. Example I The following statement dynamically changes the limit on sessions for your insta nce to 64 and the warning threshold for sessions on your instance to 54: ALTER SYSTEM SET LICENSE_MAX_SESSIONS = 64 LICENSE_SESSIONS_WARNING = 54; If the number of sessions reaches 54, Oracle writes a warning message to the ALE RT file for each subsequent session. Also, users with RESTRICTED SESSION system privilege receive warning messages when they begin subsequent sessions. If the number of sessions reaches 64, only users with RESTRICTED SESSION system

privilege can begin new sessions until the number of sessions falls below 64 aga in. Example II The following statement dynamically disables the limit for sessions on your inst ance: ALTER SYSTEM SET LICENSE_MAX_SESSIONS = 0; After you issue the above statement, Oracle no longer limits the number of sessi ons on your instance. Example III The following statement dynamically changes the limit on the number of users in the database to 200: ALTER SYSTEM SET LICENSE_MAX_USERS = 200; After you issue the above statement, Oracle prevents the number of users in the database from exceeding 200. Switching Redo Log File Groups The SWITCH LOGFILE option of the ALTER SYSTEM command explicitly forces Oracle t o begin writing to a new redo log file group, regardless of whether the files in the current redo log file group are full. You may want to force a log switch to drop or rename the current redo log file group or one of its members, because y ou cannot drop or rename a file while Oracle is writing to it. The forced log sw itch affects only your instance's redo log thread. Note that when you force a lo g switch, Oracle begins to perform a checkpoint. Oracle returns control to you i mmediately rather than when the associated checkpoint is complete. The following statement forces a log switch: ALTER SYSTEM SWITCH LOGFILE; Enabling and Disabling Distributed Recovery Oracle allows you to perform distributed transactions, or transactions that modi fy data on multiple databases. If a network or machine failure occurs during the commit process for a distributed transaction, the state of the transaction may be unknown, or in doubt. Once the failure has been corrected and the network and its nodes are back online, Oracle recovers the transaction. If you are using Oracle in multiple-process mode, this distributed recovery is p erformed automatically. If you are using Oracle in single-process (single user) mode, such as on the MS-DOS operating system, you must explicitly initiate distr ibuted recovery with the following statement. ALTER SYSTEM ENABLE DISTRIBUTED RECOVERY; You may need to issue the above statement more than once to recover an in-doubt transaction, especially if the remote node involved in the transaction is not ac cessible. In-doubt transactions appear in the data dictionary view DBA_2PC_PENDI NG. You can tell that the transaction is recovered when it no longer appears in

DBA_2PC_PENDING. For more information about distributed transactions and distrib uted recovery, see Oracle8 Distributed Database Systems. You can disable distributed recovery in both single-process and multiprocess mod e with the following statement: ALTER SYSTEM DISABLE DISTRIBUTED RECOVERY; You may want to disable distributed recovery for demonstration purposes. You can then enable distributed recovery again by issuing an ALTER SYSTEM statement wit h the ENABLE DISTRIBUTED RECOVERY clause. Terminating a Session The KILL SESSION clause of the ALTER SYSTEM command terminates a session, immedi ately performing the following tasks: rolling back its current transactions releasing all of its locks freeing all of its resources You may want to kill the session of a user that is holding resources needed by o ther users. The user receives an error message indicating that the session has b een killed; that user can no longer make calls to the database without beginning a new session. You can kill a session only on the same instance as your current session. If you try to kill a session that is performing some activity that must be compl eted, such as waiting for a reply from a remote database or rolling back a trans action, Oracle waits for this activity to complete, kills the session, and then returns control to you. If the waiting lasts as long as a minute, Oracle marks t he session to be killed and returns control to you with a message indicating tha t the session is marked to be killed. Oracle then kills the session when the act ivity is complete. Example Consider this data from the V$SESSION dynamic performance table: SELECT sid, serial, username FROM v$session SID SERIAL USERNAME ----- --------- ---------------1 1 2 1 3 1 4 1 5 1 7 1 8 28 OPS$BQUIGLEY 10 211 OPS$SWIFT 11 39 OPS$OBRIEN 12 13 SYSTEM 13 8 SCOTT The following statement kills the session of the user SCOTT using the SID and SE RIAL# values from V$SESSION:

ALTER SYSTEM KILL SESSION '13, 8'; Disconnecting a Session The DISCONNECT SESSION clause is similar to the KILL SESSION clause, but with tw o distinct differences. First, the ALTER SYSTEM DISCONNECT SESSION 'X, Y' POST_TRANSACTION command waits until any current transaction that the session is working on completes before t aking effect. Second, the session is disconnected rather than killed, which means that the ded icated server process (or virtual circuit if the connection was made through MTS ) is destroyed by this command. Termination of a session's connection causes app lication failover to take effect if the appropriate system parameters are config ured. Disconnecting a session essentially allows you to perform a manual application f ailover. Using this command in a parallel server environment allows you to disco nnect sessions on an overloaded instance and shift them to another instance. The POST_TRANSACTION keyword is required. Example The following statement disconnects user SCOTT's session, using the SID and SERI AL# values from V$SESSION: ALTER SYSTEM DISCONNECT SESSION '13, 8' POST_TRANSACTION; ***************************************************************************/ --------------------------------------------------------------------------------------------

You might also like