"Oracle PL-SQL by Example" SHORT NOTES





Hemiseki kimi ilk olaraq  “HELLO WORLD“ example-mizle baslayaq ;)
BEGIN
DBMS_OUTPUT.PUT_LINE('hello, world');
END;



DBMS_OUTPUT.PUT_LINE   bele deyim de  bizim javada , c#-da  sout veya messagebox.show   ne isi gourse onlarla eyni isi gorur .


Execute etdikden sora neticeni consolda gormek ucun ise  evvelceden  asagidaki kodu run edin
SET SERVEROUTPUT ON





PL/SQL  umumi sintaksis formasi asagidaki kimidr
DECLARE
Declaration statements
BEGIN
Executable statements
EXCEPTION
Exception-handling statements
END;

Isteseniz  nested(ic-ice)  begin-end bloklar da yazma imkaniniz var



BEGIN -- outer block
BEGIN -- inner block
...;
END; -- end of inner block
END; -- end of outer block

Meselem bucur
SET SERVEROUTPUT ON
<< outer_block >>
DECLARE
v_test NUMBER := 123;
BEGIN
DBMS_OUTPUT.PUT_LINE
('Outer Block, v_test: '||v_test);
<< inner_block >>
DECLARE
v_test NUMBER := 456;
BEGIN
DBMS_OUTPUT.PUT_LINE
('Inner Block, v_test: '||v_test);
DBMS_OUTPUT.PUT_LINE
('Inner Block, outer_block.v_test: '||
Outer_block.v_test);
END inner_block;
END outer_block;






Declare hissesinde  deyiskenlerimizi declare edirik adi ustunde)))

Deyisken adi + veya her hansi ededle baslaya bilmez
DECLARE
v_first_name VARCHAR2(35);
v_last_name VARCHAR2(35);
c_counter CONSTANT NUMBER := 0;



Meselem bir mesaji declare edib sora ona  deyer verib ekarana verek
DECLARE
msg VARCHAR2(30);
BEGIN
  msg := message_for_the_world;
  DBMS_OUTPUT.PUT_LINE(msg);
END;
***Bu arada  declare zamani  da  deyiskene qiymet de vere bilersiniz









Exceptionu handle –in ilkin formasi ise asagidaki kimidi
BEGIN
SELECT first_name, last_name
INTO v_first_name, v_last_name
FROM student
WHERE student_id = 123;
DBMS_OUTPUT.PUT_LINE ('Student name: '||v_first_name||' '||
v_last_name);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE ('There is no student with '||
'student id 123');
END;


DECLARE
v_student_id NUMBER := &sv_student_id;
v_enrolled VARCHAR2(3) := 'NO';
BEGIN
DBMS_OUTPUT.PUT_LINE ('Check if the student is enrolled');
SELECT 'YES'
INTO v_enrolled
FROM enrollment
WHERE student_id = v_student_id;
DBMS_OUTPUT.PUT_LINE ('The student is enrolled into one course');
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE ('The student is not enrolled');

WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE
('The student is enrolled in too many courses');
END;

Bizim javada vey a C# -da stringleri birlesdirerken  istfde etidiyimiz  +  evezine plsqlde  ||  islenir

SET SERVEROUTPUT ON
DECLARE
e_show_exception_scope EXCEPTION;  
-- BU SEKILDE EXCEPTIONU EVVELCEDEN DECLARE DE ETMEK OLAR
v_student_id NUMBER := 123;
BEGIN
DBMS_OUTPUT.PUT_LINE('outer student id is '
||v_student_id);
DECLARE
v_student_id VARCHAR2(8) := 125;
BEGIN
DBMS_OUTPUT.PUT_LINE('inner student id is '
||v_student_id);
RAISE e_show_exception_scope;
END;
EXCEPTION
WHEN e_show_exception_scope
THEN
DBMS_OUTPUT.PUT_LINE('When am I displayed?');
DBMS_OUTPUT.PUT_LINE('outer student id is '
||v_student_id);
END;



Iki error  sertin yoxlanmasi
EXCEPTION
WHEN VALUE_ERROR OR INVALID_NUMBER THEN
DBMS_OUTPUT.PUT_LINE ('An error has occurred');



Exception user terefinden define da edile biler evvelceden

DECLARE
e_invalid_id EXCEPTION;
BEGIN
...
EXCEPTION
WHEN e_invalid_id THEN
DBMS_OUTPUT.PUT_LINE ('An id cannot be negative');
END;


Other-  xetasi butun xetalari  tutur

DECLARE 
   a date; 
 BEGIN 
   select sysdate into a from dual; 
   insert into date values(a); 
   COMMIT; 
 EXCEPTION  
   WHEN OTHERS THEN 
    ROLLBACK; 
 END;






SQLCODE fonksiyonu SQL xeta nomresini verir, SQLERRM ise SQL xeta  mesajını verir
DECLARE
v_zip VARCHAR2(5) := '&sv_zip';
v_city VARCHAR2(15);
v_state CHAR(2);
v_err_code NUMBER;
v_err_msg VARCHAR2(200);
BEGIN
SELECT city, state
INTO v_city, v_state
FROM zipcode
WHERE zip = v_zip;
DBMS_OUTPUT.PUT_LINE (v_city||', '||v_state);
EXCEPTION
WHEN OTHERS THEN
v_err_code := SQLCODE;
v_err_msg := SUBSTR(SQLERRM, 1, 200);
DBMS_OUTPUT.PUT_LINE ('Error code: '||v_err_code);
DBMS_OUTPUT.PUT_LINE ('Error message: '||v_err_msg);
END;



Exception
Oracle Hata Kodu
SQLCODE Değeri

ACCESS_INTO_NULL

ORA-06530

-6530

CASE_NOT_FOUND

ORA-06592

-6592

COLLECTION_IS_NULL

ORA-06531

-6531

CURSOR_ALREADY_OPEN

ORA-06511

-6511

DUP_VAL_ON_INDEX

ORA-00001

-1

INVALID_CURSOR

ORA-01001

-1001

INVALID_NUMBER

ORA-01722

-1722

LOGIN_DENIED

ORA-01017

-1017

NO_DATA_FOUND

ORA-01403

+100

NOT_LOGGED_ON

ORA-01012

-1012

PROGRAM_ERROR

ORA-06501

-6501

ROWTYPE_MISMATCH

ORA-06504

-6504

SELF_IS_NULL

ORA-30625

-30625

STORAGE_ERROR

ORA-06500

-6500

SUBSCRIPT_BEYOND_COUNT

ORA-06533

-6533

SUBSCRIPT_OUTSIDE_LIMIT

ORA-06532

-6532

SYS_INVALID_ROWID

ORA-01410

-1410

TIMEOUT_ON_RESOURCE

ORA-00051

-51

TOO_MANY_ROWS

ORA-01422

-1422

VALUE_ERROR

ORA-06502

-6502

ZERO_DIVIDE

ORA-01476

-1476






PL/SQl-de ozumuz  RAISE_APPLICATION_ERROR   ile oz exception ORA xetalarimizi yarada bilerik
Burada xeta  nomresi -20000 ile -20999 arasında ola biler. Xeta mesajı da 2048 bytes uzunluğunda ola biler

Declare  
    
 Begin  
  --"hata"'ya neden olabilecek işlemler  
 raise_application_error(-20001,'Dikkat!!');
 End;  

Indi ise bu xetamizi istfde edek

DECLARE  
  stok_error exception;  
  stok number(5);  
 BEGIN  
   select sayı into stok from anbar;  
   IF stok< 100 THEN  
    RAISE stok_ error;  
   END IF;  
 EXCEPTION  
   WHEN stok_ error THEN  
    raise_application_error(-20001,"Stok error bas Verdi!!");  
 END;  

Eger  stok  100-den kicikdise  stok_error throw olmasini deyirik.Sonra ise  bu error zamani ne gostersin deyirik


PL/SQL Xetalarini Bir SQL xeta nomresine gore yazdirmaq: 

xetalara adlandirmaq ucun
"pragma exception_init(exception_adi -Oracle_xeta_nomresi);" şeklinde bir ifade itfde edilir.


 Declare 
  xeta exception; 
  pragma exception_init(xeta,-60); 
 Begin 
  --"xeta"'ya sebeb emelyatlar… 
 Exception 
  When xeta then 
  Rollback; 
 End; 

