ORACLE PL/SQL – OBJECT TYPE -2 USING PL/SQL OBJECT “TYPE LIST”

Denizi bir testiye dökersen ne alır?

:Bir günün kısmetini –Mevlana

 

Merhaba
Önceki makalemizde object type’ları incelemiştik.(Buradan inceleyebilirsiniz) Bu makalemizde de object type’ların list özelliğini inceleyeceğiz
Herzaman ki gibi önce create. Hadi type ve type listimizi create scriptini yazalım.

---create type
create or replace type t_key_value as object 
(
key    varchar2(1000),
value  varchar2(4000)
)
/

 

-- create type (List<>)

create or replace type t_key_value_list as table of t_key_value;
/

 

type’ı referans alan bir liste oluşturmuş olduk aslında.
Şimdi bunları nasıl kullanacağız onu inceleyelim.
Kısa bir özet geçeyim.
Öncelikle bir for dongusu kuruyoruz. bu dondu 1 den 7ye kadar(7 de dahil) çalışacak.
bu for dongusunda gelen deger 1 ise pazartesi, 2 ise salı, 3 ise çarşamba… olacak şekilde
v_day diye bir değişkenimize değer atıyor. burada farklı olarak case kullanıyoruz(Buradan case kullanımını inceleyebilirsiniz)
buraya kadar fasa fiso….
Burdan sonra artık v_kv type’ımıza değer ataması yapıyoruz(Bu konuyuda buradan inceleyebilirsiniz)

type’ı doldurduktan sonra, v_kv_list’i extend edip, oluşturduğumuz type’ı index vererek atıyoruz.
daha sonra verdiğimiz bu index’ten geri okuyacağız

Burada iki for döngüsü var, biri yazar biri okur.
Her kodun yanına comment eklemeye çalışıyorum ki, sıfırdan başlayan insanlarda anlayabilsin diye
Faydalı olabilmek ümidiyle

 

-- Created on 14.05.2015 by Cevheri 

declare
  v_kv      t_Key_Value := t_Key_Value(null, null); -- oncelikle type degiskenimizi tanımlıyor ve initialize ediyoruz
  v_kv_list t_key_value_list := t_key_value_list(); -- key value type'ının listesini olusturmustuk onu tanımlıyoruz
  v_day     varchar2(10) := null; -- gunlerin isimlerini tutabilmek icin ayrı bir degisken tanımladık case fonksiyonu ile buna deger atayacağız
begin
  -- WRITE TYPE
  -------------------------------------------------
  -- Yedi kez donecek bir for döngüsü oluşturuyoruz
  dbms_output.put_line('------ Deger Atama  ------');
  for r in 1 .. 7 loop
    ------------------------
    -- gelen degere gore gunun ismi ilgili degiskene atilacak
    case r -- r for dongusundeki donus degerini alır o yüzden ayrıca bir degisken tanımlamaya gerek yok
      when 1 then
        v_day := 'PAZARTESI';
      when 2 then
        v_day := 'SALI';
      when 3 then
        v_day := 'CARSAMBA';
      when 4 then
        v_day := 'PERSEMBE';
      when 5 then
        v_day := 'CUMA';
      when 6 then
        v_day := 'CUMARTESI';
      when 7 then
        v_day := 'PAZAR';
      else
        v_day := null; -- olmaz ama her zaman siz kodunuzu yazarken ELSE'yi düşünün ve yazın...
    end case;
    ------------------------
  
    -- oncelikle type degiskenimi dolduruyoruz....  
    v_kv.key   := r;
    v_kv.value := v_day;
    ------------------------
    -- object type listimizi extend edip, içine type basacağız. 
    v_kv_list.extend;
    v_kv_list(v_kv_list.count) := v_kv; -- index vererek type'ı refere ediyoruz.
    ------------------------
  
    dbms_output.put_line('Atanan Key   :' || v_kv.key);
    dbms_output.put_line('Atanan Value :' || v_kv.value);
  end loop;
  
  dbms_output.put_line('-----------------------------');
  -- END WRITE-------------------------------------

  --**************************************************************

  -- READ TYPE-------------------------------------
  
  v_kv := null;
  dbms_output.put_line('-------  Deger Okuma   ------');
  -- hadi artık, doldurulan listelerin içindeki değerleri okuyalım
  for r in v_kv_list.first .. v_kv_list.last loop
  
    v_kv := v_kv_list(r); --- yine index vererek okuyoruz....
  
    dbms_output.put_line('Okunan Key   :' || v_kv.key);
    dbms_output.put_line('Okunan Value :' || v_kv.value);
  end loop;
  
  dbms_output.put_line('----------------------------');
  -- END READ-------------------------------------

