Hurriyet

31 Ocak 2014 Cuma

Oracle E-Business Suite: Request ID ile Concurrent Programı Çalıştıran Concurrent Manager'ın Bulunması

Request Id'si verilen bir concurrent programı çalıştıran concurrent manager'ın bulunması için aşağıdaki sorguyu kullanabiliriz. 

 select fcr.request_id req_id,  
  substr(fcq.concurrent_queue_name, 1, 20) queue,  
  to_char(fcr.actual_start_date,'hh24:mi') s_time,  
  substr(fcr.user_concurrent_program_name, 1, 60) name,  
  substr(fcr.requestor, 1, 9 ) u_name,  
  round((sysdate -actual_start_date) *24, 2) elap,  
  decode(fcr.phase_code,'R','Running','P','Inactive','C','Completed', fcr.phase_code) Phase,  
  substr(decode( fcr.status_code, 'A', 'WAITING', 'B', 'RESUMING',  
     'C', 'NORMAL', 'D', 'CANCELLED', 'E', 'ERROR', 'F', 'SCHEDULED',  
     'G', 'WARNING', 'H', 'ON HOLD', 'I', 'NORMAL', 'M', 'NO MANAGER',  
     'Q', 'STANDBY', 'R', 'NORMAL', 'S', 'SUSPENDED', 'T', 'TERMINATED',  
     'U', 'DISABLED', 'W', 'PAUSED', 'X', 'TERMINATED', 'Z', 'WAITING',  
     'UNKNOWN'), 1, 10)  
  from  
     apps.fnd_concurrent_queues fcq,  
     apps.fnd_concurrent_processes fcp,  
     apps.fnd_conc_req_summary_v fcr  
  where fcp.concurrent_queue_id = fcq.concurrent_queue_id  
   and fcp.queue_application_id = fcq.application_id  
   and fcr.controlling_manager = fcp.concurrent_process_id  
   and fcr.request_id = '&1'  
   order by request_id ;  


Ayrıca aşağıdaki örnek gibi  concurrent request id'sinde bulunan concurrent program id'sinden concurrent program ile ilgili daha fazla bilgi edinebiliriz.

 select * from apps.fnd_concurrent_requests where request_id='29928207';   
 select * from apps.fnd_concurrent_programs_tl where concurrent_program_id=52334 ; 

Concurrent request'imizin başarıyla çalışıp çalışmadığını görmek için ise fnd_concurrent_request tablosuna bakarız.

Not: Yukarıdaki sorguları bir concurrent request ile ilgili sorun çözme aşamasında kullanabiliriz.




29 Ocak 2014 Çarşamba

PL/SQL: Exception - Hata Yönetimi - PL/SQL Debuging - Handling PL/SQL Errors - PL/SQL Debuging

PL/SQL procedure'lari içerisindeki run-time hataları dizayn yanlışlıkları, donanım bozuklukları veya kodlama hataları gibi bir sürü nedenden dolayı ortaya çıkmaktadır. Bütün olabilecek hataları tahmin edemesek de, karşımızı çıkabileceklerini düşündüğümüz hataları işleyebiliriz.

Eğer programımızda hata kontrolü yoksa programın çalışması durur ve programın kontrolü işletim sistemine döner. Hata kontrolü varsa da program hatalara rağmen devam edebilir.

Exception Nedir?

 PL/SQL'de bir warning veya error durumunun ortaya çıkması "exception" olarak tanımlanır. Exception'lar ya kullanıcılar tarafından ya da sistem tarafından tanımlanırlar. Kullanıcı tarafından tanımlanan hatalar "raise" ifadesiyle başlatılırlar.

Çıkan hataları yönetmek için exception blokları yazarız. Exception ortaya çıktığında çalışma durup o bloğu kapsayan exception bloğuna gider.

Aşağıdaki örneğimizde standart bir hata bloğu tanımlamaktayız. Bu hata bloğunda tarih bilgisi çekilip tarih tablomuzun tek sütununa ekleriz. Eğer hata olursa da o ifadeyi kapsayan begin bloğundaki exception kısmına giderek oradaki hatalar arasından arama yapar. Örneğimizdeki hata diğer bütün hataları kapsadığı için eğer hata çıkarsa hemen o kısma girer ve rollback eder.

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

Önceden Tanımlı PL/SQL Exception'ları:

Sistem tarafından tanımlı hatalar ne zaman PL/SQL de bir hata olursa, o zaman tetiklenirler. Oracle hatalarının hepsinin bir hata numarası vardır; ancak bu hatalar adlarıyla kontrol edilirler.

Genel olarak ortaya çıkacak hataları "OTHERS" ifadesiyle kapsayabiliriz. Hatalar ortaya çıktığında SQLCODE ve SQLERRM fonksiyonları işimize yarayabilir. SQLCODE fonksiyonu SQL hata numarasını verirken, SQLERRM ise SQL hata mesajını vermektedir.

Ayrıca diğer adı olmayan hataları işlemek için  "pragma exception init" ifadesini kullanabiliriz. Aşağıdaki hatalar hata koduna tanımlı isim  verilmiş olan hatalardır.

ExceptionOracle Hata KoduSQLCODE 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

Özetle yukarıdaki tanımlı hatalarımız olabileceğini öngörüyorsak "exception when ..... then" boşluğuna o tanımlı hata ismini vererek o hatayı işleyebiliriz.

PL/SQL Hatalarını Tanımlamak:

PL/SQL'de kendi hatalarımızı tanımlayabiliriz. Yukarıdaki hatalar dışında karşımıza çıkabilecek olanları kendimiz tanımlayarak bunların işlenmesini sağlayabiliriz. Bu hatalar değişken tanımlama kısmında tanımlanırlar. Örnek olarak aşağıdaki tanımı verebiliriz.

Declare
  hata exception;

PL/SQL Hatalarını Bir SQL Hata Numarasıyla Eşleştirmek: 

Hataların bir isimle eşleştirilmesi için "pragma exception_init(exception_ismi,-Oracle_hata_numarası;" şeklinde bir ifade kullanmalıyız.

 Declare  
  hata exception;  
  pragma exception_init(hata,-60);  
 Begin  
  --"hata"'ya neden olabilecek işlemler  
 Exception  
  When hata then  
  Rollback;  
 End;  

Yukarıdaki örnekte ORA-00060 olan deadlock hatası gerçekleştiğinde bu hatayı bize "hata" olarak bir uyarı diye gösterecektir.

Programda Kendi PL/SQL Hatalarımızı Yaratmak:

RAISE_APPLICATION_ERROR procedure'ı ile kendi ORA- hatalarımızı yaratabiliriz. Bu şekilde bir hata olmasa bile, bizim iş akışımıza uygun olmayan bir durum yakaladığımızda programı durdurup uygulamaya mesaj gönderebiliriz. Burada hata numarası olarak verebileceğimiz sayı -20000 ile -20999 arasında olabilir. Hata mesajı da 2048 bytes uzunluğunda olabilir.

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

Yukarıdaki durumda program çalıştığında uyarı amaçlı bir ifade çalıştırmaktayız. İşlemlerimiz bir ORA hatasına neden olmasa da, kendimiz programımızı bu şekilde durdurabiliriz.

RAISE İfadesiyle Exception Üretmek:

Yukarıdaki başlığımızda nasıl exception üretebileceğimizi gördük. Bu exception işlemek istediğimizde "raise" ifadesini kullanabiliriz.  Bunun için ilk önce kendi hatamızı tanımlamamız gerekir.

DECLARE  
  stok_hatası exception;  
  stok number(5);  
 BEGIN  
   select sayı into stok from depo;  
   IF stok< 100 THEN  
    RAISE stok_hatası;  
   END IF;  
 EXCEPTION  
   WHEN stok_hatası THEN  
    raise_application_error(-20001,"Stok kalmamış durumdadır");  
 END;  

Örneğimizde ilk önce stok_hatası şeklinde hatamızı tanımlamaktayız. Sonra uygun zaman geldiği zaman eğer şartlar sağlanıyorsa stok_hatası şeklinde hatamız tetiklenir. Bu hata tetiklendiği zaman programın ne yapması gerektiğini exception bloğunda tanımlarız. Örneğimizde bunu raise_application_error procedure'u ile işlemekteyiz. Bu şekilde kısaca eğer hatayla karşılaşırsak bize "Stok kalmamıştır" şeklinde uyarı verecektir.