ORA-00060 olan deadlock xetasini "xeta" olarak tutduq


FUNCTION miles_debit(p_trans_id  IN NUMBER,
                       p_ext_refno IN VARCHAR2) RETURN NUMBER
  IS
    l_trans_id NUMBER;
    not_enough_balance EXCEPTION;
    PRAGMA EXCEPTION_INIT(not_enough_balance,-80101); 
  BEGIN
     l_trans_id :=  bonus_test.miles_order_pkg.milesdebit@bonus(p_tranid => p_trans_id,p_key => p_ext_refno);
   
     RETURN l_trans_id; 
                                                         
  EXCEPTION
     WHEN not_enough_balance THEN
       tools.raiseException(CONST.ERR_NOT_ENOUGH_MILES, 'not enough miles');                                                         
  END;




Deyiskeni  input formdan siz ozunuz daxil etmek istteyirsinizse & simvolu istfde etmelisiniz
v_num NUMBER := &sv_num;
bu zaman input form acilir ve y_num  -a deyer vermeyinizi isteyir

Meselem bu example baxaq
SET SERVEROUTPUT ON
DECLARE
v_num NUMBER := &sv_num;
v_result NUMBER;
BEGIN
v_result := POWER(v_num, 2);
DBMS_OUTPUT.PUT_LINE ('The value of v_result is: '||
v_result);
END;


NUMBER(5,3); bu cur teyin etme  size 5 reqemli olub vergulden sora 3 reqem yaza bilme imkani verir (meselem 12.345 ) eger  4-cu veya daha cox yazilarsa  avtomatik 3 vergule yuvarlaqlasdirilacaq

SET SERVEROUTPUT ON
DECLARE
v_name student.first_name%TYPE;
v_grade grade.numeric_grade%TYPE;
BEGIN
DBMS_OUTPUT.PUT_LINE(NVL(v_name, 'No Name ')||
' has grade of '||NVL(v_grade, 0));
END;

%TYPE ile  bazadaki columumuzun tipinde oldugunu qeyd ede bilirik

DECLARE
v_zip zipcode.zip%TYPE;
v_user zipcode.created_by%TYPE;
v_date zipcode.created_date%TYPE;
BEGIN
SELECT 43438, USER, SYSDATE
INTO v_zip, v_user, v_date
--Bu setir ile biz selectden gelen neticeleri  deyiskenlerimizie veririk

FROM dual;

INSERT INTO zipcode
(ZIP, CREATED_BY ,CREATED_DATE, MODIFIED_BY,
MODIFIED_DATE
)
VALUES(v_zip, v_user, v_date, v_user, v_date);
--Burada ise hemin deyiskenleri bazamiza uygun cedvelimize yaziriq
END;





SAVEPOINT istfdesi ile  rollback etmek

BEGIN
INSERT INTO student
( student_id, Last_name, zip, registration_date,
created_by, created_date, modified_by,
modified_date
)
VALUES ( student_id_seq.nextval, 'Tashi', 10015,
'01-JAN-99', 'STUDENTA', '01-JAN-99',
'STUDENTA','01-JAN-99'
);
SAVEPOINT A;

INSERT INTO student
( student_id, Last_name, zip, registration_date,
created_by, created_date, modified_by,
modified_date
)
VALUES (student_id_seq.nextval, 'Sonam', 10015,
'01-JAN-99', 'STUDENTB','01-JAN-99',
'STUDENTB', '01-JAN-99'
);
SAVEPOINT B;

INSERT INTO student
( student_id, Last_name, zip, registration_date,
created_by, created_date, modified_by,
modified_date
)
VALUES (student_id_seq.nextval, 'Norbu', 10015,
'01-JAN-99', 'STUDENTB', '01-JAN-99',
'STUDENTB', '01-JAN-99'
);
SAVEPOINT C;

ROLLBACK TO B; 
END;


IF  sert opertaoru
IF CONDITION THEN
STATEMENT 1;
...
STATEMENT N;
END IF;


Else IF  strukturu:

IF CONDITION 1 THEN
STATEMENT 1;
ELSIF CONDITION 2 THEN
STATEMENT 2;








If ile  null olub olmamamagin yoxlanmasi
IF number_of_pages IS NULL
THEN
                     DBMS_OUTPUT.PUT_LINE('Warning: number of pages is unknown.');
END IF;



ELSIF CONDITION 3 THEN
STATEMENT 3;
...
ELSE
STATEMENT N;
END IF;

SET SERVEROUTPUT ON
DECLARE
v_student_id NUMBER := 102;
v_section_id NUMBER := 89;
v_final_grade NUMBER;
v_letter_grade CHAR(1);
BEGIN
SELECT final_grade
INTO v_final_grade
FROM enrollment
WHERE student_id = v_student_id
AND section_id = v_section_id;
IF v_final_grade >= 90 THEN
v_letter_grade := 'A';
ELSIF v_final_grade >= 80 THEN
v_letter_grade := 'B';
ELSIF v_final_grade >= 70 THEN
v_letter_grade := 'C';
ELSIF v_final_grade >= 60 THEN
v_letter_grade := 'D';
ELSE
v_letter_grade := 'F';
END IF;
-- control resumes here
DBMS_OUTPUT.PUT_LINE ('Letter grade is: '||
v_letter_grade);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE ('There is no such student or section');
END;


Qisa formada basqa formada da yazmaq olar

IF x = y THEN v_txt := 'YES'; ELSE v_txt :='NO'; END IF;


Ile asagidaki  forma eyni isi gorur

IF x = y THEN
v_txt := 'YES';
ELSE
v_txt := 'NO';
END IF;






DECLARE
v_num1 NUMBER := 0;
v_num2 NUMBER;
BEGIN
IF v_num1 = v_num2 THEN
DBMS_OUTPUT.PUT_LINE ('v_num1 = v_num2');
       ELSE
DBMS_OUTPUT.PUT_LINE ('v_num1 != v_num2');
END IF;
END;


ELSE IF -  bilirsinizki  eger bir  sert  odenirse  digger sertlere baxilmir


NULLIF (expression1, expression2)  --  iki expression bir birine beraberdise  null verir deyilse  ilk ifadeni geri qaytarir .
NVL- funksyasi ise tam tersini edir 2-ci ifadeni qaytarir  eyni deyilse

Meselem bir listi  0 –a beraber olanlari null edib getirmek isteyirsinizse
select NULLIF(list,0) from table


COALESCE()butun listi null olub omadigini yoxlayir ve listin ilk  qiymetini geri qaytarir

Ic ice  yazilmis  NVL  funkisyasi ile eyni isi gorur   yeni
NVL(expression1, NVL(expression2, NVL(expression3,...))) 

Loop  istfdesi

LOOP
STATEMENT 1;
STATEMENT 2;
...
STATEMENT N;
END LOOP;




Loop zamani sert  yazib loopdan cixmani da ede bilerik

LOOP
STATEMENT 1;
STATEMENT 2;
EXIT WHEN CONDITION;
END LOOP;



SET SERVEROUTPUT ON
DECLARE
v_counter BINARY_INTEGER := 0;
BEGIN
LOOP
-- increment loop counter by one
v_counter := v_counter + 1;
DBMS_OUTPUT.PUT_LINE ('v_counter = '||v_counter);
-- if EXIT condition yields TRUE exit the loop
IF v_counter = 5 THEN
EXIT;
END IF;
END LOOP;
-- control resumes here
DBMS_OUTPUT.PUT_LINE ('Done...');
END;



WHILE LOOP  istfdesi

WHILE CONDITION LOOP
STATEMENT 1;
STATEMENT 2;
...
STATEMENT N;
END LOOP;



FOR LOOP istfdesi

FOR loop_counter IN [REVERSE] lower_limit..upper_limit LOOP
STATEMENT 1;
STATEMENT 2;
...
STATEMENT N;
END LOOP;


BEGIN
FOR v_counter IN 1..5 LOOP
DBMS_OUTPUT.PUT_LINE ('v_counter = '||v_counter);
END LOOP;
END;



IN yanina  REVERSE  yazsaniz bu  tersden  yeni azalma demekdi.Counter get gede azalsin
BEGIN