end;

Selam ve Dua ile…

DBMS_APPLICATION_INFO – 2 (MODULE , ACTION)

Hiç görmediğim bir sevinçle; kapına geldim.
“Kim o” de yeter ki;
Sen kim olmamı istiyorsan o olmaya geldim –Mevlana

Merhaba

Daha önce dbms_application_info.client_info metodundan hatırlanacağı gibi, oracle session bilgilerini read ve set edebiliyorduk.

(Öncelikle bu yazıyı okumanızda fayda var DBMS_APPLICATION_INFO – 1   (CLIENT_INFO))

Oracle Client_Info haricinde session’ı setleyebileceğimiz iki alan daha veriyor; bunlarda Module_Name ve Action_Name bilgileridir. Bu iki değer için, Module Action bilgisinin parent’i diyebiliriz.

Örnek ile anlatalım,

Oracle ile çalışan bir Program yazdınız. İsmi: OracleIleCalisanProgramSoft. Programınız; oracle’a her connect olduğunuda “Module” alanını programınızın ismiyle setlersiniz. o sabit kalır. Sonra her farklı işlem yapmaya kalktığında da, action kısmını setlersiniz.

Örnek :

Sisteme Giriş Yaparken (loglama vs.. yaptığınızı varsayalım ve uzun sürdüğünü düşünelim.)

Module: OracleIleCalisanProgramSoft

Action  : Login

 

Muhasebe işlemleri yapmaya başladı

Module: OracleIleCalisanProgramSoft

Action  : Muhasebe

 

Raporlama almaya başladı (Topluca Fatura Hazırlıyor vs..)

Module: OracleIleCalisanProgramSoft

Action: Raporlama

 

Bu Sayede, hali hazırda program işlemlerine devam ederken bunu takip edebilecek, tablolara bir kaydın hangi aşamada atıldığını tutmak isterseniz de yine yazılmış bu action bilgisini read ederek kulllanabileceksiniz.

———————————————————————

Artık kod yazmaya devam edebilir (En sevdiğim tarafı)

Bunların nasıl yapılacağını yazalım.

-------
-------
declare
  -- ilk module atamalarımı yapıyorum.
  v_module        varchar2(4000) := 'ORACLE_ILE_CALISAN_HERHANGI_BIR_PROGRAM.EXE';
  v_active_module varchar2(4000) := null;

  -- ilk action atamalarımı yapıyorum.
  -- Bunu programın ilerleyen zamanlarında da değiştirebilir ve tekrar set_action yapabilirim.
  v_action        varchar2(4000) := 'PROGRAMIN_BIR_PARCASI';
  v_active_action varchar2(4000) := null;
begin
  -- Sessiondaki, module ve action bilgilerini okuyalım...
  dbms_application_info.read_module(module_name => v_active_module, action_name => v_active_action);

  -- Module bilgisi daha önce hiç atanmamışsa, atamasını yapıyoruz.
  if (v_active_module is null) then
    dbms_application_info.set_module(v_module, v_action);
    dbms_output.put_line('Sessiona Yeni atanan Module Bilgisi : ' || v_module);
  else
    -- varsa olan bilgiyi kullanabiliriz
    dbms_output.put_line('Sessiondaki Aktif Module Bilgisi : ' || v_active_module);
  end if;

  --Action bilgisi o an için atanmamışsa veya atamasını istediğimiz bilgiden farklıya
  if (v_active_action is null or v_active_action != 'BENIM_ISTEDIGIN_ACTION_BILGISI_DEGILSE') then
    dbms_application_info.set_action(action_name => v_action);
    dbms_output.put_line('Sessiona Yeni atanan Action Bilgisi : ' || v_action);
  else
    --Varsa ve benim istediğim bilgiyse direk okuyabiliriz....
    dbms_output.put_line('Sessiondaki Aktif Module Bilgisi : ' || v_active_action);
  end if;