Bu şekilde kendi yarattığımız hatayı işlemiş oluruz.

Loop İçerisine Exception Tanımlamak:

Loop içerisine Exception tanımlama örneğimiz için aşağıdaki synoynm compile etme örneğimize bakabiliriz. Bu örnekte görebileceğimiz gibi exception tanımlayabilmemiz için, exception'ın ait olduğu bir begin end bloğu olmalıdır. Loop içerisinde begin.. end bloğu koyarak içeride yaşanabilecek herhangi bir hatanın farkında olabiliriz.

 declare  
 cursor a is select owner,object_name from dba_objects where object_type='SYNONYM' and status='INVALID' and owner!='PUBLIC';  
 z varchar2(100);  
 begin  
 for x in a  
 loop  
   
 begin  
 z:= 'alter synonym '|| x.owner || '.'|| x.object_name || ' compile;';  
 execute immediate z;  
 exception when others  
 then   
 dbms_output.put_line(SQLERRM || ' ' ||SQLCODE || ' ' || x.object_name);  
 end;  
 end loop;  
   
   
 end;  
 / 





27 Ocak 2014 Pazartesi

Oracle E-Business Suite: Yeni Bir Ürün Nasıl Lisanslanır? - How To Licence A New Product?

Oracle E-Business Suite'de yeni bir ürün alındığında, ilk yapılması gereken bu ürünün lisanslanmasıdır. Bunun için de Licence Manager'a gidilip kayıt yapılır.

Licence Manager "System Administrator" sorumluluğu altında "Oracle Applications Manager" menüsünde "Licence Manager" olarak yer almaktadır.


Licence Manager'a tıkladığımızda sistemimizde kayıtlı olan ürünleri ve dilleri görebiliriz.



Bu sayfada ya yeni kuracağımız dili ya da lisanslayacağımız ürünü seçeriz. Burada "Products'a" tıklarız. Sonra da "Licence a Component" seçeneğini seçeriz. Bunu seçtikten sonra karşımıza lisanslı olan veya lisanslanabilecek ürünler çıkar.

Buradan lisanslanacak ürün seçildikten sonra "Next" denir, ürün lisanslanmış olur. Ancak bu ürünün kullanılması için yeterli değildir. Bunun için de adadmin tooluna gidilerekten yeni ürünümüz için  1. seçenek altındaki "Generate Applications Files Menu"  içerisindeki

-Generate message files
-Generate forms files
-Generate report files
-Generate graphic files
-Generate product Jar files

işlemlerini yaparız.  Ertesinde de yine adadmin'den  "Compile/Reload Applications Database Entities Menu" içerisindeki

-Compile APPS schema
-Compile Menu Information
-Compile Flexfields

seçeneklerini çalıştırırız.

En sonunda adautocfg.sh komutunu çalıştırırız.


Refernaslar:

Understanding and Managing Licensing Options in Oracle E-Business Suite (Note 1639705.1)https://blogs.oracle.com/stevenChan/entry/understanding_license_manager_in_oracle




Oracle E-Business Suite: İlgili Concurrent Programın Request ID'si verilerekten SQL Trace Dosyasının Bulunması

prompt 
ACCEPT request prompt 'SQL Trace dosyasının bulunmasını istediğimiz concurrent programın request id'sini giriniz: ' 


COLUMN traceid format a8
COLUMN tracename format a80
COLUMN user_concurrent_program_name format a40
COLUMN execname format a15
COLUMN enable_trace format a12
SET lines 80
SET pages 22
SET head OFF

SELECT 
req.request_id
,req.logfile_node_name node
,req.oracle_Process_id
,req.enable_trace
,dest.VALUE||'/'||LOWER(dbnm.VALUE)||'_ora_'||oracle_process_id||'.trc' trace_filename
,prog.user_concurrent_program_name
,execname.execution_file_name
,execname.subroutine_name 
,phase_code 
,status_code
,ses.SID
,ses.serial#
,ses.module
,ses.machine
FROM 
fnd_concurrent_requests req
,v$session ses
,v$process proc
,v$parameter dest
,v$parameter dbnm
,fnd_concurrent_programs_vl prog
,fnd_executables execname
WHERE 1=1
AND req.request_id = &request
AND req.oracle_process_id=proc.spid(+)
AND proc.addr = ses.paddr(+)
AND dest.NAME='user_dump_dest'
AND dbnm.NAME='db_name'
AND req.concurrent_program_id = prog.concurrent_program_id
AND req.program_application_id = prog.application_id
AND prog.application_id = execname.application_id
AND prog.executable_id=execname.executable_id

24 Ocak 2014 Cuma

Oracle E-Business Suite: Adpatch ve/veya Adadmin için Defaultsfile Oluşturulması - Creating Defaultsfile For Adpatch and/or Adadmin

Oracle E-Business Suite'de patch ve maintenance işlerinde hızımızı arttırmak için ve adpatch ve adadmin komutlarını çalıştırdığımızda ortaya çıkan gereksiz soruları cevaplamamak için defaultsfile adı verilen bir text dosyası yaratabiliriz.

Defaultsfile ile bu komutların çalıştırılması sırasında kullanıcıya sorulan sorular bir text dosyasına yazılır. Sonrasında tekrar ihtiyacımız olma durumunda bu text dosyasını kullanaraktan gereksiz soruları atlayıp amacımıza daha kısa sürede oluşabiliriz.

Bunu yapma nedenimiz ise bazen bazı işleri, java jar dosyalarını tekrar compile etmemiz gerekmesi, Apps schema'sını tekrar compile etmemizin gerekmesi gibi  işleri defalarca yapma ihtiyacı duyma ihtimalimizdir. Ya da belirli işleri tekrar hiç beklemeden gerçekleştirmemiz gerekebilir.


Defaultsfile Nasıl Oluşturulur?

Defaultsfile dosyasını aşağıdaki komutla oluşturabiliriz. Adpatch veya Adadmin komutlarında kullanılabilinir.

adadmin defaultsfile=$APPL_TOP/admin/$TWO_TASK/defaultsfile 

Burada defaultsfile opsiyonu defaultsfile dosyasının nerede olduğunu gösterir. Bu dosya herhangi bir yer de bulunabilinir.

Bu komut çalıştırıldığında (adadmin veya adpatch), komut ilk önce belirtilen lokasyonda defaults file text dosyası bulunuyor mu diye bir kontrol eder. Eğer bulunmuyorsa soruları sorar. Bu sorulara verdiğimiz cevaplar defaultsfile text dosyasında kaydedilir. İşlemlerimiz yapıldığında bunlar kaydedilir.

Bu şekilde defaultsfile dosyası oluşturduğumuzda, bir dahaki sefere komut çalıştırıldığında önceden verdiğimiz cevaplara göre gerekli komutlar gerçekleştirilir. Yani bir düğmeye basmış gibi gerekli işlemi gerçekleştirebiliriz.


Defaultsfile'ın Adpatch ile Kullanılması:

İlk olarak adpatch komutumuzu defaultsfile parametresiyle birlikte kullanırız.

 adpatch defaultsfile=$APPL_TOP/admin/$TWO_TASK/defaultsfile 

Defaultsfile ile birlikte adpatch çalıştırıldıktan sonra bize Oracle Applications Patch'in nereye çıkartıldığını sorana kadar devam ederiz. Sorduğunda da "abort" yazıp çıkarız.

Komutumuzdan çıktıktan sonra örnek olarak patch 123456 için adpatch'imizi defaultsfile ile çalıştırmak istersek:

Bu patch'in bulunduğu dizini : $APPL_TOP/patch/123456
Kaç paralel workerla çalışması gerektiği: 10
Autopatch'in yazmasını istediğimiz log dosyasını: u123456.drv.log

yazmamız gerekir. Bunu yazınca da elimize aşağıdaki gibi bir kod oluşur.

 adpatch defaultsfile=$APPL_TOP/admin/$TWO_TASK/defaultsfile \  
 logfile=u123456.drv.log \  
 patchtop=$APPL_TOP/patch/123456 \  
 driver=u123456.drv \  
 workers=10 \  
 interactive=no  