FOR v_counter IN REVERSE 1..5 LOOP
DBMS_OUTPUT.PUT_LINE ('v_counter = '||v_counter);
END LOOP;
END;

v_counter = 5
v_counter = 4
v_counter = 3
v_counter = 2
v_counter = 1


Nested Loop-lar da mumkundu

BEGIN
<<outer>>
FOR v_counter IN 1..3 LOOP
<<inner>>
FOR v_counter IN 1..2 LOOP
DBMS_OUTPUT.PUT_LINE ('outer.v_counter '||outer.v_counter);
DBMS_OUTPUT.PUT_LINE ('inner.v_counter '||inner.v_counter);
END LOOP inner;
END LOOP outer;
END;





CONTiNUE  istfdesi -  loop-da  mueyyen sertde emelyatin uzerinnen hoppanib qaldigi yerden loppa yninden girmeye komeklik edir


LOOP
STATEMENT 1;
STATEMENT 2;
IF CONTINUE_CONDITION THEN
CONTINUE;
END IF;
EXIT WHEN EXIT_CONDITION;
END LOOP;




CONTINUE WHEN  de istfde etmek olar

SET SERVEROUTPUT ON
DECLARE
v_sum NUMBER := 0;
BEGIN
FOR v_counter in 1..10 LOOP
-- if v_counter is odd, pass control to the top of the loop
CONTINUE WHEN mod(v_counter, 2) != 0;
v_sum := v_sum + v_counter;
DBMS_OUTPUT.PUT_LINE ('Current sum is: '||v_sum);
END LOOP;
-- control resumes here
DBMS_OUTPUT.PUT_LINE ('Final sum is: '||v_sum);
END;








PL/SQL  cursor

Lori dilde desem selectden geen neticeni ozunde saxlayir
Ve siz bunu hanisa loop-a salib select neticlerine gore nese ede bilersiz / 

1)      Implicit Cursor : Bu cursor tipi  DML ifadeleri (select, insert, update, delete)  vaxti yaradilan sadece bir setir iafedelri

2)      Explicit Cursor: birden cox netice qaytaran select ifadeleri

Bu 2 cursor tipi eyni  işleve sahiptirler ancak erişim biçiminde farklılık gösterirler


DECLARE
  CURSOR cur_personel IS
     SELECT adi
         FROM personel
      WHERE personel_id = 3;

   v_adi VARCHAR2(50);
BEGIN
  OPEN cur_personel ;
  FETCH cur_personel INTO v_adi;
  CLOSE cur_personel;
END;

Bu explicit cursordur  gelin ind bunu implict formada yazaq:

DECLARE
   v_adi VARCHAR2(50);
BEGIN
   SELECT adi 
        INTO v_adi
   FROM personel
   WHERE personel_id = 3;
END;


Implict cursorda diqqet edin sadeec 1 data done biler

Impict  cursorlarda   open close fetch islerin  oracle ozu axa terefde edir. Implict cursor eslinde performans olaraq daha yaxsidi amma  dezavantaji  xetaya daha aciq olmasidi


declare 
  cursor p_cur is  select ID,CODE from PRODUCTNAMES;
begin
  for p_data in p_cur
  loop
update PRODUCT set product_code = p_data.code where id = p_data.id;
  commit;
end loop;
end;

Yuxaridaki kodda  Productnamesden gelen idleri ve codlari  p_cur  cursorumuza yigdiq , Sonra ise  loopa salib   pdata –ya menipsetdik her gelen rowdaki deyerleri
Ve  product cedvelinde  gelen idyle yoxlayib beraberdise update etdik


FETCHING ROWS IN A CURSOR

FETCH cursor_name INTO PL/SQL variables;

Or

FETCH cursor_name INTO PL/SQL record;
SET SERVEROUTPUT ON



DECLARE
CURSOR c_zip IS
SELECT *
FROM zipcode;
vr_zip c_zip%ROWTYPE;
BEGIN
OPEN c_zip;   ---  cursoru acmaq
LOOP
FETCH c_zip INTO vr_zip;
EXIT WHEN c_zip%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(vr_zip.zip||
' '||vr_zip.city||' '||vr_zip.state);
END LOOP;
END;

SET SERVEROUTPUT ON;
DECLARE
CURSOR c_student_name IS
SELECT first_name, last_name
FROM student
vr_student_name c_student_name%ROWTYPE;
BEGIN
OPEN c_student_name;
LOOP
FETCH c_student_name INTO vr_student_name;
EXIT WHEN c_student_name%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Student name: '||
vr_student_name.first_name
||' '||vr_student_name.last_name);
END LOOP;
CLOSE c_student_name;    - cursoru baglamaq
END;

Diqqet etdinizse  OPEN ve CLOSE istde etdik .
Bir seyi buarada bilinki  eger bir cursoru baglamasaq  ondan sora hemin cursoru loop-da istfde etseniz  0-dan baslamiyacaq  yeni oldugu son movqeden cursor  istfde edilecek






Explicit Cursor –un bir ozelliyi :
%ISOPEN : Cursor açılmış ve baglanmamais ise TRUE, baglanmis veya açılmamış ise FALSE qaytarir


Implict cursorda bezi ozleiikler var ki olari istfde ede bilersiniz
CURSOR ATTRIBUTE SYNTAX DESCRIPTION

%NOTFOUND         cursor_name%NOTFOUND        
 A Boolean attribute that returns TRUE if
the previous FETCH did not return a row
and FALSE if it did.


%FOUND              cursor_name%FOUND
 A Boolean attribute that returns TRUE if
the previous FETCH returned a row and
FALSE if it did not.


%ROWCOUNT            cursor_name%ROWCOUNT
The number of records fetched from a
cursor at that point in time.
%ISOPEN cursor_name%ISOPEN A Boolean attribute that returns TRUE if
the cursor is open and FALSE if it is not.

SET SERVEROUTPUT ON
DECLARE
v_sid student.student_id%TYPE;
CURSOR c_student IS
SELECT student_id
FROM student
WHERE student_id < 110;
BEGIN
OPEN c_student;
LOOP
FETCH c_student INTO v_sid;
IF c_student%FOUND THEN
DBMS_OUTPUT.PUT_LINE
('Just FETCHED row '
||TO_CHAR(c_student%ROWCOUNT)||
' Student ID: '||v_sid);
                      ELSE
EXIT;
END IF;
END LOOP;
CLOSE c_student;
EXCEPTION
WHEN OTHERS
THEN
IF c_student%ISOPEN
THEN
CLOSE c_student;
END IF;
END;


SET SERVEROUTPUT ON
DECLARE
v_city zipcode.city%type;
BEGIN
SELECT city
INTO v_city
FROM zipcode
WHERE zip = 07002;
IF SQL%ROWCOUNT = 1
THEN
DBMS_OUTPUT.PUT_LINE(v_city ||' has a '||
'zipcode of 07002');
ELSIF SQL%ROWCOUNT = 0
THEN
DBMS_OUTPUT.PUT_LINE('The zipcode 07002 is '||
' not in the database');
ELSE
DBMS_OUTPUT.PUT_LINE('Stop harassing me');
END IF;
END;


Paremetirli CURSOR
Yazilis formasi
CURSOR c_zip (p_state IN zipcode.state%TYPE) IS
SELECT zip, city, state
FROM zipcode
WHERE state = p_state;


IStfadesine baxaq