end;
/
----------

dbms_application_info.set_module,

dbms_application_info.set_action,

dbms_application_info.read_module metodlarını inceledik.

Kolay gelsin dileklerimle…

 

Selam ve Dua İle…

 

DBMS_APPLICATION_INFO – 1 (CLIENT_INFO)

Ayağın kırıldı diye üzülme.
Allah sana belki kanat verecek.

Kuyu dibinde kaldın diye kırılma,
belki oradan bile bir kapı açılır.

Yusuf kuyudan sultan oldu –Mevlana

Merhaba

Bugünkü yazımız, PL/SQL Developer’ların sıklıkla kullandığı

DBMS_APPLICATION_INFO.READ_CLIENT_INFO  ve DBMS_APPLICATION_INFO.SET_CLIENT_INFO procedurleriyle alakalı olacaktır.

Öncelikle Client_Info nedir ondan bahsedelim.

select v.CLIENT_INFO, v.* from v$session v

Oracle, sistemdeki aktif sessionların bilgisini yukardaki bir view aracılığıyla bize sunmaktadır. sisteminizdeki aktif sessionların listesini bu sorgu ile görebilirsiniz. Her yeni session açıldığında, bu sessiona ait bir yığın bilgi de tutulur. sessionid leri, çalıştırdığı sqller, aktif-pasif durumu, bağlandığı bilgisiyarın bilgileri vb….

Bize de bu bilgilerden bazılarını yazma ve sonrasında okuma imkanı vermiştir. Yani siz oracle’da yeni bir session açtığınızda; oracle’ın bu topladığı veriler haricinde (sınırlı sayıda) session bilgisini kendiniz yönetebilirsiniz.

(Normalde bu işler için GLOBAL TEMPORARY TABLE kullanmak daha doğrudur; ama hazır elimizde olan alanı yönetmek daha kolay olduğu için bu alanlarıda kullanmakta da fayda var. GLOBAL TEMPORARY TABLE hakkında da bir yazı yazmak nasip olursa, orada bu konuyu daha detaylı anlatırım. )

Şimdi set ve read metodlarının örnek kullanımını inceleyelim.

--
declare
  -- atamasını yapacağımız user bilgisini set ediyoruz
  v_client_info        varchar2(4000) := 'TEST_USER'; 

  -- daha önce ataması yapılan user bilgisi varsa bu değişkene atayacağız
  v_active_client_info varchar2(4000) := null; 
begin
  
  -- read metodu ile client info bilgisini değişkene atıyoruz
  dbms_application_info.read_client_info(client_info => v_active_client_info);
  
  -- eğer daha önce atama yapılmamışsa, atama yapacağız; varsa direk yazdıracağız
  if (v_active_client_info is null) then
    dbms_application_info.set_client_info(client_info => v_client_info);
    dbms_output.put_line('Sessiona atanan User Bilgisi : '||v_client_info);
  else
    dbms_output.put_line('Sessiondaki Aktif User : '||v_active_client_info);
  end if;
end;
--

kod ilk çalıştığında çıktı şu şekilde := Sessiona atanan User Bilgisi : TEST_USER

eğer aynı sessionda tekrar çalıştırırsak :=  Sessiondaki Aktif User : TEST_USER

 

Bunu ister database’in logon_triggger’ında isterseniz; yazdığınız arayüzün open session metodunda yazın ve session açık olduğu sürece, istediğiniz yerden bu bilgilere ulaşın.

HAZIR BİR GLOBAL DEĞİŞKEN