23 Ocak 2014 Perşembe

Oracle Veritabanı: Bir Başka Kullanıcı Olarak Bağlanmak - Connecting As An Another User

Veritabanımızda bazen başka bir kullanıcı olarak giriş yapmamız gerekebilir. Bunun için Oracle tarafında bunu mümkün kılabilecek bir özellik bulunmaktadır. Bu özellik sayesinde veritabanına başka bir kullanıcıyla giriş yapabiliriz. Bunun için ilk olarak kullanıcımıza "connect through" yetkisini vermemiz gerekir. Bu yetki bir dba tarafından verilebilinir.

Örnek:

 alter user berke grant connect through oracle;  

Buradaki örneğimizde oracle kullanıcısına "berke" kullanıcısı olarak bağlanmak için yetki veririz.  Bu yetki verildikten sonra da oracle kullanıcısı kendi şifresini vererekten berke kullanıcısı olarak bağlanabilir. Bunun için de aşağıdaki syntax'ı kullanmalıdır.

 sqlplus oracle[berke]/oracle  

Bu şekilde oracle kullanıcısı berke olarak oracle şifresinin vererekten bağlanmış olur.

22 Ocak 2014 Çarşamba

Oracle Veritabanı:Oracle Net Listener - Oracle Servisler - Services

Servis Nedir?

Oracle veritabanı client'lara bir servis olarak tanıtılmaktadır. Bu servisler sayesınde veritabanına bağlanılır. Servisler listener'lara kaydedilir. Oradan da listenerlar tarafından uygun veritabanına bağlantısı sağlanır. Bir veritabanının birden fazla kayıtlı servisi olabilir. Veritabanındanki servis ismi spfile'da kayıtlıdır.

show parameter service_names 

Servisler sayesinde veritabanındaki yük bölümlenir. Her servisin ortak özellikleri bulunmaktadır. Örnek olarak Oracle E-Business Suite'de her sorumluluk için ayrı bir servis yaratılmaktadır. Bu servisler veritabanında kayıtlı olarak durmaktadırlar.

Servisler sayesinde iş yükleri tanımlayabiliriz, bunları yönetebiliriz, açıp kapatabiliriz. Buna göre ölçümler de yapabiliriz.

Veritabanındaki Servislerle İlgili Tablolar:


 DBA_SERVICES  
 ALL_SERVICES or V$SERVICES  
 V$ACTIVE_SERVICES  
 V$SERVICE_STATS  
 V$SERVICE_EVENT  
 V$SERVICE_WAIT_CLASSES  
 V$SERV_MOD_ACT_STATS  
 V$SERVICE_METRICS  
 V$SERVICE_METRICS_HISTORY  

Servis Yaratmak İçin: 

Servisleri DBCA ile,NetCA ile veya Oracle Enterprise Manager ile tanımlayabiliriz. Bundan başka service_names parametresini değiştirip DBMS_SERVICE.CREATE_SERVICE paketini çalıştıraraktan service'imizi yaratabiliriz.

Örnek :

 exec DBMS_SERVICE.CREATE_SERVICE('SERV1','SERV.oracle.com');

Yaratılan Servisin Başlatılması:

exec DBMS_SERVICE.START_SERVICE('SERV1');  

Servisin Durdurulması:

exec DBMS_SERVICE.STOP_SERVICE('SERV1');  

Servisin Silinmesi:

exec DBMS_SERVICE.DELETE_SERVICE('SERV1');  

Veritabanı Servisine Nasıl Bağlanılır?

Veritabanına bağlanmak için client'lar belirli bir bağlantı syntax'ı kullanmak zorundadırlar. Bu syntax'da veritabanının lokasyonu, bulunduğu makina, kullanılması gereken port  ve gerekli servis ismi yazılıdır. Bu bağlantı detayları tnsnames.ora dosyasında yazılıdır.

Aşağıdaki örnekte makina adı, servis adı, bağlantı portu, ve instance adı yer almaktadır.

sales=
 (DESCRIPTION= 
  (ADDRESS=(PROTOCOL=tcp)(HOST=sales-server)(PORT=1521)) 
  (CONNECT_DATA= 
     (SID=sales)
     (SERVICE_NAME=sales.us.example.com)
     (INSTANCE_NAME=sales)))

SID veritabanını, service adı  bağlanacağımız servisi, instance adı da veritabanı instance'ını belirtir. Rac veritabanı değilse tek instance vardır.

Tnsnames.ora dosyası client tarafına konaraktan uzaktaki makinanın veritabanı sunucusuna bağlanması sağlanır. Client tarafındaki makina bilgileri bu dosyadan alır.

Veritabanına bağlantı aşağıdaki gibi sağlanır:

Uygulama <=> Client(SQL*NET) <=>Network Bağlantısı TCP\IP <=>Listener <=>Veritabanı

Veritabanı kendisine gelen istekleri açık olan listenerdaki dinlenilen servislere göre veritabanına yönlendirir.

Network Konfigürasyon Dosyaları:


tnsnames.ora
Tnsnames.ora dosyası client ve server'larda bulunur. Burada bağlantı ifadeleri yer alır. Bu bağlantı ifadelerinde bağlanılacak servisler ve bağlantı adresleri bulunur.
sqlnet.ora
Bu dosya da client  ve server'da bulunur. Bu dosyada veritabanına erişimle ilgili çeşitli parametreler yer alır. Bu parametreler güvenlikle ilgili, loglamayla ilgili ya da bağlantıyla ilgili olabilir.
listener.ora
Bu dosya server'da bulunur. Bu dosyada dinlenilen veritabanı servisleri yer alır. Listener tarafından kullanılan çeşitli parametreler yer alır. 

TNS Net Service Name Hatası:

TNS Net Service Name hatasını eğer environment dosyamızda Oracle SID'miz bulunmuyorsa alabilir. Service Name'imiz resimde görüldüğü üzere lsnrctl'den de kontrol etmemize rağmen SQLPlus'a bağlanamıyorduk.

Bunun için kullanıcımızın home directory'sine gideriz. Orada da .bash_profile dosyasının içerisine ORACLE_SID,ORACLE_HOME parametrelerini ekleyip PATH'de sqlplus'un bulunduğu klasörü ekleriz. ".bash_profile" gizli bir dosya olduğu için "ls -al .bash_profile" şeklinde dosyayı bulabiliriz. Sonra da "vi .bash_profile"ile dosyanın içeriğini değiştirebiliriz.



Özetle:
.bash profile dosyasını aşağıdaki gibi güncelleriz.

ORACLE_HOME="/u01/install/PROD/11.2.0"
export ORACLE_HOME

ORACLE_SID="DENEME"
export ORACLE_SID


export PATH=$ORACLE_HOME/bin:$ORACLE_HOME/OPatch:$PATH


Yukarıdaki adımları attıktan sonra TNS Net Service Name is incorrectly specified hatasını düzeltmiş oluruz.

Oracle Veritabanı: Schema ile Kullanıcı Arasındaki Fark - Difference Between A Schema and User

Oracle veritabanında kullanıcılar ve kullanıcılarla aynı adla yaratılan schema'lar hakkında anlam karmaşası olabiliyor.

Schema'lar veritabanı objelerinin bir araya toplanmış haline denir. Bu schema'lar içerisinde tablolar, view'lar, sequence'lar, procedure'ler,synonyms'ler, index'ler ve database links'ler bulunur.

Kullanıcıların her birinin bir scheması bulunur. Her schema kullanıcı adıyla aynı isme sahiptir. Bir kullanıcı yaratıldığında aynı adla schema'da yaratılır.

Schema'ların tablespace'lerle ilgisi ise schema'lar kullanıcıların nesnelerini mantıksal olarak tutarken bunların fiziksel karşılıkları tablespace dediğimiz yerlerde tutulur. Birden fazla schema bir tane tablespace'de tutulabilir. Bununla birlikte her kullanıcının bir tane schema'sı olabileceğinden birden fazla kullancı aynı tablespace'i kullanabilir.

Bir kullanıcının objesine ulaşmak istediğinde tablespace adını değilde schema adını yazıp "." koyarız.

Örnek: select * from scott.emp  


21 Ocak 2014 Salı