DECLARE
CURSOR c_zip (p_state IN zipcode.state%TYPE) IS
SELECT zip, city, state
FROM zipcode
WHERE state = p_state
BEGIN
FOR r_zip IN c_zip('NJ')
LOOP ...
DBMS_OUTPUT.PUT_LINE(r_zip.city||
' '||r_zip.zip');
END LOOP;
END;


TRIGGERLER
Triggerleri  bazada mueyyen emeliyyatlar etdikden evvel vey a sonar nese etditmek isteyirikse istfde edirik
Trigger ile meselem :
-Cedvele data  girişi, update ve silme emeliyyatlarini loglaya bilerik.
-Oracle Login-Logof –lari loglaya bilerik  
-Cedvel  üzerinde geden  DML –lere controller qoya bilerik
-Avtomatik  artan primary (sequence)-e  trigger ile default gondere bilerik.

CREATE
    [DEFINER = { user | CURRENT_USER }]
    TRIGGER trigger_name
    trigger_time trigger_event
    ON tbl_name FOR EACH ROW
    trigger_body
trigger_time: { BEFORE | AFTER }
trigger_event: { INSERT | UPDATE | DELETE }

Buradaki  before ve after – yeni emeliyyatdn evvelmi yoxsa sonrami  gorsun ne edirse onu onu bildiririk !


Triggerleri yaradarken  artiq islek veziyyete enable vezyitenide olurlar.Bu bezen problemler yarada biler deye  diabled  seklinde de yaratmaq olar  yeni sonradan ozunuz enable edersiniz.

CREATE OR REPLACE TRIGGER SALES_TRG
BEFORE INSERT ON SALES_TAB
FOR EACH ROW
DISABLED
BEGIN
NULL;
END;


Before Insert ile  yeni insertden evvel  istfde ederek  defult deyer verme  emeliyyatini ede bielrik
Meselem bir 4 sutunlu cedvelimiz olsun
CREATE TABLE sales_tab(
order_no NUMBER,
order_date DATE,
customer_id VARCHAR2(10),
sales_user VARCHAR2(30));

Bu cedvele insert zamani  bezi columlara  default valueni   trggerimiz ile verek
CREATE OR REPLACE TRIGGER SALES_TRG_1
BEFORE INSERT ON sales_tab
FOR EACH ROW
DECLARE
BEGIN
:NEW.SALES_USER:=USER;
:NEW.ORDER_DATE:=SYSDATE;
END;


INSERT INTO sales_tab(order_no,customer_id) VALUES (1,'M0001');



SELECT  * FROM sales_tab;

ORDER_NO  ORDER_DATE            CUSTOMER_ID   SALES_USER
1          1/13/2013 5:32:37 PM      M0001          HR


Diqqet etseniz  biz  oerder_Date ve sales_user –e  deyer vermedik insert zamani
Ancaq yazdigimiz trigger ile  deyerler verildi .
Ve bir seyi de diqqete alinki eger deyer verseydik bele  triggerimiz  o deyerleri override edib oz defaultunu verecekdi !


                                  

Before delete ile meselem  silmeye icaze vermeyek triggerimiz ile
CREATE OR REPLACE TRIGGER SALES_TRG_2
  BEFORE DELETE ON sales_tab
  FOR EACH ROW
DECLARE
BEGIN
raise_application_error(-20000, 'SILME_OLMAZ : SIle Bilmezsiniz !!!.');
END;

Indi ise silmeyi yoxlayaq
DELETE FROM sales_tab n WHERE n.order_no=1;


ORA-20000: 'SILME_OLMAZ : SIle Bilmezsiniz !!!.
ORA-06512: at "HR.SALES_TRG_2", line 3
ORA-04088: error during execution of trigger 'HR.SALES_TRG_2'

Gorduyunuz kimi mesajimizi aldiq


Basqa bir misalda meselem eger heftesonudusa    bazaya  emelyat etmeye icaze vermeyek

CREATE OR REPLACE TRIGGER SALES_TRG_3
  BEFORE INSERT OR UPDATE OR DELETE ON sales_tab
  FOR EACH ROW
DECLARE
BEGIN
IF TRIM(to_char(SYSDATE,'DAY')) IN ('SATURDAY','SUNDAY') THEN
raise_application_error(-20000,'HSONU:Heftesonu her hansi  emeliyyat apara bilmezsiniz !!!');
END IF;
END;


Bir heftesonunda cedvelimizde update temeye calisaq ))
UPDATE sales_tab f
SET f.order_date=f.order_date+1
WHERE f.order_no=1;

ORA-20000: 'HSONU:Heftesonu her hansi  emeliyyat apara bilmezsiniz !!!
ORA-06512: at "HR.SALES_TRG_3", line 5
ORA-04088: error during execution of trigger 'HR.SALES_TRG_3'








Gelin indi ise mueyyen bir user-in  login olmaya qoymaga
CREATE OR REPLACE TRIGGER SALES_TRG_4
   AFTER LOGON ON DATABASE
BEGIN
   IF SYS_CONTEXT('USERENV','SESSION_USER') IN (RESUL) THEN
      raise_application_error(-20003,'Icaze verilmedi !!!..');
   END IF;
END;


Indi ise bir cedvel yaradaq ve burada   kim ne zaman slime emeliyyati etdise  onun kim oldigi ne vaxt sildiyii tutaq

CREATE TABLE SALES_TAB_LOG
( order_no NUMBER,
order_date DATE,
customer_id VARCHAR2(10),
sales_user VARCHAR2(30),
delete_user VARCHAR2(30),
delete_time DATE);

CREATE OR REPLACE TRIGGER SALES_TRG_5
AFTER DELETE ON sales_tab
FOR EACH ROW
DECLARE
BEGIN
INSERT INTO sales_tab_log VALUES(
:OLD.Order_No,
:OLD.Order_Date,
:OLD.CUSTOMER_ID,
:OLD.SALES_USER,
USER,
SYSDATE,
:OLD.Order_No||' Nolu  data '||USER||' terefinden '||SYSDATE ||' Tarixinde  Silindi.');
END;


DELETE FROM sales_tab n WHERE n.order_no=1;
SELECT t.delete_user,t.delete_time,t.notes FROM SALES_TAB_LOG t;

1        HR       1/14/2013 10:15:10 AM       1 Nolu  data  HR terefinden 14-JAN-13 Tarixinde  Silindi





INSTEAD OF –triggerer  her hansi emeliyyat  zamani  onun evezine ne is gore bielrik onun icin istfde olunur
CREATE OR REPLACE TRIGGER instructor_summary_del
INSTEAD OF DELETE ON instructor_summary_view
–- burada cevdel yox view istfde ede bilerik
FOR EACH ROW
BEGIN
DELETE FROM section
WHERE instructor_id = :OLD.INSTRUCTOR_ID;
DELETE FROM instructor
WHERE instructor_id = :OLD.INSTRUCTOR_ID;
END;

Basqa bir missal olaraq meselem  bazadan nese silmeye calisan  adamin  computer_name-I sizden istenibse yeni bunun ucun INSTEAD OF  trigger isytfde etmelisiniz


Bu arada  view-lardan soz acilmisken

View yaratmaq
CREATE VIEW course_cost AS
SELECT course_no, description, cost
FROM course;
Bir seyi unutmuyun ki viewlar selectden gelen datani  yaradildiqda ozunde  store etmir



PL/SQL  collections

3 cur collection tipi var PL/SQL-de

1- Associative Array
2- Nested Table
3- Varray





1- Associative Array
Bu tipde  evelceden  tutumu  falan gosterilme ve  initialize olunmadan  istfde etmek olur
Index-imiz  varchar2, binary integer veya integer  ola biler
Index  tipini “index by” ile gosteririk
Colectionu yaratmaq ucun ise TYPE” sozu istfde edilir


DECLARE
TYPE myassociativearray IS TABLE OF NUMBER
INDEX BY PLS_INTEGER;
myarray  myassociativearray;
BEGIN
myarray (150) := 25;
DBMS_OUTPUT.put_line (myarray(150));
END;


VE YA INDEX TIPI DEYISEK

DECLARE
TYPE myassociativearray IS TABLE OF NUMBER
INDEX BY VARCHAR2 (30);
myarray myassociativearray;
BEGIN
myarray (‘Turkey) := 90;
myarray (‘Germany) := 49;
myarray (‘Amrica) := 1;
myarray (‘Nitherland) := 31;
END;

2- Nested Table

Bu collection tipinde de evvelceden tutum gosterilmir ancaq  ferq ondadirki  bu tipde evvelceden initialize olunmalidir

DECLARE
TYPE mynestedtablearray IS TABLE OF NUMBER;
myarray mynestedtablearray;
BEGIN
myarray := mynestedtablearray (); — Initializing   
myarray.EXTEND; — 1 itemliq   yer acildi.
myarray (1) := 5;
myarray.EXTEND; — 1 itemliq  yer acildi.
myarray (2) := 15;
myarray.EXTEND (3); — 3 itemliq  yer acildi.
myarray (3) := 25;
myarray (4) := 35;
myarray (5) := 45;
END;