Kolay Gelsin Dileklerimle

 

Selam ve Dua ile…

 

Oracle Bağlı Kullanıcıları(session) Topluca düşürme işlemi

Sisteminizde yüzlerce bağlı kullanıcı olabilir.

Bazen bir alter, create vb..  Database’de bir işlem yapmak istersiniz;

ama bağlı kullanıcılar sizi LOCK konumuna düşürür ve db işlemleriniz kısıtlanır.

Sisteme bağlanıp bunları tek tek KILL ederiz. 198. useri tam KILL  etmişizdir ki….

27. user sisteme tekrar bağlanmıştır.  Neyse uzatmayalım ve hadi bunları topluca nasıl KILL ederiz ona bakalım.

 

declare
  cursor c_kill is
    select inst_id, sid, serial#
      from gv$session t
     where upper(username) = 'TEST'
        or upper(osuser) = 'TEST-USER'
        or upper(machine) = 'TEST-PC'
        or program = 'Toad.exe'; --vb.... buraya bir çok seçenek eklenebilir.
begin
  for r in c_kill loop
    --örnek Kullanım alter system kill session 'sid,serial#';
    execute immediate 'alter system kill session ' || '''' || r.sid || ',' || r.serial# ||'''';
  end loop;
end;

 

 

Oracle Logon Trigger

Bir Database'in olmazsa olmazı,
Loglama, Güvenlik...

Bu yazımızda oracle logon triggerından bahsedeceğiz. 
Yapı itibariyle diğer triggerlardan çokta farkı yok aslında(syntax aynı) 
sadece tablo yerinde database'e bağlandığında bir iş yapmasını istiyoruz. 
Yazımı aşağıdaki şekildedir.

create or replace trigger trg_logonDB
after logon on database
declare
  Cursor c is
    Select * from v$session where audsid = userenv('sessionid');

  cp         c%rowtype;
  rp         logonhistory%rowtype;
  v_ipadress varchar2(1000);
  v_host     varchar2(1000);
  v_module   varchar2(1000);
begin
  -- Cevheri 13.09.2014
  -- db'ye login olan tum userlari takip edelim

  open c;
  fetch c
    into cp;
  close c;

  -- oracle'in kendi baglantilarini es gecelim..... 🙂
  if cp.type != 'BACKGROUND' then

      ---------------------------------------------------------------------
      select SYS_CONTEXT('USERENV', 'IP_ADDRESS') into v_ipadress from dual;
      select SYS_CONTEXT('USERENV', 'HOST')       into v_host     from dual;
      select SYS_CONTEXT('USERENV', 'module')     into v_module   from dual;



      ---------------------------------------------------------------------
      -- Rapor icin log tutmaya gerek yok
      -- Forms icin log tutmaya gerek yok
      if upper(v_module) not in('FRMWEB.EXE', 'REPORTS.EXE') then

        rp.kullaniciad      := cp.username;
        rp.username         := cp.osuser;
        rp.ip_address       := v_ipadress;
        rp.host_name        := v_host;
        rp.operating_system := v_module;
        rp.language         := userenv('LANG');
        rp.time_zone        := null;
        rp.logondate        := sysdate;
        rp.logoutdate       := null; -- logof triggerinda dolduracağız 🙂
        rp.dbusername       := user;
        rp.sid              := cp.sid;

        insert into logonhistory values rp;
        commit;

      end if;
  end if;

-- Güvenlik kısmına geçelim. 🙂 istediğine izin ver 
begin
  if sys_context('userenv', 'ip_address') ='192.168.1.1' then
    DbHata('Giriş Yasak .....');
  elsif sys_context('userenv', 'session_user') in ('PATRON') then
    DbHata('Şifreniz Bloke Olmuş :(');
  end if;
end;


exception
  when others then
    DbHata(sqlerrm);
end tr_logonDB;

işte bu kadar... logon triggerımız artık db'ye kim bağlanırsa bağlansın
loglama, güvenlik işlemlerini yapacaktır.