Oracle Veritabanı: Trace Dosyaları - Trace Files

Trace dosyaları ADR(Automatic Diagnostic Repository)  bölgesinde tutulurlar. Burada dosyları tek tek bulmak için veritabanındaki tabloları sorgulayabiliriz. Aşağıdaki sorguları kullanırsak şu anki session'ımızla ilgili trace file'ımızı bulabiliriz. Bu session'la ilgil bilgiler aşağıdaki trace dosyasına yazılır.

SELECT VALUE FROM V$DIAG_INFO WHERE NAME = 'Default Trace File';

Şu an session'la ilgili bütün trace dosyaları için aşağıdaki sorguyu çalıştırabiliriz. Bu sorguyla trace dosyalarının bulunduğu klasöre gidebiliriz.

 SELECT VALUE FROM V$DIAG_INFO WHERE NAME = 'Diag Trace';  

Oracle Veritabanında trace dosyalarına yazan process'leri görmek için aşağıdaki sorguyu kullanabiliriz.

SELECT PID, PROGRAM, TRACEFILE FROM V$PROCESS;  

Trace dosyalarında karşılaşlan hataları görmek için aşağıdaki sorguyu çalıştırabiliriz.

select * from v$diag_vproblem;  

Oracle Veritabanı: (System Change Number) SCN Nedir - Ne İşe Yarar? - Nasıl Çalışır?

System Change Number(SCN) Nedir?

Scn data tutarlılığını sağlayan bir mekanizmadır. Scn database'in o anki durumu için verilen "unique" bir numaradır. Scn numarası her redo kaydı için bir tane verilir. Her transaction'dan sonra bir tane arttırılır. Ayrıca her "commit;" sorgusundan sonra verilir. Commit edilen her transaction log writer(LGWR) process'ini çağırır. O da SGA'daki redo log bufferındaki bilgileri online redo log dosyalarına yazar.

SCN Nasıl Bulunur?

10g ve sonrasında aşağıdaki sorgu kullanılabilinir.

 SELECT current_scn  
 FROM V$DATABASE;  

SCN Değişme Oranı Ne Kadardır?

v$log_history ile SCN değişim oranını kontrol edebiliriz. Ne kadar hızlı loglar switch ediyorsa ona göre database de büyük bir I/O  yoğunluğu vardır.

 select thread#, first_time, next_time, first_change# ,next_change#, sequence#,  
   next_change#-first_change# diff, round ((next_change#-first_change#)/(next_time-first_time)/24/60/60) rt  
 from (  
 select thread#, first_time, first_change#,next_time, next_change#, sequence#,dest_id from v$archived_log  
 where next_time > sysdate-30 and dest_id=1  
 order by next_time  
 )  
 order by first_time, thread#  


Yukarıdaki sorgu kullanıldığında bize log file switch'leri arasındaki farklar görülebilinir. Hangi zamanlarda ne kadar artış olduğu, ne zaman yoğunluk arttığını buradan görebiliriz.

Referanslar:
http://orainternals.wordpress.com/2012/01/19/scn-what-why-and-how/
http://oracledbascriptsfromajith.blogspot.com.tr/2009/05/understanding-scnsystem-change-number.html




Oracle Veritabanı: Oracle Error ORA-48913 Caught While Writing To Trace Files

ORA-48913 hatası trace file'ımız yeterince büyük olmadığı zaman karşılaştığımız bir hatadır. Alert loglarımızıda karşılaşabiliriz. Sistemimize yoğun bir yük geldiğinde bu yükle ilgili gerekli bilgiler loglanır ve trace file'a yazılır. Trace file'da yeterince yer olmadığında, bununla ilgili bir hata alert log'a yazılır. Bunu çözmemiz için Oracle'da bulunan bir parametreyi değiştirmemiz gerekir. Bu parametre max_dump_file_size'dir.

show parameter max_dump_file_size;  

Bu parametre kb cinsinden verilmektedir. Default değeri 10mb'dır. Bu parametreyi değiştirmek için, aşağıda tırnak içindeki kısma istediğimiz değeri yazabiliriz.

 alter system set max_dump_file_size='' scope=BOTH

Bu parametre dinamik bir parametredir. Hemen değiştirilebilinir.

19 Ocak 2014 Pazar

Oracle Veritabanı: Database Cloning - Veritabanı Klonlama

Database klonlamanın amacı DBA'lerin developer'lara hızlı bir test veya development ortamları hazırlanmasıdır. Klonlar genellikle production ortamından alınırlar.

Database hızlıca klonlamak için aşağıda sıralayacağımız adımların atılması gerekmektedir.

1.Adım:

Sqlplus'tan bağlanıp controlfile yedeği alınır. Controlfile yedeği trace directory'sine alınarak controlfile yaratılma script'i bir trace dosyasına yazılır.

 sqlplus / as sysdba  
   
 alter database backup controlfile to trace;  





Trace'e backup alındıktan sonra gerekli bilgiler bir trace dosyasına yazılır. Hangi trace dosyasına yazıldığını görmek için alert_SID.orcl içine bakılabilinir.

tail -100 alert_orcl.ora | grep "controlfile"  

 Backup controlfile written to trace file /oracle/product/11.2.0/diag/rdbms/orcl/orcl/trace/orcl_ora_3666148.trc  
 Completed: alter database backup controlfile to trace  







Eğer farklı bir lokasyona backup alınacaksa aşağıdaki gibi syntax kullanılır.

 alter database backup controlfile to trace as '/home/users/oracle/berke_deneme.ctl' 

Control File trace dosyasına alındıktan sonra bu trace dosyasında aşağıdaki gibi SQL'ler bulunur. SQL'ler içerisinde 2 durum belirtilmiştir. 1.sinde yani NORESETLOGS durumunda online log'lar elimizde olmalıdır ki bu klon durumunda elimizde bulunmaktadır. Bu durumda database'imizin adını değiştirmeden tutmuş oluruz.

2.durumda ise veritabanı RESETLOGS ile açılır. Ya loglar yoktur ya da veritabanı ismi değiştirilmek isteniyordur.

Her iki durumda da lokasyonlar yeni uygun konumlarına göre değiştirilmelidirler. Örneğin aşağıdaki sistemde "/u01/" ile başlayan lokasyonu uygun şekilde değiştiririz. Bunu bütün log lokasyonları ve diğer gerekli yerler için değiştiririz.

Bu işlemleri yaptıktan sonra durumumuza göre yani şeçimimize göre hangi kısmı istiyorsak kopyalayıp onu bir SQL dosyasına yerleştiririz.