3)Varray: Bu collection tipi hem intiliaze edilmek, hemde başlangıçta tutumu  verilmelidir

DECLARE
TYPE myvarray IS VARRAY (3) OF NUMBER;
arrayvar myvarray;
BEGIN
arrayvar := myvarray (); — initiliazing
arrayvar.EXTEND (3); — 3 elemanlik yer acildi
arrayvar (1) := 1;
arrayvar (2) := 2;
arrayvar (3) := 3;
END;


Bezi Collection metodlari

EXISTS returns TRUE if a specified element exists in a collection. This method can be
used to avoid SUBSCRIPT_OUTSIDE_LIMIT exceptions.

. COUNT returns the total number of elements in a collection.
. EXTEND increases the size of a collection.

. DELETE deletes either all elements, elements in the specified range, or a particular
element from a collection. Note that PL/SQL keeps placeholders of the deleted elements.

. FIRST and LAST return subscripts of the first and last elements of a collection. Note that
if the first elements of a nested table are deleted, the FIRST method returns a value greater
than 1. If elements have been deleted from the middle of a nested table, the LAST method
returns a value greater than the COUNT method.

. PRIOR and NEXT return subscripts that precede and succeed a specified collection
subscript.

. TRIM removes either one or a specified number of elements from the end of a collection.
Note that PL/SQL does not keep placeholders for the trimmed elements.

Record Types
Bir biri ile baglantili ama ferqli tipleri tutur.Recordlari bir nov javadaki class-lara benzetmek olar.
TYPE record_typ IS RECORD(
     field1 datatype1 [NOT NULL] [:= expression1],
     field1 datatype2 [NOT NULL] [:= expression2],
     …
    
field1 datatypen [NOT NULL] [:= expressionn]
);

Meselem
TYPE person_rec_typ IS RECORD(
     vlast_name varchar2(30),
     vsalary        number(5) NOT NULL := 0,
     phone         varchar2(10)
);


DECLARE
TYPE person_rec_typ IS RECORD(
     vlast_name employee.last_name%TYPE,
     vsalary employee.salary%TYPE NOT NULL := 0,
     phone employee.phone%TYPE,
);
Recordun istfdesine baxaq

vperson_rec person_rec_typ;
BEGIN
     SELECT last_name, salary, phone
     INTO
vperson_rec
     FROM employee WHERE id =101;     vperson_rec.vsalary := vperson_rec.vsalary + 2000;
    IF
vperson_rec.vsalary > 3000 THEN
          dbms_output.put_line(’Person: ‘||
vperson_rec.vlast_name ||
                                          ‘ ‘ ||
vperson_rec.phone || ‘ $’ ||vperson_rec.vsalary);
   ELSE        dbms_output.put_line(’Person: ‘||
vperson_rec.vlast_name ||’ ‘ ||vperson_rec.phone);
  END IF;
END;

Table besed ve cursor based olur recordlar
SET SERVEROUTPUT ON
DECLARE
zip_rec zipcode%ROWTYPE;
BEGIN
SELECT *
INTO zip_rec
FROM zipcode
WHERE rownum < 2;
DBMS_OUTPUT.PUT_LINE ('Zip: '||zip_rec.zip);
DBMS_OUTPUT.PUT_LINE ('City: '||zip_rec.city);
DBMS_OUTPUT.PUT_LINE ('State: '||zip_rec.state);
DBMS_OUTPUT.PUT_LINE ('Created By: '||zip_rec.created_by);
DBMS_OUTPUT.PUT_LINE ('Created Date: '||zip_rec.created_date);
DBMS_OUTPUT.PUT_LINE ('Modified By: '||zip_rec.modified_by);
DBMS_OUTPUT.PUT_LINE ('Modified Date: '||zip_rec.modified_date);
END;










SET SERVEROUTPUT ON
DECLARE
CURSOR zip_cur IS
SELECT *
FROM zipcode
WHERE rownum < 4;