Asagidaki dosya trace dosyamiza yazilan controlfile dosyasidir. Bu dosyadan 1 numarali ornegi aliriz ve icindeki orcl ile baslayan kisimlari yeni veritabanimizin adina gore degistiririz.

 --   Set #1. NORESETLOGS case  
 --  
 -- The following commands will create a new control file and use it  
 -- to open the database.  
 -- Data used by Recovery Manager will be lost.  
 -- Additional logs may be required for media recovery of offline  
 -- Use this only if the current versions of all online logs are  
 -- available.  
 -- After mounting the created controlfile, the following SQL  
 -- statement will place the database in the appropriate  
 -- protection mode:  
 -- ALTER DATABASE SET STANDBY DATABASE TO MAXIMIZE PERFORMANCE  
 STARTUP NOMOUNT  
 CREATE CONTROLFILE REUSE DATABASE "ORCL" NORESETLOGS ARCHIVELOG  
   MAXLOGFILES 16  
   MAXLOGMEMBERS 3  
   MAXDATAFILES 100  
   MAXINSTANCES 8  
   MAXLOGHISTORY 292  
 LOGFILE  
  GROUP 1 '/u01/app/oracle/oradata/orcl/redo01.log' SIZE 50M BLOCKSIZE 512,  
  GROUP 2 '/u01/app/oracle/oradata/orcl/redo02.log' SIZE 50M BLOCKSIZE 512,  
  GROUP 3 '/u01/app/oracle/oradata/orcl/redo03.log' SIZE 50M BLOCKSIZE 512  
 -- STANDBY LOGFILE  
 DATAFILE  
  '/u01/app/oracle/oradata/orcl/system01.dbf',  
  '/u01/app/oracle/oradata/orcl/sysaux01.dbf',  
  '/u01/app/oracle/oradata/orcl/undotbs01.dbf',  
  '/u01/app/oracle/oradata/orcl/users01.dbf',  
  '/u01/app/oracle/oradata/orcl/example01.dbf'  
 CHARACTER SET WE8MSWIN1252  
 ;  
 -- Commands to re-create incarnation table  
 -- Below log names MUST be changed to existing filenames on  
 -- disk. Any one log file from each branch can be used to  
 -- re-create incarnation records.  
 -- ALTER DATABASE REGISTER LOGFILE '/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2013_12_23/o1_mf_1_1_%u_.arc';  
 -- ALTER DATABASE REGISTER LOGFILE '/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2013_12_23/o1_mf_1_1_%u_.arc';  
 -- Recovery is required if any of the datafiles are restored backups,  
 -- or if the last shutdown was not normal or immediate.  
 RECOVER DATABASE  
 -- All logs need archiving and a log switch is needed.  
 ALTER SYSTEM ARCHIVE LOG ALL;  
 -- Database can now be opened normally.  
 ALTER DATABASE OPEN;  
 -- Commands to add tempfiles to temporary tablespaces.  
 -- Online tempfiles have complete space information.  
 -- Other tempfiles may require adjustment.  
 ALTER TABLESPACE TEMP ADD TEMPFILE '/u01/app/oracle/oradata/orcl/temp01.dbf'  
    SIZE 20971520 REUSE AUTOEXTEND ON NEXT 655360 MAXSIZE 32767M;  
 -- End of tempfile additions.  
 --  
 --   Set #2. RESETLOGS case  
 --  
 -- The following commands will create a new control file and use it  
 -- to open the database.  
 -- Data used by Recovery Manager will be lost.  
 -- The contents of online logs will be lost and all backups will  
 -- be invalidated. Use this only if online logs are damaged.  
 -- After mounting the created controlfile, the following SQL  
 -- statement will place the database in the appropriate  
 -- protection mode:  
 -- ALTER DATABASE SET STANDBY DATABASE TO MAXIMIZE PERFORMANCE  
 STARTUP NOMOUNT  
 CREATE CONTROLFILE REUSE DATABASE "ORCL" RESETLOGS ARCHIVELOG  
   MAXLOGFILES 16  
   MAXLOGMEMBERS 3  
   MAXDATAFILES 100  
   MAXINSTANCES 8  
   MAXLOGHISTORY 292  
 LOGFILE  
  GROUP 1 '/u01/app/oracle/oradata/orcl/redo01.log' SIZE 50M BLOCKSIZE 512,  
  GROUP 2 '/u01/app/oracle/oradata/orcl/redo02.log' SIZE 50M BLOCKSIZE 512,  
  GROUP 3 '/u01/app/oracle/oradata/orcl/redo03.log' SIZE 50M BLOCKSIZE 512  
 -- STANDBY LOGFILE  
 DATAFILE  
  '/u01/app/oracle/oradata/orcl/system01.dbf',  
  '/u01/app/oracle/oradata/orcl/sysaux01.dbf',  
  '/u01/app/oracle/oradata/orcl/undotbs01.dbf',  
  '/u01/app/oracle/oradata/orcl/users01.dbf',  
  '/u01/app/oracle/oradata/orcl/example01.dbf'  
 CHARACTER SET WE8MSWIN1252  
 ;  
 -- Commands to re-create incarnation table  
 -- Below log names MUST be changed to existing filenames on  
 -- disk. Any one log file from each branch can be used to  
 -- re-create incarnation records.  
 -- ALTER DATABASE REGISTER LOGFILE '/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2013_12_23/o1_mf_1_1_%u_.arc';  
 -- ALTER DATABASE REGISTER LOGFILE '/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2013_12_23/o1_mf_1_1_%u_.arc';  
 -- Recovery is required if any of the datafiles are restored backups,  
 -- or if the last shutdown was not normal or immediate.  
 RECOVER DATABASE USING BACKUP CONTROLFILE  
 -- Database can now be opened zeroing the online logs.  
 ALTER DATABASE OPEN RESETLOGS;  
 -- Commands to add tempfiles to temporary tablespaces.  
 -- Online tempfiles have complete space information.  
 -- Other tempfiles may require adjustment.  
 ALTER TABLESPACE TEMP ADD TEMPFILE '/u01/app/oracle/oradata/orcl/temp01.dbf'  
    SIZE 20971520 REUSE AUTOEXTEND ON NEXT 655360 MAXSIZE 32767M;  
 -- End of tempfile additions.  
 --  

Degisikliklerden sonra asagidaki bir sekil almasi gerekir.

 --  Set #1. NORESETLOGS case   
  --   
  -- The following commands will create a new control file and use it   
  -- to open the database.   
  -- Data used by Recovery Manager will be lost.   
  -- Additional logs may be required for media recovery of offline   
  -- Use this only if the current versions of all online logs are   
  -- available.   
  -- After mounting the created controlfile, the following SQL   
  -- statement will place the database in the appropriate   
  -- protection mode:   
  -- ALTER DATABASE SET STANDBY DATABASE TO MAXIMIZE PERFORMANCE   
    
  CREATE CONTROLFILE SET DATABASE "BERKE" NORESETLOGS ARCHIVELOG   
   MAXLOGFILES 16   
   MAXLOGMEMBERS 3   
   MAXDATAFILES 100   
   MAXINSTANCES 8   
   MAXLOGHISTORY 292   
  LOGFILE   
  GROUP 1 '/u02/app/oracle/oradata/berke/redo01.log' SIZE 50M BLOCKSIZE 512,   
  GROUP 2 '/u02/app/oracle/oradata/berke/redo02.log' SIZE 50M BLOCKSIZE 512,   
  GROUP 3 '/u02/app/oracle/oradata/berke/redo03.log' SIZE 50M BLOCKSIZE 512   
  -- STANDBY LOGFILE   
  DATAFILE   
  '/u02/app/oracle/oradata/berke/system01.dbf',   
  '/u02/app/oracle/oradata/berke/sysaux01.dbf',   
  '/u02/app/oracle/oradata/berke/undotbs01.dbf',   
  '/u02/app/oracle/oradata/berke/users01.dbf',   
  '/u02/app/oracle/oradata/berke/example01.dbf'   
  CHARACTER SET WE8MSWIN1252   
  ;   
  -- Commands to re-create incarnation table   
  -- Below log names MUST be changed to existing filenames on   
  -- disk. Any one log file from each branch can be used to   
  -- re-create incarnation records.   
  -- ALTER DATABASE REGISTER LOGFILE '/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2013_12_23/o1_mf_1_1_%u_.arc';   
  -- ALTER DATABASE REGISTER LOGFILE '/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2013_12_23/o1_mf_1_1_%u_.arc';   
  -- Recovery is required if any of the datafiles are restored backups,   
  -- or if the last shutdown was not normal or immediate.   
   
  -- Commands to add tempfiles to temporary tablespaces.   
  -- Online tempfiles have complete space information.   
  -- Other tempfiles may require adjustment.   
   
  -- End of tempfile additions.   
  --  

Yukaridaki gibi bir hale getirdikten sonra bunu bir sql dosyali uzanti olarak kaydederiz.

2.Adım

Klonu alınacak database kapatılır.

 shutdown database;  

Database kapatılmadan önce belirli bilgiler depolanması "best practice"'dir.

 spool '/home/users/oracle/berke_dbinfo'  
 select name,value from v$parameter where value like '%/oracle%';  
 show parameter dispatchers;  
 select name from v$datafile;  
 select * from v$logfile;  
 select member from v$logfile;  
 spool off;  

Controlfile'dan sonra pfile dosyasıda yedeklenir.

 create pfile from spfile;  















Pfile'ın yedeğini aldıktan sonra bu dosyanın içerisinde yeni alacağımız klonun durumuna göre gerekli değişiklikler yapılır; ama öncesinde pfile'ımızdan yeni sistemde kullanılmak üzere aşağıdaki komuttaki gibi yeni veritabanını adını yansıtacak şekilde bir pfile yaratırız.

 cp $ORACLE_HOME/dbs/initorcl.ora $ORACLE_HOME/dbs/initberke.ora 