zip_rec     zip_cur%ROWTYPE;
BEGIN
OPEN zip_cur;
LOOP
FETCH zip_cur INTO  zip_rec;
EXIT WHEN  zip_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE ('Zip: '||zip_rec.zip);
DBMS_OUTPUT.PUT_LINE ('City: '||zip_rec.city);
DBMS_OUTPUT.PUT_LINE ('State: '||zip_rec.state);
DBMS_OUTPUT.PUT_LINE ('Created By: '||zip_rec.created_by);
DBMS_OUTPUT.PUT_LINE ('Created Date:
'||zip_rec.created_date);
DBMS_OUTPUT.PUT_LINE ('Modified By:
'||zip_rec.modified_by);
DBMS_OUTPUT.PUT_LINE ('Modified Date:
'||zip_rec.modified_date);
END LOOP;
END;



Collections of record

SET SERVEROUTPUT ON
DECLARE
CURSOR name_cur IS
SELECT first_name, last_name
FROM student
WHERE ROWNUM <= 4;
TYPE    name_type    IS TABLE OF      name_cur%ROWTYPE;

name_tab name_type := name_type();
v_counter INTEGER := 0;
BEGIN
FOR name_rec IN name_cur LOOP
v_counter := v_counter + 1;
name_tab.EXTEND;
name_tab(v_counter).first_name := name_rec.first_name;
name_tab(v_counter).last_name := name_rec.last_name;
DBMS_OUTPUT.PUT_LINE('First Name('||v_counter||'): '||
name_tab(v_counter).first_name);
DBMS_OUTPUT.PUT_LINE('Last Name('||v_counter||'): '||
name_tab(v_counter).last_name);
END LOOP;
END;



  FUNCTION test RETURN t_product_bonus_coll
  IS
   l_bonus_z  bonus_test.bonus_common_pkg.getbonusestabletype@bonus;
   l_bonus    t_product_bonus;
   l_bonuses  t_product_bonus_coll;
   l_cifs     t_str_coll;
  BEGIN
     --get client cifs
     l_cifs := CORE_USER.get_user_flex_ids(p_user_id => CNTXT.USER_ID);
   
     IF l_cifs IS NOT NULL AND l_cifs.count > 0 THEN
       l_bonus_z := bonus_test.bonus_common_pkg.get_bonuses@bonus(l_cifs(l_cifs.first));
     END IF;

     l_bonuses := t_product_bonus_coll();
     --
     IF l_bonus_z IS NOT NULL THEN
       l_bonuses.extend(l_bonus_z.count);
       --
       FOR idx IN nvl(l_bonus_z.first, 0) .. nvl(l_bonus_z.last, -1)
         LOOP
           l_bonus := t_product_bonus();
           --
           l_bonus.id         := l_bonus_z(idx).bonusid;
           l_bonus.name       := l_bonus_z(idx).bonusname;
           l_bonus.currency   := l_bonus_z(idx).currency;
           l_bonus.amount     := nvl(l_bonus_z(idx).balance, 0);
           l_bonus.bonus_type := l_bonus_z(idx).bonustype;
           l_bonus.type       := CORE_PRODUCT.PRODUCT_BONUS;
           l_bonus.system     := CONST.SYSTEM_BNS;
           l_bonus.status     := CONST.STATUS_ACTIVE;

           l_bonuses(idx) := l_bonus;
         END LOOP;
     END IF;

     RETURN l_bonuses;
  END;



 FUNCTION get_gifts(p_paging_id   IN VARCHAR2,
                     p_paging_size IN INTEGER) RETURN T_GIFTS PIPELINED
  IS
    l_gift_coll_z  bonus_test.hearts_order_pkg.getgifttabletype@bonus;
    l_gift_z       bonus_test.hearts_order_pkg.getgifttype@bonus;
    l_gift         BONUS.t_gift;
    l_next         PLS_INTEGER;
  BEGIN
   
      l_gift_coll_z := bonus_test.hearts_order_pkg.getgiftlist@bonus(CNTXT.LANG , p_paging_id , p_paging_size); 
 
      IF l_gift_coll_z IS NOT NULL THEN
       
         l_next := l_gift_coll_z.first;
         WHILE (l_next IS NOT NULL)
           LOOP
               l_gift_z := l_gift_coll_z(l_next);

               l_gift.id            := l_gift_z.GIFT_ID;
               l_gift.name          := l_gift_z.GIFT_NAME;
               l_gift.price         := l_gift_z.HEARTS_PRICE;
               l_gift.currency      := l_gift_z.CURRENCY;
               l_gift.provider_id   := l_gift_z.PARTNER_ID;
               l_gift.provider_name := l_gift_z.PARTNER_NAME;
               l_gift.total         := l_gift_z.TOTAL_REST;
       
               PIPE ROW(l_gift);
               l_next := l_gift_coll_z.next(l_next);    
           END LOOP;
       END IF;

     RETURN;
  END;



EXECUTE IMMEDIATE
Execute immediate ile  dinamik olaraq kod icerisinde  string seklindeki sql-lerimizi  run ede bilerik
declare
  vString varchar2(300);
begin
  --Normal şekilde istfde edilen bir emeliyyat.
  begin
    dbms_output.put_line('normal isleyen  output emeliyyati’);
  end;

  --Execute immediate için hazırlanan string kod.
  vString := 'begin
               dbms_output.put_line(''execute immediate ile çalışan output.'');
              end;';

  --Statik ya da dinamik olarak hazırlanan string ifadeyi bu şekilde çalıştırabilersiniz.
  execute immediate vString;
end;







FORALL istfdesi

For iecrisinde bir nece defe  Insert , Update ,Delete yeni DML emeilyyatlari  edirsinizse
Bunun ucun for yox FORALL  istfde etmeniz meslehetdi performans ve doger cehetlerden
FOR i IN 1..10 LOOP
INSERT INTO table_name
VALUES (...);
END LOOP;

FORALL i IN 1..10
INSERT INTO test (row_num, row_text)
VALUES (row_num_tab(i), row_text_tab(i));
COMMIT;
Adi for istfdesinde  emeliyyat sql-den PL/SQL –e  tutaqki 10 defe gedecekdise  for all ile  sadece bir defe gonderir






BULK COLLECT
Cox yuklu sekilde bir data cekilecekse  bunu cursorla etmek evezine  BULK COLLECT istfde etmek cox daha performanslidir

Tutaqki:
DECLARE
CURSOR student_cur IS
SELECT student_id, first_name, last_name
FROM student;
BEGIN
FOR rec IN student_cur LOOP
DBMS_OUTPUT.PUT_LINE ('student_id: '||rec.student_id);
DBMS_OUTPUT.PUT_LINE ('first_name: '||rec.first_name);
DBMS_OUTPUT.PUT_LINE ('last_name: '||rec.last_name);
END LOOP;
END;

Indi ise eynis eyi bulk collect ile edek

DECLARE
-- Define collection type and variables to be used by the
-- BULK COLLECT clause
TYPE student_id_type IS TABLE OF student.student_id%TYPE;
TYPE first_name_type IS TABLE OF student.first_name%TYPE;
TYPE last_name_type IS TABLE OF student.last_name%TYPE;
student_id_tab student_id_type;
first_name_tab first_name_type;
last_name_tab last_name_type;
BEGIN
-- Fetch all student data at once via BULK COLLECT clause
SELECT student_id, first_name, last_name
BULK COLLECT INTO student_id_tab, first_name_tab, last_name_tab
FROM student;
FOR i IN student_id_tab.FIRST..student_id_tab.LAST
LOOP
DBMS_OUTPUT.PUT_LINE ('student_id: '||student_id_tab(i));
DBMS_OUTPUT.PUT_LINE ('first_name: '||first_name_tab(i));
DBMS_OUTPUT.PUT_LINE ('last_name: '||last_name_tab(i));
END LOOP;
END;






PL/SQL  prosedurlar

CREATE OR REPLACE PROCEDURE name
[(parameter[, parameter, ...])]
AS
[local declarations]
BEGIN
executable statements
[EXCEPTION
exception handlers]
END [name];

Geriye deyer dondurmeyeceksinizse istfde ede bilersiniz databasede yer tutmur
Parametirli ve ya parametirsiz de olurlar
IN , OUT , IN OUT tipde parameterler de ala bilir
CREATE OR REPLACE PROCEDURE Discount
AS
CURSOR c_group_discount
IS
SELECT distinct s.course_no, c.description
FROM section s, enrollment e, course c
WHERE s.section_id = e.section_id
AND c.course_no = s.course_no
GROUP BY s.course_no, c.description,
e.section_id, s.section_id
HAVING COUNT(*) >=8;
BEGIN
FOR r_group_discount IN c_group_discount
LOOP
UPDATE course
SET cost = cost * .95
WHERE course_no = r_group_discount.course_no;
DBMS_OUTPUT.PUT_LINE
('A 5% discount has been given to '||
r_group_discount.course_no||' '||
r_group_discount.description
);
END LOOP;
END;

MODE DESCRIPTION USAGE
IN   Passes a value into the program Read-only value
Constants, literals, expressions
Cannot be changed within the program’s default mode

OUT   Passes a value back from the program Write-only value
Cannot assign default values
Must be a variable
A value is assigned only if the program is successful

IN OUT    Passes values in and also sends values back Has to be a variable


Funksyalardan ferqli olaraq  prosedurlar deyer dondermeye biler ancaq lazim geldikde out ile deyer donderile biler

Meselem PL/SQL- de  in ve out istfdesine baxaq
CREATE OR REPLACE PROCEDURE ogrenci_bilgi(p_no IN NUMBER,
                                          p_ad OUT VARCHAR2,
                                          p_soyad OUT VARCHAR2,
                                          p_yuzluk_sistem_not IN OUT NUMBER)
IS
BEGIN
    SELECT  ad, soyad, not_ortalama * p_yuzluk_sistem_not
      INTO  p_ad, p_soyad, p_yuzluk_sistem_not
      FROM  ogrenci
     WHERE  no = p_no ;
END;

Gelin indi bu proseduru basqa bir blokda  cagiraq

DECLARE
    v_no            NUMBER := 1;
    v_ad            VARCHAR2 (10);
    v_soyad         VARCHAR2 (20);
    v_yuzluk_sistem_not NUMBER := 25;
BEGIN
    ogrenci_bilgi (v_no, v_ad, v_soyad, v_yuzluk_sistem_not);
    DBMS_OUTPUT.put_line ('No: ' || v_no);
    DBMS_OUTPUT.put_line ('İsim: ' || v_ad || ' ' || v_soyad);
    DBMS_OUTPUT.put_line ('Yüzlük sistemdeki not: ' || v_yuzluk_sistem_not);
END;


In ve out istfdesini artiq bu misaldan anlamis oldunuz yeqinki

Diqqet etdinizse  v_yuzluk_sistem_not –a deyer verilmisdi  25 olaraq ancaq  IN OUT oldugu ucun  prosedur daxilinde qiymeti deyisdi ve geri dondu







FUNKSYALAR

Prosedurlar kimidir ancaq mutleq return olmalidi

CREATE [OR REPLACE] FUNCTION function_name
(parameter list)
RETURN datatype
IS
BEGIN
<body>
RETURN (return_value);
END;


CREATE OR REPLACE FUNCTION show_description
(i_course_no course.course_no%TYPE)
RETURN varchar2
AS
v_description varchar2(50);
BEGIN
SELECT description
INTO v_description
FROM course
WHERE course_no = i_course_no;

RETURN v_description;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
RETURN(‘The Course is not in the database');
WHEN OTHERS
THEN
RETURN(‘Error in running show_description');
END;



PACKAGES
PACKAGE package_name
IS
[declarations of variables and types]
[specifications of cursors]
[specifications of modules]
END [package_name];


Developerler mentiqi olaraq  prosedurlari , funksyalari ve.s  bir yerde packagelerde tutmalari daha rahat olur

Package istfdesi ile
Istfde rahatlasir, dizayn qurulmasi asanlasir
Performans artrir

Packageler 2 yere ayrilir
1)spesifikasyon
2)body

Spesifikasyonu  bizim javada c# da bildyimiz interfaceler kimi dusune bilersiniz yeni  procedurlr funskayalar aldiglari parametrler var aa govde yoxdu
Govde hardadi ?
Govde 2)body dediyimiz hissede butunuyle tututlur

CREATE PACKAGE cust_sal AS
   PROCEDURE find_sal(v_id hr.employees.employee_id%type);
END cust_sal;

CREATE OR REPLACE PACKAGE BODY cust_sal AS
   PROCEDURE find_sal(v_id hr.employees.employee_id%TYPE) IS
   v_sal hr.employees.salary%TYPE;
   BEGIN
      SELECT salary INTO v_sal FROM hr.employees WHERE id = v_id;
      dbms_output.put_line('Salary : '|| v_sal);
   END find_sal;
END v_sal;





Gelin indi  packageden procedurumuzu cagiraq


/
DECLARE
   code hr.employees.employee_id%type := &cc_id;
BEGIN
   cust_sal.find_sal(code);
END;
/


 PL/Sql-de  tiplerin cevrilmesi
SELECT to_date('13.05.2015','DD.MM.YYYY') FROM dual;
13.5.2015
 
SELECT to_date('13.05.2015 09:40:12','DD.MM.YYYY HH24:MI:SS') FROM dual;
13.5.2015 09:40:12
 
SELECT to_date('13/05/2015 21:19:34','DD/MM/YYYY HH24:MI:SS') FROM dual;
13.5.2015 21:19:34
SELECT to_number('1234.34') FROM dual;
1234,34
SELECT to_char(12.45) FROM dual;
12.45
 
SELECT to_char(SYSDATE,'DAY') FROM dual;
MONDAY
 
SELECT to_char(SYSDATE,'DD-MM-YYYY DAY') FROM dual;
17-08-2015 MONDAY

PL/SQL string funksyalar
CHR:
Verilen ASCII kodun STRING qarsiligini verir.
SELECT(CHR(68) || CHR(65) || CHR(78)) FROM DUAL;
DAN
ASCII:
Verilen charin ASCII kodunu tapir.
Enter = CHR(13)
SELECT ASCII(‘A’) FROM DUAL;
SELECT ASCII(‘z’) FROM DUAL;
UPPER:
Verilen Stringi büyük harflerle yazir.
SELECT UPPER(‘Upper Fonksiyonunun çıktısı’) FROM DUAL;
UPPER FONKSIYONUNUN ÇIKTISI
LOWER:
Verilen Stringi kicik harflerle yazar.
SELECT LOWER(‘Lower Fonksiyasi’) FROM DUAL;
lower fonksiyasi
INITCAP:
verilen stringin her herfini boyuk herfle yazir.
SELECT INITCAP(‘initcap fonksiyasi’) FROM DUAL;
Initcap Fonksiyasi
TO_CHAR:
Verilen ededi ya da tarixi STRING -e
SELECT TO_CHAR(SYSDATE,’DD MM YYYY’) FROM dual;
SELECT TO_CHAR(12345) FROM dual;
CONCAT:
İki stringi birlesdirir.
SELECT CONCAT(‘Resul‘, ‘Rza’) FROM DUAL;
Ya da || ile
SELECT ‘Resul ‘||’Rza’ FROM DUAL;
LENGTH:
Verilen stringin  uzunlugunu .
SELECT LENGTH(‘nece herf’) FROM DUAL;
12
LPAD:
Verilen stringin soldan n xana olacaq şekilde x herf elave edir.(25 herf olana qeder)
SELECT LPAD(‘Resul rza’, 25, ‘X’) FROM DUAL;
XXXXXXXXXXXXXXXXResul rza
RPAD:
Verilen stringin sagdan n xana olacaq şekilde x herf elave eder.(25 herf olana qeder)
SELECT RPAD(‘
Resul rza’, 25, ‘X’) FROM DUAL;
Resul rzaXXXXXXXXXXXXXXXX
TRIM:
Stringin başında ve sonundaki boşluqları silir.
SELECT TRIM( ‘ Trim ‘) FROM dual;
Trim
LTRIM:
Stringin solundaki boşlugu silir.
SELECT LTRIM( ‘ LTrim ‘) FROM dual;
LTrim 
RTRIM:
Stringin sağındaki boşluqlari silir.
SELECT RTRIM( ‘ RTrim ') FROM dual;
RTrim
REPLACE:
bir stringi digeriyle evez edir
SELECT REPLACE(‘
Resul rza’,'e’,'r’) FROM dual;
Rrsul rza
REVERSE:
verilen stringi tersden yazir
SELECT REVERSE(‘Reverse’) FROM DUAL;
esreveR
SOUNDEX:
Verilen stringin fonetik benzerliğini temel alır.
SELECT * FROM TEST WHERE SOUNDEX(namecol) = SOUNDEX(‘CAR’);
– car sesine benzer kayıtlar..
DUMP:
Verilen stringin byte ve ascii özelliklerini verir.
SELECT DUMP(‘ABab’) FROM dual;
Typ=96 Len=4: 65,66,97,98
SUBSTR:
verilen stringden istenilen uzunlugu kesip alır, x DEN y ye kadar.
SELECT SUBSTR(‘SUBSTR’,1,3) FROM dual;
SUB
INSTR:
Verilen stringde istenen karakterin kaçıncı sırada geçtiğini bulur..
SELECT INSTR(‘instr fonksiyonu’,'s’, 1 ) FROM DUAL;
3. karakter s
NVL:
Verilen STRING ya da kolon değeri boşsa yeni değer atamak için kullanılır.
SELECT NVL(”,’X') FROM dual;
SELECT f.TABLE_NAME,f.CLUSTER_NAME,
NVL(f.CLUSTER_NAME,’CLUSTER YOK’) CLUSTER_DURUMU
FROM USER_TABLES f;
NVL2:
Verilen STRING ya da kolon değeri doluysa bir değer vermek, boşsa bir değer vermek için kullanılır.
SELECT f.TABLE_NAME,f.CLUSTER_NAME,
NVL2(f.CLUSTER_NAME,’CLUSTER VAR’,'CLUSTER YOK’)CLUSTER_DURUMU
FROM ALL_TABLES f;
DECODE:
DECODE(deger,a,b,x,y,z) şeklinde kullanılır,
yani değer a ise b,x ise y,bunların dışında ise z yaz demektir…
SELECT DECODE(TO_CHAR(SYSDATE,’DAY’),’SUNDAY’,'PAZAR’,'PAZAR DEĞİL’) FROM dual;
PLSQL Numerik Fonksiyonlar..
En sık kullanılan numerik fonksiyonları aşağıda örneklerle açıklamaya çalıştım.
Umarım faydalı olur..

ABS:
Verilen sayının mutlak değerini döndürür.
SELECT ABS(-19) FROM dual;
19
AVG:
Verilen kolonun aritmetik ortalamasını(average) almaya yarar.
SELECT AVG(salary) FROM hr.employess;
CEIL:
Verilen sayı küsüratlı ise bir üst tamsayıya yuvarlar, tamsayıysa kendini döndürür.
SELECT CEIL(12.23) FROM dual;
13
COUNT:
Sütun sayısını saydırmaya yarar.
SELECT COUNT(1) FROM hr.employess;
89
FLOOR:
Verilen sayı küsüratlı ise bir alt tamsayıya yuvarlar, tamsayıysa kendini döndürür.
CEIL fonksiyonunun tersini yapar.
SELECT FLOOR(12.34) FROM dual;
12
EXP:
e üssü n değerini döndürür.
SELECT EXP(11) FROM DUAL; — e üssü 11
59874,14171
MEDIAN:
Medyan(ortanca) almaya yarar..
SELECT MEDIAN(salary) from hr.employees where department = ‘Marketing’;

GREATEST:
Virgülle ayrılmış şekilde verilen sayılar arasından en büyüğünü geri döndürür.
SELECT GREATEST(1,2,3,4,9) FROM dual;
9
LEAST:
Virgülle ayrılmış şekilde verilen sayılar arasından en küçüğünü geri döndürür.
SELECT LEAST(-1,2,23,7,9,43,7777) FROM dual;
-1
MAX:
verilen sütundaki en büyük sayısal değeri döndürür.
–Örnekte en yüksek maaşı bulur
SELECT MAX(salary) FROM hr.employess;
MIN:
verilen sütundaki en küçük sayısal değeri döndürür.
–Örnekte en düşük maaşı bulur
SELECT MIN(salary) FROM hr.employess;
MOD:
Modüler aritmatik ile kalanı bulur.
–26 3e bölününce ne kalır..
SELECT MOD(26,3) FROM dual;
2
POWER:
Power üs almaya yarar.
– 5in 3. kuvvetini bulduralım.
SELECT POWER(5,3) FROM dual;
SIGN:
Verilen sayının işaretini döndürür.Negatif sayıysa -1, pozitif sayıysa 1, 0 sa 0 döndürür..
SELECT SIGN(-100) FROM dual;
-1
SELECT SIGN(65) FROM dual;
1
SELECT SIGN(0) FROM dual;
0
ROUND:
Verilen sayıyı istenen basamak kadar yuvarlamaya yarar.
Yuvarlanan sayı 5 DEN büyükse yukarı, küçükse aşağı yuvarlanır.
SELECT ROUND(192.36,1) FROM dual;
192,4
SELECT ROUND(3.14365,3) FROM dual;
3,144
Eğer basamak parametresi verilmezse sayıyı tam sayıya yuvarlar.
SELECT ROUND(22.67890) FROM dual;
23
SELECT ROUND(78.1256) FROM dual;
78
SQRT:
Verilen sayının karekökünü alır.
SELECT SQRT(64) FROM dual;
8
SUM:
Verilen sütundaki değerlerin toplamını döndürür.
–Maaşların toplamı
SELECT SUM(salary) FROM hr.employess;
TO_NUMBER:
to_number verilen değer eğer aslında sayı ise ve tipi NUMBER değilse bunu numbera dönüştürür.
Karakter tipinden NUMBER tipine dönüşüm yapar.
SELECT TO_NUMBER(’123.56′) FROM dual;
123,56
TRUNC:
Verilen sayıdan istenen kadar küsürat kesilebilir,yuvarlanmaz direk kesilir.
SELECT TRUNC(123.456,2) FROM dual;
123,45
Eğer ikinci parametre verilmezse küsürat komple atılır.
SELECT TRUNC(123.456) FROM dual;
123

SQL Tarih Saat Fonksiyonları

Plsql’de tarih ve saat işlemlerini örneklerle açıklamaya çalıştım..
Şu anki zaman;
SELECT SYSDATE FROM dual;
Şu anki zaman; ( systimestamp )
SELECT SYSTIMESTAMP FROM dual
Saat dilimi ve current tarih:
SELECT sessiontimezone, current_date FROM DUAL;
Saat dilimini değiştirmek:
ALTER SESSION SET TIME_ZONE = ‘-5:0′;
Tarihe gün eklemek, çıkarmak:
SELECT SYSDATE+10 FROM dual; –10 gün sonraki tarih
SELECT SYSDATE+45 FROM dual; –45 gün önceki tarih
Tarihi stringe çevirmek:
SELECT TO_CHAR(SYSDATE,’DD-MON-YYYY HH:MI:SS’) FROM dual;
Tarihin saat kısmını almak:
SELECT TO_CHAR(SYSDATE,’HH:MI:SS’) FROM dual;
SELECT TO_CHAR(SYSDATE,’HH24:MI:SS’) FROM dual;
Tarihin gün/ay/yıl kısmını almak:
SELECT TO_CHAR(SYSDATE,’DD.MM.YYYY’) FROM dual; –string döndürür
SELECT TRUNC(SYSDATE) FROM dual; –tarih döndürür
Tarihin yılını almak:
SELECT TO_CHAR(SYSDATE,’YYYY’) FROM dual;
Tarihin yılını yazıyla almak:
SELECT TO_CHAR(SYSDATE,’YEAR’) FROM dual;
Yılın hangi günü olduğunu bulmak: (1-365)
SELECT TO_CHAR(SYSDATE,’DDD’) FROM dual;
Tarihin hangi çeyreğe düştüğünü bulmak:(1,2,3,4 çeyrek)
SELECT TO_CHAR(SYSDATE,’Q') FROM dual;
Tarihin Ay numarasını bulmak:
SELECT TO_CHAR(SYSDATE,’MM’) FROM dual;
Tarihin gün numarasını bulmak:
SELECT TO_CHAR(SYSDATE,’DD’) FROM dual;
Tarihin ay adını bulmak:
SELECT TO_CHAR(SYSDATE,’MONTH’) FROM dual;
SELECT TO_CHAR(SYSDATE,’MON’) FROM dual;
Tarihin gün adını bulmak:
SELECT TO_CHAR(SYSDATE,’DAY’) FROM dual;
Tarihe Ay eklemek, çıkarmak:
SELECT ADD_MONTHS(SYSDATE,1) FROM dual;
SELECT ADD_MONTHS(SYSDATE,-4) FROM dual;
Ayın ilk gününü bulmak:
SELECT TO_CHAR(TRUNC(SYSDATE,’MM’),’DD.MM.YYYY’) FROM DUAL;
Ayın son gününü bulmak:
SELECT last_day(SYSDATE) FROM dual;
Bir sonraki X gününün tarihini bulmak:
SELECT NEXT_DAY(SYSDATE, ‘SALI’) FROM DUAL;
–Bir sonraki salının tarihi
Verilen stringi tarihe çevirmek:
SELECT TO_DATE(’21.10.2010′,’DD.MM.YYYY’) FROM dual;
Verilen tarihin yıl hafta numarasını bulmak(1-52):
SELECT TO_CHAR(SYSDATE,’IW’) FROM dual;
İki tarih arasındaki ay farkını bulmak:
SELECT MONTHS_BETWEEN(SYSDATE+365,SYSDATE-365) FROM DUAL;
Verilen tarihler arasındaki en büyüğünü bulmak:
SELECT GREATEST(SYSDATE, SYSDATE+10, SYSDATE+190) FROM DUAL;
Verilen tarihler arasındaki en küçüğünü bulmak:
SELECT LEAST(SYSDATE, SYSDATE-10,SYSDATE+190) FROM DUAL;
MAX ve MIN fonksiyonları tarihlerde de kullanılabilir.
Maximum tarihi bulmak:
SELECT MAX(last_ddl_time) FROM user_objects;
Minumum tarihi bulmak:
SELECT MAX(last_ddl_time) FROM user_objects;


Regular Expression ile Sayı Kontrolü

Geçen gün bir yazılımcı arkadaşımın böyle bir ihtiyacı oldu, concat edilerek üretilmiş bir referans alandaki metin değerlerini elde etmemiz gerekiyordu. Stringdeki numerik değerleri temizlemek istiyoruz, bunun için plsql regular expression ve plsql replace fonksiyonu kullanacağız.

Regular expression ile numerik alanların kontrolü:

SELECT (REGEXP_REPLACE('abcd12345ew rwer', '[0-9]')) FROM DUAL;
abcdew rwer
 
SELECT (REGEXP_REPLACE(kolon_adi, '[0-9]')) FROM tablo;

REPLACE fonksiyonu ile numerik alanların kontrolü:

Aynı işlemi plsql replace fonksiyonu ile de yapabilirdik,ama biraz daha uzunca ve zahmetli.
Bu sebeple regular expression kullanmak daha mantıklı ve regular expression daha esnek bir yapıya sahip.
SELECT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE
('abcd12345ew rwer',0,NULL),1,NULL),2,NULL),3,NULL),4,NULL),5,NULL),6,NULL),7,NULL),8,NULL),9,NULL) FROM DUAL;
 
abcdew rwer






Yorumlar

  1. Əladı! Təbriklər. çox gözəl izah etmisən. uğurların daimi olsun.

    YanıtlaSil
  2. salam!
    SQL de bir problemyaranib. Proqram 2016 ci il de Açılamda bu xətani verir. ADDITIONAL INFARMATION: A network-related or incttance-specific error occurred while establihing a connection to SQL Server. The server was not found was accesible

    YanıtlaSil
  3. və 2015 tarixini seçib açanda isə proqram açılır anca bir cedvelde bu xəta çıxır Could not find stored procedure 'PBalainek'

    YanıtlaSil

Yorum Gönder

Bu blogdaki popüler yayınlar

INGILIS DILI BUTUN ZAMANLAR

İNGİLİS DİLİNDƏ ƏN ÇOX İSTİFADƏ OLUNAN 2600 CÜMLƏ QƏLİBLƏRİ VƏ 6000 SÖZ