Bu yarattığımız pfile dosyası yeni veritabanımızın pfile'ını temsil etmektedir.

 Yarattıktan sonra klasör adları değiştirilir. Belli başlı pfile'da değiştirilecek parametreler aşağıdaki gibidir.

 *.control_files   
 *.audit_file_dest  
 *.db_recovery_file_dest  
 *.diagnostic_dest  
 *.log_archive_dest_1=’LOCATION=’  

Bunları yeni lokasyonlarına göre adlandırdıktan sonra diğer adımlara geçeriz.

3.Adım

Bütün datafile'lar yeni makinadaki uygun yerlerine kopyalanır. Bire bir kopyalama yapılacağı için dosya dizinleri değişmeyecektir.

scp -r /oracle/product/oradata/orcl/* berke@berke_laptop:/u02/app/oracle/product/oradata/berke/.

Datafile adı değiştirilecekse ona göre klasör oluşturulması gerekir. Örneğin uzaktaki makinada klasör adı "berke" olarak değil "orcl" olarak değiştirilir ve öyle yaratılır.

Eğer uzaktaki makinada gerekli dizinler oluşturulmadıysa, oluşturulacak gerekli dizinler aşağıdaki komutlarla bulunur ve yaratılır.

 cd /oracle  
 find . -name *orcl*  
 find . -name *ORCL*  

Veritabanımızın ismiyle oluşturulmuş bütün klasörleri bulmak için ise:

 find . -type d -name *ORCL* 

Böylece database ismimizle yaratılmış olabilecek bütün klasörleri buluruz ve ona göre gerekli dizinleri yaratabiliriz.
ORACLE_HOME klasörümüzdeki binary dosyalarda taşınması gereken dosyalardır. Yani /u01/app/oracle/product/11.2.0/db_1'den yeni makinadaki yerlerine direk olarak kopyalanir.

İlk olarak aynı klasör yapısını oluştururuz. Aynı klasör yapısını oluşturmak için yukarıda find ile çıkarttığımız klasörleri mkdir -p komutuyla oluştururuz. Mkdir  -p komutu ile oluşturmamızın nedeni bütün ardı ardına gelen klasörleri arka arkaya yaratmasıdır.

4.Adım

3.Adımda eğer klasör adları değiştirilirse 1.adımda backup'ını aldığımız Controlfile'ı kopyalayıp editleriz. Oradaki controlfile yaratma script'ini alıp içinde belirli değişiklikler yaparız.

 CREATE CONTROLFILE SET DATABASE "ORCL" RESETLOGS  

Eğer aynı kalacaksa  dokunulmaz.

CREATE CONTROLFILE REUSE DATABASE "BERKE" NORESETLOGS  

5.Adım 

init_.ora dosyası kopyalanır. $ORACLE_HOME/dbs altına atılır.


scp init_BERKE.ora berke@berke_laptop:/u02/oracle/product/11.2.0/db_1/dbs/.

Bu parametre dosyasında eğer parametrelerde değişiklik yapıldıysa controlfile yerleri ile oynandıysa bu değişiklikler aynen yansıtılır.

6.Adim

Bu adima kadar yeni makinamizda sirasiyla:

1- Yeni makinamizda calistiracagimiz controlfile scriptini olusturduk.
2- Eski makinamizdaki veritabanini kapatip butun datafile`lari yeni makinamizdaki yerlerine tasidik. Ayrıca bütün binary dosyalarımızı yani $ORACLE_HOME altındaki dosyaları yeni makinamıza aktardık.
3- Pfile dosyamizi yeni lokasyonuna atip orada , datafile ve controlfile ile ilgili yaptigimiz degisiklikleri yansitacak islemleri yaptik.

Artik geriye veritabanimizi `startup nomount pfile=`init_berke.ora` ` komutuyla acip ilk adimda olusturdugumuz controlfile sql scriptini calistirmak kalir.

Sonrasinda veritabanini acabiliriz.



16 Ocak 2014 Perşembe

Linux / Unix Komutu: Mailx - Mailx Komutu Nedir - Nasıl Kullanılır - Unix Sistemden Mail Göndermek - Hem Body'li Hem Attachment'lı Mail Göndermek - How To Use Mailx Command

Mailx komutuyla Unix ve Linux ortamlarda mail atabiliriz. Mailx komutunu tek başına kullanmak biraz zahmetlidir. Bu şekilde kullanabilmek mümkünse de genelde diğer bir komut ile birleşik olarak kullanılır.

Mailx Komutu Kullanımı:


 mailx berke.oz@abc.com.tr  

ya da

 mailx  -s deneme berke.oz@abc.com.tr  

Mailx komutundaki -s ile mailini subject kısımını doldururuz. Burada deneme olarak belirlemiş bulunmaktayız. Yukarıdaki gibi mail komutumuzu oluşturduğumuzda bize subject sorusunu sormaz.ama -s parametresini kullanmadan basarsak bize subject sorar. Subject ile ilgili cevabı verdikten sonra mesajın içeriğini doldururuz. Mesajı yazmayı bitirdiğimizde 'ctrl + D' tuşuna basıp maili bitiririz.

Mailimizi kendimiz yazmayacaksak ve bir komutun çıktısını yazdırıp kendimize mail atmak istiyorsak, komutların çıktısını toptan bir log dosyasına yazıp kendimize ya attachment olarak ya da mail olarak attırabiliriz.

Aşağıdaki komut ile log dosyamızın içerisindeki bilgileri kendimize mail olarak "deneme" konu adıyla attırırız.

 more abc.log | mailx -s deneme berke.oz@abc.com.tr  

Attachment Olarak Mail Nasıl Gönderilir?

Mail'e attachment koyabilmemiz için başka bir komut kullanmaktayız Bu komut uuencode'dur. Attachment'ı dolduracağımız dosyayı önce okuturuz. Burada içinde bilgi olan abc.log dosyasını okuyup sonrasında uuencode ile binary dosyalara çeviririz. Attachment içerisinde nasıl bir isimle görülmesini istiyorsak uuencode'da o ismi yazarız. Ben burada "uuencode abc.log" şeklinde yazsam da oraya istediğimiz adı koyabiliriz. Bu ad attachment dosyasının adı olarak  mail'de gözükecektir. Sonrasında ise standart olarak mailx komutumuzu kullanırız.

more abc.log | uuencode abc.log | mailx -s deneme berke.oz@abc.com.tr

Attachment'lı Mail Nasıl Gönderilir?

Attachment'lı mail olarak göndermenin diğer konu başlığımızdan farkı mailimizin içerisinde attachment ve body olmasıdır. Üstteki mail komutunda dosya attachment olarak eklenir ancak body kısmına yazı yazılmaz.
Bu konu başlığımızda ise hem body de text göndermek için, hem de attachment olarak dosya göndermek nasıl olur onu göstereceğiz.

Bunun için en başta attachment dosyası hazırlanması gerekir. Attachment olarak göndermek istediğimiz dosyayı uuencode komutuyla birlikte attachment dosyasının ismini görmek istediğimiz şekilde formatlarız. Yani abc.log olarak sistemde bulunan dosyayı abcd.txt olarak mail'imize ekleriz.

uuencode abc.log abc.log > abcd.txt 

Sonrasında bu attachment dosyasını body kısmında görülmesi istenen dosyayla birleştiririz.

cat abc.log abcd.txt > birlestirilmis_text_adı.txt  

Bütün text'ler hazırlandıktan sonra mail gönderilmeye hazır hale gelir.

mailx -s "Statü Kontrolü" berke.oz@abc.com.tr < birlestirimis_text_adı.txt

Bu şekilde mail'imizin içeriğinde hem göndereceğimiz dosyanın text'ini, hem de kendisini attachment olarak göndermiş oluruz.

Mailx Komutunda From Kısmının Ayarlanması:

Mailx komutuna "-r" argümanını kullanaraktan from kısmını ayarlayabiliriz. Aşağıdaki örnekte "adapcctl.sh" adlı dosya içinde text olan herhangi bir dosya iken, -r argümanı "from" kısmını belirler -s "subject" kısmını belirlerken "to" kısmını da "abc" den sonraki mail adresi belirler.

more adapcctl.sh | mailx -r "deneme@deneme.com" -s "abc" ber@mailinator.com


Referans:
http://www.nyayapati.com/srao/2010/03/sending-email-with-a-body-and-attachment-from-unix/

14 Ocak 2014 Salı

Oracle E-Business Suite: Forms_compile.sh

Forms_compile.sh dosyası uygulama dosyaları içerisinde aşağıdaki dizinde yer alır.

 $AU_TOP/forms/US

Bununla birlikte diğer dillerin klasörlerinde de yer alır. Örnek olarak Türkçe için aşağıdaki dosyaya da gidebiliriz.

 $AU_TOP/forms/TR

Bu klasörlerin altında forms_compile.sh script dosyası bulunur. Bu dosyanın içerisine bakarsak aşağıdaki kodları görebiliriz.



Bu kodun içinde toptan değiştirmek istediğimiz modül adını yazaraktan içerisindeki bütün formları derleyebiliriz. Tabiki bu derleme işini yaptıktan sonra sistemimizde kurulu olan diğer dillerde de yapmalıyız. Örnek olarak US için derleme yapınca TR için de derleme yapmalıyız. Derleme yapılırken sistemin kapalı olması tavsiye edilir. (Daha fazla bilgi için forms compile ile ilgili yazımıza bakabiliriz.)

Oracle Veritabanı: Trigger'lar - Trigger Nedir? - Triggers - What are Triggers?

Trigger'lar insert, update ve delete ifadelerinden sonra çalıştırılan procedure'lardır. Bunlar tablolar üzerinde tanımlanırlar. Trigger'lar SQL ve PL\SQL ifadelerini içerebilirler ve diğer PL\SQL birimlerini çağırabilirler. Veritabanında saklanırlar. Belirli durumlarda çağırılırlar.

Trigger'ların procedurelardan farkı; trigger'lar Oracle tarafından tetiklenirken procedure'lar başka trigger'lar, application'lar veya kullanıcı tarafından çalıştırılabilirler.

Trigger'lar veritabanında tablolardan farklı bir yerde tutulurlar. Sadece tablolar üzerinde tanımlanabilirler. View'lar üzerine tanımlanamasalarda, view'ların üzerinde bir değişiklik yapılmaya çalışıldığında view'ın üzerine tanımlandığı tablolarda kaydedilmiş trigger'lar çalıştırılır.

Trigger'ın Tetiklendiği Durum Tipleri:

Herhangi bir DML(Data Manipulation Language) ifadesi : INSERT, UPDATE, DELETE
Herhangi bir DDL(Data Definition Language) ifadesi: CREATE, ALTER, DROP
Herhnagi bir veritabanı işleminde: Örnek olarak Logon, Logoff, Startup, Shutdown işleminde.

Trigger'ların Kullanım Amaçları: 

Trigger'lar ile DML ifadelerinin kullanımı kısıtlanabilir. Normalde bunun için role ve yetkiler kullanılırken, trigger'lar ile kullanıcının adına bakılmaksızın tablolar üzerine giriş çıkışlar kısıtlanır ve değişiklik yapılması düzenlenir.

Trigger'ların diğer genel kullanım alanlar:

-Otomatik olarak ilgili sütunlar için değerler üretmesi
-Uygun olmayan transaction'ları engellemek için
-Güvenlik katmanı oluşturmak için
-Loglama yapmak için
-Yapılan işlemlerle ilgili kayıt oluşturmak için
-Tablolar arasında eşleme ve eşitleme yapmak için
-Tablo erişimiyle ilgili bilgiler toplamak için

Not: Transaction Nedir?
Transaction olarak belirttiğimiz sorgular ya DML ifadeleridir ya da DDL ifadeleridir. DDL ifadeleri gönderildiğinde otomatik olarak commit edilirken, DML ifadeleri gönderildiğinde ertesinde commit veya rollback sorgularıda gönderilmelidirler ki transaction bitsin.

Trigger'lar ve Constraint'ler(Kısıtlar):

Kısıtlarda tablo içerisindeki veriler düzenlenir ve gelecek olan transactionlarda kısıtlar uygulanır. Yani tablo içerisindeki bütün verilerin ve gelecekde girilecek verilerin constraint'lere uygun olabilieceğini söyleyebiliriz.  Bir tabloya kısıt koyulduğunda içerideki datalarında buna uygun olması gerekir. Öte yandan trigger'lar tanımlandıkları zaman tablo içerisindeki verileri kontrol etmezler. Sadece sonradan girilen verileri kontrol ederler ve buna göre içerilerindeki kodları çalıştırırlar.

Trigger Zamanlama Tipleri:

1-Before: Trigger içerisindeki işlemler tablo üzerine gerçekleşecek işlemden önce çalışır.
2-After: Trigger yapılan işlemden sonra çalışır.
3-Instead of: SQL ifadesi yerine Trigger'ın içerisindeki ifadeler çalıştırılır. Bu işlem genelde view'lar üzerine işlem yapmak istendiğinde kullanılır. Böylece view'a ulaşılmak istendiğinde aslında onu oluşturan tablolar oluşturulur.

Statement Level Triggers ve Row Level Triggers:


Statement Level Triggers
Row Level Triggers
Standart Trigger tipidir.
“For Each Row” ifadesini kullanır.
Triggerı çalıştıran durum için çalıştırılır. Yani  eğer update,delete veya insert ifadesi birden fazla satırı değiştirse bile, trigger bir kere çalışır.
Row level trigger’da update,delete veya insert ifadelerinden herhangi birisinin değiştirdiği her satır için trigger çalıştırılır.
Herhangi bir değişikliğe neden olmasa da bir kere çalıştırılır.
Her hiçbir değişikliğe neden olmıyorsa tetiklenmez.

Trigger'ların Kısımları:

Bir trigger'ın basitçe 3 tane kısmı vardır. 
1-Trigger'ın hangi tablo üzerinde ne zaman çalışacağını gösteren kısım.
2-Trigger kısıtı - Ne zaman tetikleneceğini gösteren kısım.
3-Trigger aksiyonu - Bütün koşullar oluştuğunda trigger'ın hangi işlemleri yapacağını gösteren bölüm.

1-Trigger Olayı:

Trigger'ın çalışmasını  sağlayan ilk kısımdır. Burada hangi tablonun hangi sütununun üzerine tanımlı olduğu ve DML ifadesinin öncesinde mi sonrasında mı çalışacağını tanımlarız. 

Genel ifade:

[AFTER|BEFORE] [INSERT|UPDATE|DELETE] OF [KOLON_ADI] ON [TABLO_ADI]

Update ifadesinde birden fazla kolon adı belirtilebilinirken delete ve insert ifadelerinde bütün satır etkilendiği için tek bir kolon adı verilebilinir.

2- Trigger Kısıtı:

Trigger kısıtlarında boolean bir ifade verilir. Bu ifade doğru olduğunda ancak devamındaki kod çalıştırılır. 

WHEN (trigger_kısıt =true) 

3- Trigger Aksiyonu:

Trigger aksiyonu içinde SQL ifadeleri içeren bir PL\SQL procedure'udür. Trigger tetiklendikten ve trigger kısıtı doğru çıktıktan sonra trigger aksiyonu çalıştırılır. 

Koşullu İfadeler:

Koşullu ifadeler olarak belirttiğimiz anahtar kelimeler birden fazla trigger tipi kullanıldığı zaman işe yarayabilirler. Örnekte belirttiğimiz trigger birden fazla durumda(insert,update,delete) tetikleneceği için bunları ayırmak için içerisinde "DELETING", "INSERTING" veya "UPDATING" ifadelerinin kullanılması gerekir.


 CREATE OR REPLACE TRIGGER secure_emp BEFORE  
 INSERT OR UPDATE OR DELETE ON employees   
  BEGIN  
   IF (TO_CHAR(SYSDATE,'DY') IN ('SAT','SUN')) OR  
     (TO_CHAR(SYSDATE,'HH24')   
     NOT BETWEEN '08' AND '18') THEN  
    IF DELETING THEN RAISE_APPLICATION_ERROR(  
     -20502,'You may delete from EMPLOYEES table'||  
     'only during normal business hours.');  
    ELSIF INSERTING THEN RAISE_APPLICATION_ERROR(  
     -20500,'You may insert into EMPLOYEES table'||   
     'only during normal business hours.');  
    ELSIF UPDATING ('SALARY') THEN  
     RAISE_APPLICATION_ERROR(-20503, 'You may '||     'update SALARY only normal during business hours.');  
    ELSE RAISE_APPLICATION_ERROR(-20504,'You may'||  
     ' update EMPLOYEES table only during'||  
     ' normal business hours.');  
    END IF;  
   END IF;  
  END; 


DML Trigger Örneği:

Dml trigger'ımızda yaptığımız işleme göre trigger insert veya update işlemlerinde tetiklenmektedir. Tetiklendiğinde de tetikleyen ifadenin etkilediği bütün satırlar için belirli şartlara göre trigger içinde sorgular çalışır. Eğer belirleyen şartlara uymazsa hata verir. Raise_application_error çalıştığında içinde bulunduğu blok biter ve o blok hata döndürür.


 CREATE OR REPLACE TRIGGER restrict_salary  
 BEFORE INSERT OR UPDATE OF salary ON employees  
 FOR EACH ROW  
 BEGIN  
  IF NOT (:NEW.job_id IN ('AD_PRES', 'AD_VP'))  
    AND :NEW.salary > 15000 THEN  
   RAISE_APPLICATION_ERROR (-20202,  
    'Employee cannot earn more than $15,000.');  
  END IF;  
 END;/ 

OLD ve NEW Belirteçleri:


DML ifadeleri
:OLD
:NEW
Insert
Null
Yeni girilen değer
Update
Update yapılmadan önceki değer
Yeni update edilen değer
Delete
Silinmeden önceki değer
Null

OLD ve NEW Belirteç Örneği:

Burada verilen örnekte employees adlı tabloya yapılan her giriş için bu tabloyla ilgili loglama yapan tabloya yani audit_emp'e değerler girilir.


CREATE OR REPLACE TRIGGER audit_emp_values  
 AFTER DELETE OR INSERT OR UPDATE ON employees  
 FOR EACH ROW  
 BEGIN  
  INSERT INTO audit_emp(user_name, time_stamp, id,  
   old_last_name, new_last_name, old_title,  
   new_title, old_salary, new_salary)  
  VALUES (USER, SYSDATE, :OLD.employee_id,  
   :OLD.last_name, :NEW.last_name, :OLD.job_id,  
   :NEW.job_id, :OLD.salary, :NEW.salary);  
 END;  
 /  
   

Trigger'larda When ifadesi:

Trigger'lardaki when ifadesi trigger'ın çalışmasıyla ilgili bir koşul olarak kullanılabilir. Böylece her satır için trigger çalıştırıldığında trigger'ın içindeki ifadelerin uygulanıp uygulanmayacağını belirler.


 CREATE OR REPLACE TRIGGER derive_commission_pct  
 BEFORE INSERT OR UPDATE OF salary ON employees  
 FOR EACH ROW  
 WHEN (NEW.job_id = 'SA_REP')  
 BEGIN  
  IF INSERTING THEN  
   :NEW.commission_pct := 0;  
  ELSIF :OLD.commission_pct IS NULL THEN  
   :NEW.commission_pct := 0;  
  ELSE   
   :NEW.commission_pct := :OLD.commission_pct+0.05;  
  END IF;  
 END;  
 /  

Trigger'lardaki İşlem Sırası:

1-Önce "Before" triggerı varsa çalışır.
2-Sonra varsa "Before Row" triggerı kullanılır.
3-Ertesinde triggeri içerisinde yapılacak işlemler yapılır
4-"After Row" trigger'ı bulunuyorsa o çalıştırılır.
5-"After" triggerı tetiklenir.

Trigger'la ilgili Tablolar:


 user|all|dba_triggers



Örnekler:

1-
 CREATE TRIGGER rt BEFORE UPDATE OR DELETE OR INSERT ON sal   
 FOR EACH ROW BEGIN   
  stat.rowcnt := stat.rowcnt + 1;   
 END;   
 /   

Buradaki örneğimizde yarattığımız trigger, update,delete ve insert ifadelerinden sonra tablodaki her değer için bir değeri  bir arttırmaktadır.

2-
 CREATE TRIGGER at AFTER UPDATE OR DELETE OR INSERT ON sal   
 DECLARE   
  typ CHAR(8);   
  hour NUMBER;   
 BEGIN   
  IF updating   
  THEN typ := 'update'; END IF;   
  IF deleting THEN typ := 'delete'; END IF;   
  IF inserting THEN typ := 'insert'; END IF;   
    
  hour := TRUNC((SYSDATE - TRUNC(SYSDATE)) * 24);   
  UPDATE stat_tab   
   SET rowcnt = rowcnt + stat.rowcnt   
   WHERE utype = typ   
    AND uhour = hour;   
  IF SQL%ROWCOUNT = 0 THEN   
   INSERT INTO stat_tab VALUES (typ, stat.rowcnt, hour);   
  END IF;   
    
 EXCEPTION   
  WHEN dup_val_on_index THEN   
   UPDATE stat_tab   
    SET rowcnt = rowcnt + stat.rowcnt   
    WHERE utype = typ   
     AND uhour = hour;   
 END;   
 /

Buradaki örneğimizde de yine sütun belirtmeden tablomuza yapılan bir update,delete veya insert transaction'ınından sonra bir kere çalışmak üzere, her  trigger update için çalıştıysa bir kolon değeri update diye, diğer işlemler için de aynı şekilde çalışacak şekilde bir trigger yaratmaktayız. Bu örneğin genel amacı bir tabloya yapılan güncellemeleri loglamaktır.

3-


 CREATE OR REPLACE TRIGGER DBA.Trigger  
   BEFORE INSERT OR UPDATE  
   ON DBA.Logs  
   REFERENCING NEW AS NEW OLD AS OLD  
   FOR EACH ROW  
 DECLARE  
   TYPE session_type IS TABLE OF SYS.V_$SESSION%ROWTYPE;  
   
   session_tab  session_type;  
 BEGIN  
   IF (  UPPER (:NEW.UPDT_BY_OSUSER) ^= UPPER (:OLD.UPDT_BY_OSUSER)  
     OR UPPER (:NEW.UPDT_BY_MACHINE) ^= UPPER (:OLD.UPDT_BY_MACHINE))  
   THEN  
    RAISE_APPLICATION_ERROR (-20000, 'You Cannot Update UPDT_BY* columns!');  
   ELSE  
    SELECT s.*  
     BULK COLLECT INTO session_tab  
     FROM sys.v_$session s  
     WHERE s.audsid = USERENV ('SESSIONID') AND ROWNUM = 1;  
   
    :NEW.UPDT_BY_USER := SESSION_TAB (1).USERNAME;  
    :NEW.UPDT_BY_OSUSER := SESSION_TAB (1).OSUSER;  
    :NEW.UPDT_BY_MACHINE := SESSION_TAB (1).MACHINE;  
    :NEW.UPDT_TIMESTAMP := SYSDATE;  
   END IF;  
 END Trigger;  
 /  

Trigger'da var olan eski değerler ile tablonun içerisine aktarılacak yeni değerleri ayırt etmek için bir ifade bulunmaktadır.

"REFERENCING NEW AS NEW OLD AS OLD"

Bu kullanımla satırların hangi sütununa ekleme veya değişiklik yapılıyorsa :NEW veya :OLD şeklinde sütunun değişiklikten önceki ve sütunun değişiklikten sonraki hallerine referanslar yapılabilinir. Sütuna insert edilmeye çalışılan ve update edilmeye çalışılıan değer :NEW ile erişilebilinirken eski değere :OLD ile erişilebilinir. Bu procedure içerisinde eski değer yeni değerle karşılaştırılarak bir tutarsızlık varsa hata verdirilmektedir. Ertesinde de eğer hata çıkmaz ise kullanıcının girdiği değerler başka bir sütuna belirli değerlerle kaydedilir.

ORA-25001 Hatası:
ORA-25001 hatası view'lar üzerine trigger yaratmaya çalıştığımızda olmaktadır. Bu sorunun çözümü yaratılacak trigger'ı instead of ile trigger'ı ile değiştirmektir.