Database dbid:
databasein dbisi database bazında controlfile ve spfile dönüşü yapacaksanız ve recovery catalog kullanmıyorsanız önemlidir.
Datafileların yapısı ve fiziksel yerleride bizim için önemlidir. unutulmamalıdırki controlfile database'in fiziksel yapısını tutar
Controlfile record keep time parameterisi defualt özelliği 7 gündür. Recovery catalog olmayan bir databasede rman yedek bilgileri controlfile saklanır. O yüzden bu parametereye dikkat etmemiz gerekir.
Controlfile autobackup özelliğini açmak son derece önemlidir. Bu sayese controlfile ilgilendiren her türlü değişiklikte yedeği otomatik alınır.
Daha ufak backup pieces daha etkilidir.
Rman dbms_backup_restore packagenı kullanır.
7/24 çalışmak için database archive moda almak gerekir.
SQL>shutdown immediate
SQL>startup mount;
SQL>alter database archivelog;
SQL>alter database open;
rmande controlfile otomatik backup alması
RMAN> connect target /
RMAN>Show all;
RMAN>configure controlfile autobackup on ;
basit bir backup örneği burada archiveloglarında yedeği alınacaktır.
RMAN> run
{
Allocate channel d1 type disk format
‘/u01/backup/orcl_full_%T_%s_%p.bkp’;
Backup database plus archivelog;
}
RMAN> list backup summary;
report komutları sayesinde veritabanından rman bazında sorgulama yapabiliriz.
RMAN> report schema;
Report of database schema
List of Permanent Datafiles
===========================
File Size(MB) Tablespace RB segs Datafile Name
---- -------- -------------------- ------- ------------------------
1 620 SYSTEM YES /u02/oradata/orcl/system01.dbf
2 255 UNDOTBS1 YES /u02/oradata/orcl/undotbs01.dbf
3 460 SYSAUX NO /u02/oradata/orcl/sysaux01.dbf
5 100 Zekeriya NO /u03/oradata/orcl/zekeriya.dbf
6 200 HTML_DB NO /u02/oradata/orcl/html_db_01.dbf
7 50 FLOW_1 NO /u02/oradata/orcl/FLOW_1.dbf
8 100 COLLAB07 NO /u03/oradata/orcl/deneme.dbf
List of Temporary Files
=======================
File Size(MB) Tablespace Maxsize(MB) Tempfile Name
---- -------- -------------------- ----------- --------------------
1 41 TEMP 32767 /u03/oradata/orcl/temp07.dbf
Örnek seneryo.
Controlfile 2 numarayı ve zekeriya.dbf kaybettik diyelim.
Shutdown abort ile database kapatıp.
Diğer çalışan controlfilelardan bir tanesini 2.controlfile lokasyonuna kopyalayıp rename ederiz.
daha sonra database'i mount duruma alırız.
run
{
allocate channel d1 type disk format
'/u01/backup/orcl_%T_%s_%p.bkp';
restore datafile '/u03/oradata/orcl/zekeriya.dbf';
}
daha sonra
sqlplus “/ as sysdba”
SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-01113: file 5 needs media recovery
ORA-01110: data file 5: '/u03/oradata/orcl/zekeriya.dbf'
SQL> recover database ;
Media recovery complete.
SQL> alter database open;
Database altered.
databasein açılması için butun fileların SCN numaraların aynı olmaları gerekir. O yuzdende recover yapmak zorundayız.
Controlfile yedekten dönme similasyonu
eğer controlfilelarımızı kaybetmissek database en iyi nomount duruma gelir.
RMAN> list backup of controlfile;
RMAN> restore controlfile from autobackup to
‘/yeni/control02.ctl’;
yada
controlfile spesific bir zaman dönmek
RMAN> restore controlfile from autobackup until time
“to_date(’04/12/2008 08:00:00’,’MM/DD/YYYY
HH24:MI:SS’);
Otomatik backupdan değilde spesific bir backuptan controlfile dönmek
RMAN> Run
{ allocate channel device type disk;
restore controlfile
from ‘/u01/oradata/backup/backup_piece_name’;
}
Block corruption seneryosu
–ORA-01578: ORACLE data blockcorrupted (file # 5, block # 24222)
–ORA-01110: data file 5:‘/u03/oradata/orcl/zekeriya.dbf’
SQL> select * from v$database_block_corruption;
FILE# BLOCK# BLOCKS
CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
5 24222 1 0 FRACTURED
Bu corruption hangi blocktan kaynaklanıyor ve hangi objelere karsılık geliyor?
SELECT tablespace_name, segment_type, owner,
segment_name
FROM dba_extents
WHERE file_id = 5
and 24222 between block_id AND block_id + blocks - 1
yapılması gereken rman komutu
run
{
allocate channel d1 type disk format
'/u01/backup/orcl_%T_%s_%p.bkp';
blockrecover datafile 5 block 24222;
}
Farklı bir lokasyona inmek
RMAN> run
{
allocate channel d1 type disk format
'/u01/backup/orcl_%T_%s_%p.bkp';
set newname for datafile 5 to '/u03/oradata/orcl/zekeriya.dbf';
restore database ;
switch datafile all;
recover database ;
}
Select * from v$datafile;
Restore işlemini PLSQLden yapmak
SQL> alter database datafile
'/u03/oradata/orcl/zekeriya.dbf' offline
DECLARE
devtype varchar2(256);
done boolean;
BEGIN
devtype:=sys.dbms_backup_restore.deviceAllocate
sys.dbms_backup_restore.restoreSetDatafile;
sys.dbms_backup_restore.restoreDatafileTo(dfnumber=>6,
toname=>'/u03/oradata/orcl/zekeriya.dbf');
sys.dbms_backup_restore.restoreBackupPiece(done=>done,
handle=>'/u01/backup/orcl_20081208_15_p.bkp',
params=>null);
sys.dbms_backup_restore.deviceDeallocate;
END;
üzerine
SQL> recover datafile '/u03/oradata/orcl/collab07.dbf';
Media recovery complete.
SQL> alter database datafile
'/u03/oradata/orcl/zekeriya.dbf' online;
Database altered
Nevar ne yoksa geri dönmek. ilk önce database nomount duruma alınır.
RMAN> run
{
allocate channel d1 type disk format
'/u01/backup/orcl_%T_%s_%p.bkp';
restore controlfile;
restore database;
}
$ sqlplus "/ as sysdba“
SQL> alter database mount;
SQL> recover database using backup
controlfile;
SQL>alter database open resetlogs
RMAN işimizin durumunu gösteren sql komutu
select l.SID, l.SERIAL#, l.CONTEXT, l.SOFAR, l.TOTALWORK,
round(l.SOFAR/l.TOTALWORK*100,2) "% Complete",
s.client_info
from v$session_longops l,
v$session s,
v$process p
where l.opname like 'RMAN:%'
and l.totalwork > 0
and p.addr = s.paddr
and s.sid = l.sid
and s.serial# = l.serial#
and l.opname not like 'RMAN: aggregate%'
and s.client_info like 'id=rman_%'
SQL> /
SID SERIAL# CONTEXT SOFAR TOTALWORK % Complete CLIENT_INFO
----- ------- ------- ---------- ---------- ---------- ------------------------------
47 2201 1 492180 492180 100.00 id=rman_rac_full_backup,rman channel=t1
30.07.2008
28.07.2008
Maliyetleri Düşürme Advance compress
Table compress yöntemi oracle 9i r2 den beri olan bir yöntemdir. Bu yöntemi bulk operasyonlarda kullanmabiliyorduk.
DML Performans için olumlu bir katkısı olduğunu söylemek oldukça güçtür. daha çok read only datalar için düşünebiliriz. fakat tabiki büyük sorgularda daha az IO neden olması ve buffer cache daha ideal kullanması son derce önemlidir.
Sıkıstırma özellikleri tablo ve partition seviyesinde yapılabiliyordu.
Advanced Compress özeliği ise 11g ile beraber gelmiştir.Bu özellik sayesinde Structred datayı unstructered datayı,backup datalarını ve network datalarını sıkıstırmamız mumkundur.
Böylece maliyetlerimizin ve kullanmak zorunda olduğumuz kaynaklarada azalma mümkündür.
Yerden kazanmak.memeoryden kazanmak ve network hattından kazanmak son derece kolay hale gelecektir.
Su anda ortaya çıkan sonuçlara bakıldığında
Yer olarak en az 3 katı bir kazanç
Table scan durumlarında 2.5 katı bir kazanç
DML permossında ise %5in altında bir kötüleşme mümkündür. Buda bize artık günümüzde OLTP sistemlerde bile tablolarımızı sıkıstırma yapabileceğimiz anlamına gelmektedir.
Securefiles üzerinde getirilen deduplicate özelliği sayesinde Duplicate dataların tek fiziksel kopyası saklanması mumkundur. LOB dataların yeni türü olan securefile nın bu özelliği oldukça önemlidir.
Tablo partition ve sub partition seviyesinde uygulanabilir. Yazma ve kopyalama operasyonlarında inanılmaz performans artısı sağlar.
Data pump Compress özelliği sayesinde metadata compress özelliği zaten 10gde vardı. Biz şimdi 11g veri tabanında hem metada hemde data kısmında sıkıstırma yapabiliyoruz.
Rman de sıkıstırma algoritması değiştirilmiş ve %40 daha iyi bir sonuc alınmıştır.En önemlisi ise recovery sırasında decompress gerektirmemesidir.Disk ve tape içinde kullanılabilir.
Özetlemek gerekirse
-Büyük tabloları(taransaction yada warehouse)
-Bütün data tiplerini
-İnanılmaz okuma performası(full table scan)
-Ve 2ile 4 katı yer kazancı compress neden tercih etmemiz gerktiğinin göstergesidir.
DML Performans için olumlu bir katkısı olduğunu söylemek oldukça güçtür. daha çok read only datalar için düşünebiliriz. fakat tabiki büyük sorgularda daha az IO neden olması ve buffer cache daha ideal kullanması son derce önemlidir.
Sıkıstırma özellikleri tablo ve partition seviyesinde yapılabiliyordu.
Advanced Compress özeliği ise 11g ile beraber gelmiştir.Bu özellik sayesinde Structred datayı unstructered datayı,backup datalarını ve network datalarını sıkıstırmamız mumkundur.
Böylece maliyetlerimizin ve kullanmak zorunda olduğumuz kaynaklarada azalma mümkündür.
Yerden kazanmak.memeoryden kazanmak ve network hattından kazanmak son derece kolay hale gelecektir.
Su anda ortaya çıkan sonuçlara bakıldığında
Yer olarak en az 3 katı bir kazanç
Table scan durumlarında 2.5 katı bir kazanç
DML permossında ise %5in altında bir kötüleşme mümkündür. Buda bize artık günümüzde OLTP sistemlerde bile tablolarımızı sıkıstırma yapabileceğimiz anlamına gelmektedir.
Securefiles üzerinde getirilen deduplicate özelliği sayesinde Duplicate dataların tek fiziksel kopyası saklanması mumkundur. LOB dataların yeni türü olan securefile nın bu özelliği oldukça önemlidir.
Tablo partition ve sub partition seviyesinde uygulanabilir. Yazma ve kopyalama operasyonlarında inanılmaz performans artısı sağlar.
Data pump Compress özelliği sayesinde metadata compress özelliği zaten 10gde vardı. Biz şimdi 11g veri tabanında hem metada hemde data kısmında sıkıstırma yapabiliyoruz.
Rman de sıkıstırma algoritması değiştirilmiş ve %40 daha iyi bir sonuc alınmıştır.En önemlisi ise recovery sırasında decompress gerektirmemesidir.Disk ve tape içinde kullanılabilir.
Özetlemek gerekirse
-Büyük tabloları(taransaction yada warehouse)
-Bütün data tiplerini
-İnanılmaz okuma performası(full table scan)
-Ve 2ile 4 katı yer kazancı compress neden tercih etmemiz gerktiğinin göstergesidir.
22.07.2008
özel index tipleri
-Funtion-based index:
Fonksiyonları index olarak kullanabilmemizi sağlar.
Cost base optimizerda etkilidir. Bu sayede fonksiyonlar where sartında yer aldıgında plan onları
pass geçmez.
- Bitmap Join index:
Tek indexin birden fazla tablodan oluşmasına izin verir.
Performans artısına önemli katkısı olabilir.
- İndex only table:
Tabloyu indexe özel organizasyonda yaratmaktır.
Ciddi performans artısı sağlayabilir.
Primary key şartı vardır.
Funtion Base index:
İndexler experrsionda yeralabilir.
SUBSTR, UPPER gibi örnekler için idealdir.
Oracle parametrelerinde
query_rewrite_enabled = true
query_rewrite_integrity = trusted
örnek olarak Create index func_fname_idx on emp (UPPER(first_name));
Enterprise edition versiyonunda bulunur.
SQL Functionlarında tavsiye edilir.
range scans
Functions in order by clauses
İkinci bir index olarakda index Organized Tables (IOT) da kullanılabilir.
Örnek karşılaştırma
SQL> select count(*) from patients
2 where upper(last_name) like 'CA%';
Elapsed: 00:00:02.34 *
Execution Plan
------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF 'PATIENTS‘
*function-based index kullanmamış
SQL> create index patients_fn1 on 2 patients(upper(last_name));
SQL> select count(*) from patients 2 where upper(last_name) like 'CA%';
Elapsed: 00:00:00.91*
Execution Plan-------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 INDEX (RANGE SCAN) OF 'PATIENTS_FN1'
* Elapsed time 1 saniyenin altında.
- Bitmap join index
CREATE TABLE EMP1 AS SELECT * FROM SCOTT.EMP;
CREATE TABLE DEPT1 AS SELECT * FROM SCOTT.DEPT;
ALTER TABLE DEPT1 ADD CONSTRAINT DEPT_CONSTR1 UNIQUE (DEPTNO);
Ufak bir tabloda bitmap join index örneği
CREATE BITMAP INDEX EMPDEPT_IDX
ON EMP1(DEPT1.DEPTNO)
FROM EMP1, DEPT1
WHERE EMP1.DEPTNO = DEPT1.DEPTNO
/
SELECT /*+ INDEX(EMP1 EMPDEPT_IDX) */ COUNT(*)
FROM EMP1, DEPT1
WHERE EMP1.DEPTNO = DEPT1.DEPTNO;
COUNT(*)
---------------
14
Elapsed: 00:00:00.67
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 BITMAP CONVERSION (COUNT)
3 2 BITMAP INDEX (FULL SCAN) OF 'EMPDEPT_IDX'
- İndex organized Table
Oracle 8den beri vardır.
İndex datasını tablo datasının dışında ayrı bir storage alanda tutmak yerine tablo üzerinde tutar.
Primary key yaratıldığı anda oluşur.
Full index scan primary key datasının dönmesi demektir.
Normel indexlere göre eşitlik ve aralık aramalarda daha hızlıdır.Yeterki I/O işleri fazla olmasın.
OLAP/DWH/VLDB ortamları için idealdir.
Fakat ROWIDs olmadığından IOTları distributed transactions veya advanced replication
kullanamayız.
CREATE TABLE test8
( doc_code CHAR(5),
doc_type INTEGER,
doc_desc VARCHAR(512),
CONSTRAINT pk_docindex PRIMARY KEY (doc_code,doc_type) )
ORGANIZATION INDEX TABLESPACE data_tbs1
PCTTHRESHOLD 20 INCLUDING doc_type
OVERFLOW TABLESPACE data_tbs2
/
11g ile beraber
•11g virtual columns indexleme
•11g invisible indexes
•Bitmap join for IOT
yöntemleride mevcuttur.
Fonksiyonları index olarak kullanabilmemizi sağlar.
Cost base optimizerda etkilidir. Bu sayede fonksiyonlar where sartında yer aldıgında plan onları
pass geçmez.
- Bitmap Join index:
Tek indexin birden fazla tablodan oluşmasına izin verir.
Performans artısına önemli katkısı olabilir.
- İndex only table:
Tabloyu indexe özel organizasyonda yaratmaktır.
Ciddi performans artısı sağlayabilir.
Primary key şartı vardır.
Funtion Base index:
İndexler experrsionda yeralabilir.
SUBSTR, UPPER gibi örnekler için idealdir.
Oracle parametrelerinde
query_rewrite_enabled = true
query_rewrite_integrity = trusted
örnek olarak Create index func_fname_idx on emp (UPPER(first_name));
Enterprise edition versiyonunda bulunur.
SQL Functionlarında tavsiye edilir.
range scans
Functions in order by clauses
İkinci bir index olarakda index Organized Tables (IOT) da kullanılabilir.
Örnek karşılaştırma
SQL> select count(*) from patients
2 where upper(last_name) like 'CA%';
Elapsed: 00:00:02.34 *
Execution Plan
------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF 'PATIENTS‘
*function-based index kullanmamış
SQL> create index patients_fn1 on 2 patients(upper(last_name));
SQL> select count(*) from patients 2 where upper(last_name) like 'CA%';
Elapsed: 00:00:00.91*
Execution Plan-------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 INDEX (RANGE SCAN) OF 'PATIENTS_FN1'
* Elapsed time 1 saniyenin altında.
- Bitmap join index
CREATE TABLE EMP1 AS SELECT * FROM SCOTT.EMP;
CREATE TABLE DEPT1 AS SELECT * FROM SCOTT.DEPT;
ALTER TABLE DEPT1 ADD CONSTRAINT DEPT_CONSTR1 UNIQUE (DEPTNO);
Ufak bir tabloda bitmap join index örneği
CREATE BITMAP INDEX EMPDEPT_IDX
ON EMP1(DEPT1.DEPTNO)
FROM EMP1, DEPT1
WHERE EMP1.DEPTNO = DEPT1.DEPTNO
/
SELECT /*+ INDEX(EMP1 EMPDEPT_IDX) */ COUNT(*)
FROM EMP1, DEPT1
WHERE EMP1.DEPTNO = DEPT1.DEPTNO;
COUNT(*)
---------------
14
Elapsed: 00:00:00.67
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 BITMAP CONVERSION (COUNT)
3 2 BITMAP INDEX (FULL SCAN) OF 'EMPDEPT_IDX'
- İndex organized Table
Oracle 8den beri vardır.
İndex datasını tablo datasının dışında ayrı bir storage alanda tutmak yerine tablo üzerinde tutar.
Primary key yaratıldığı anda oluşur.
Full index scan primary key datasının dönmesi demektir.
Normel indexlere göre eşitlik ve aralık aramalarda daha hızlıdır.Yeterki I/O işleri fazla olmasın.
OLAP/DWH/VLDB ortamları için idealdir.
Fakat ROWIDs olmadığından IOTları distributed transactions veya advanced replication
kullanamayız.
CREATE TABLE test8
( doc_code CHAR(5),
doc_type INTEGER,
doc_desc VARCHAR(512),
CONSTRAINT pk_docindex PRIMARY KEY (doc_code,doc_type) )
ORGANIZATION INDEX TABLESPACE data_tbs1
PCTTHRESHOLD 20 INCLUDING doc_type
OVERFLOW TABLESPACE data_tbs2
/
11g ile beraber
•11g virtual columns indexleme
•11g invisible indexes
•Bitmap join for IOT
yöntemleride mevcuttur.
21.07.2008
Oracle index genel bakış
İndexlerler ilgili genel problemler:
- Yetersiz indexler
- Çok fazla indexler
- Yanlış tip indexler
- Çok büyük indexler
Indexlere ihtiyaçımız olduğunu nasıl anlayabiliriz.
- Query dönüş hızınız düşükse
- Çok fazla full table scan varsa
- db file scrattered read sayısı fazla ise
- Çok fazla fiziksel okuma çok az logical okuma varsa
- Buffer busy wait eventleri fazla ise
- Çok fazla temporary alan kullanılıyorsa
Yetersiz indexleri nasıl düzeltiriz
- Query analiz edip full table scanlare bakarız
- Hash ve sort merge joinleri incereliz
- Full table scan yapan tablolardaki indexlerimiz olup olmadığını kontrol ederiz.
- yeni index yaratırız.
Çok fazla indexler hangi problemlere yol açar
- Yavaş yapılan insert update ve delete işlemlerine
- Hangi indexin kullanılacağına karar verilmemesine
- Çok fazla fiziksel yazma işlemine
- uzun parse sürelerine
Örnek seneryo
Bir tablomuz var bu tablomuzda 5 adet bitmap index,1 adet primary key ve lookup index bulunuyor.950.000 kayıdı bu tabloya insert süresi 35 dakika sürüyor.
Çözüm.
insex monitorin yaparak hangi indexlerin kullanduğını görürüz. V$sql_plan bakarak execution planı inceleriz ve kullanılmayan indexlere drop ederiz.
Sadece primary key index kalır. 950.000 kayıt ekleme süresi 1.5 dakikaya iner.
Eğer elimizdeki indexler full table scan neden oluyor yada uzun parse zamanı ortaya çıkıyorsa yada skip scan meydana geliyorsa indexlerimizin doğru olduğunu söylememiz mümkün değildir.
Gerekli index tipleri
- 10g database datawarehouse işlemleri için bitmap join indexleri FK kolonlarda tercih edelim.
- 9i DWH işlemlerdinde concat btree indexler olabilir.
- OLTP işlemlerinde bitmap indexler extra yoğun lock sorununa yol açar.
- Full table scan yapılıyorsa function base index kullanmayalım.
Çok üyük indexler yol açtığı problemler.
- Çok fazla db sequential read problemi
- Çok fazla fiziksel IO
- Çok fazla logical IO
Yarında yazıma özel index tipleri ile devam edeceğim.
- Yetersiz indexler
- Çok fazla indexler
- Yanlış tip indexler
- Çok büyük indexler
Indexlere ihtiyaçımız olduğunu nasıl anlayabiliriz.
- Query dönüş hızınız düşükse
- Çok fazla full table scan varsa
- db file scrattered read sayısı fazla ise
- Çok fazla fiziksel okuma çok az logical okuma varsa
- Buffer busy wait eventleri fazla ise
- Çok fazla temporary alan kullanılıyorsa
Yetersiz indexleri nasıl düzeltiriz
- Query analiz edip full table scanlare bakarız
- Hash ve sort merge joinleri incereliz
- Full table scan yapan tablolardaki indexlerimiz olup olmadığını kontrol ederiz.
- yeni index yaratırız.
Çok fazla indexler hangi problemlere yol açar
- Yavaş yapılan insert update ve delete işlemlerine
- Hangi indexin kullanılacağına karar verilmemesine
- Çok fazla fiziksel yazma işlemine
- uzun parse sürelerine
Örnek seneryo
Bir tablomuz var bu tablomuzda 5 adet bitmap index,1 adet primary key ve lookup index bulunuyor.950.000 kayıdı bu tabloya insert süresi 35 dakika sürüyor.
Çözüm.
insex monitorin yaparak hangi indexlerin kullanduğını görürüz. V$sql_plan bakarak execution planı inceleriz ve kullanılmayan indexlere drop ederiz.
Sadece primary key index kalır. 950.000 kayıt ekleme süresi 1.5 dakikaya iner.
Eğer elimizdeki indexler full table scan neden oluyor yada uzun parse zamanı ortaya çıkıyorsa yada skip scan meydana geliyorsa indexlerimizin doğru olduğunu söylememiz mümkün değildir.
Gerekli index tipleri
- 10g database datawarehouse işlemleri için bitmap join indexleri FK kolonlarda tercih edelim.
- 9i DWH işlemlerdinde concat btree indexler olabilir.
- OLTP işlemlerinde bitmap indexler extra yoğun lock sorununa yol açar.
- Full table scan yapılıyorsa function base index kullanmayalım.
Çok üyük indexler yol açtığı problemler.
- Çok fazla db sequential read problemi
- Çok fazla fiziksel IO
- Çok fazla logical IO
Yarında yazıma özel index tipleri ile devam edeceğim.
14.07.2008
oracle database changePerm.sh
Makinanıza 10g R2 database yükledikten sonra Unixte owner accountu dışında oracleda operating sistemden herhangi bir userla işlem yapmak istersek karsımıza çıkan problemi changePerm.sh scriptini çalıştırarak halledebiliriz.
örnek vermek gerekesirse zekeriya userı operaing sistemde oracle log on olmak isterse karşısına çıkan sen oracle oinstall gruba dahil değilsin yada dba grubuna dahil olmadığının için bağlanması mümkün olmaz. Bu problem linux ve unixlere özgüdür. Örnek olarak sqlplus bağlanmak diyebiliriz.
$ sqlplusksh: sqlplus: not found
Bunun amacı daha relax bir hak yönetimi sağlamakdır.
Başka bir deyişle butun clientların oracle Home ulaşıp çalışmalarını sağlamaktır.
Bu pakati çalıştırdığımızda
-n Do you wish to continue (y/n) [n]:yFinished running the script successfullyPlease see /tmp/changePerm_err.log for errors and /tmp/changePerm.log for the log of events
That modified the permissions and solved the problem. The developer is now able to execute SQL*Plus.
Ve bu işlem yaklaşık 10 dakika sürer.
örnek vermek gerekesirse zekeriya userı operaing sistemde oracle log on olmak isterse karşısına çıkan sen oracle oinstall gruba dahil değilsin yada dba grubuna dahil olmadığının için bağlanması mümkün olmaz. Bu problem linux ve unixlere özgüdür. Örnek olarak sqlplus bağlanmak diyebiliriz.
$ sqlplusksh: sqlplus: not found
Bunun amacı daha relax bir hak yönetimi sağlamakdır.
Başka bir deyişle butun clientların oracle Home ulaşıp çalışmalarını sağlamaktır.
Bu pakati çalıştırdığımızda
-n Do you wish to continue (y/n) [n]:yFinished running the script successfullyPlease see /tmp/changePerm_err.log for errors and /tmp/changePerm.log for the log of events
That modified the permissions and solved the problem. The developer is now able to execute SQL*Plus.
Ve bu işlem yaklaşık 10 dakika sürer.
11.07.2008
11g yeni guvenlik özellikleri
11gdeki yeni transparent data encryption özelliklerine tablespace encryptionla başlayabiliriz.
create tablespace enc ENCRYPTION
datafile 'c:\oracle\homes\server\oradata\dj11\enc.dbf' size 100M
autoextend on next 10M maxsize 2048M
default storage(ENCRYPT)
extent management local autoallocate;
create tablespace enc_a256 ENCRYPTION USING 'AES256'
datafile 'c:\oracle\homes\server\oradata\dj11\enc_a256.dbf' size 1M
autoextend on next 1M maxsize 10M
default storage(ENCRYPT)
extent management local autoallocate;
eğer wallet open değilken sorgulama yaparsak
select count(*) from encu.employee
*
ERROR at line 1:
ORA-28365: wallet is not open
Kolon sifrekelemede olan overhead tablespace ustunde olmaz. bunun sebebide databasein block size 8192 olsun 8 bytes 3des ve 16 bytes aes herhangi bir extra storage yuku getirmemesidir.
Şöyle bir karşılastırma yapıldığında ilk testimiz tablespace encryption olsun, şifreli ve şifresiz tabloları yukleyelim.tablespace bazında yapılan şifreleme %6 civarında bir ektra yuk meydana getirir. alternatif olarak 20den fazla kolunu sifreli olan fakat tablespace şifresiz olan bir yapı düşünelim.Full table scan yapılacak. full table scan operasyonun encryption yapılmıs bir tablespace göre oldukca yavas kalacaktır.Buda yaklaşık %20 civarında bir extra yuke sebeb olacatır.
ütün bunların dışında securefiles yapısı sayesinde artık çok daha etkili ve güvenli LOB data tipine ulaşmıs durumdayız.
create table t_enc_lob1
(t_enc_id NUMBER
, lb_enc CLOB encrypt
)
LOB(lb_enc) STORE AS SECUREFILE (CACHE);
yada
create table t_enc_lob2
(t_enc_id NUMBER
, lb_enc CLOB
)
LOB(lb_enc)
STORE AS SECUREFILE (CACHE
encrypt using 'AES128'
);
create table t_enc_lob5
(t_enc_id NUMBER
, lb_enc CLOB encrypt using 'AES128'
)
LOB(lb_enc) STORE AS SECUREFILE (CACHE)
/
insert into t_enc_lob5 values(1,'AAA');
alter table t_enc_lob5 MODIFY LOB(lb_enc) (decrypt);
Bunların dışında datapump encryption olayınıda unutmamak gerekir.
create table encu.emp_enc
organization external
(type ORACLE_DATAPUMP
default directory ENC_DP
access parameters (encryption enabled)
location (‘emp_enc.dmp')
)
as
select * from hr.emp;
11g ile beraber logical standby sqllerindede encryption artık mumkundur.
create tablespace enc ENCRYPTION
datafile 'c:\oracle\homes\server\oradata\dj11\enc.dbf' size 100M
autoextend on next 10M maxsize 2048M
default storage(ENCRYPT)
extent management local autoallocate;
create tablespace enc_a256 ENCRYPTION USING 'AES256'
datafile 'c:\oracle\homes\server\oradata\dj11\enc_a256.dbf' size 1M
autoextend on next 1M maxsize 10M
default storage(ENCRYPT)
extent management local autoallocate;
eğer wallet open değilken sorgulama yaparsak
select count(*) from encu.employee
*
ERROR at line 1:
ORA-28365: wallet is not open
Kolon sifrekelemede olan overhead tablespace ustunde olmaz. bunun sebebide databasein block size 8192 olsun 8 bytes 3des ve 16 bytes aes herhangi bir extra storage yuku getirmemesidir.
Şöyle bir karşılastırma yapıldığında ilk testimiz tablespace encryption olsun, şifreli ve şifresiz tabloları yukleyelim.tablespace bazında yapılan şifreleme %6 civarında bir ektra yuk meydana getirir. alternatif olarak 20den fazla kolunu sifreli olan fakat tablespace şifresiz olan bir yapı düşünelim.Full table scan yapılacak. full table scan operasyonun encryption yapılmıs bir tablespace göre oldukca yavas kalacaktır.Buda yaklaşık %20 civarında bir extra yuke sebeb olacatır.
ütün bunların dışında securefiles yapısı sayesinde artık çok daha etkili ve güvenli LOB data tipine ulaşmıs durumdayız.
create table t_enc_lob1
(t_enc_id NUMBER
, lb_enc CLOB encrypt
)
LOB(lb_enc) STORE AS SECUREFILE (CACHE);
yada
create table t_enc_lob2
(t_enc_id NUMBER
, lb_enc CLOB
)
LOB(lb_enc)
STORE AS SECUREFILE (CACHE
encrypt using 'AES128'
);
create table t_enc_lob5
(t_enc_id NUMBER
, lb_enc CLOB encrypt using 'AES128'
)
LOB(lb_enc) STORE AS SECUREFILE (CACHE)
/
insert into t_enc_lob5 values(1,'AAA');
alter table t_enc_lob5 MODIFY LOB(lb_enc) (decrypt);
Bunların dışında datapump encryption olayınıda unutmamak gerekir.
create table encu.emp_enc
organization external
(type ORACLE_DATAPUMP
default directory ENC_DP
access parameters (encryption enabled)
location (‘emp_enc.dmp')
)
as
select * from hr.emp;
11g ile beraber logical standby sqllerindede encryption artık mumkundur.
9.07.2008
PLSQL bilinmesi gerekenler-7
13- merge uygulamaları
Bilindiği üzere merge komutu iki recordu karşılaştırıp varsa update yoksa insert şeklinde davranır.
bir örnek senaryo ile açıklayalım
SELECT employee_id, title, salary
FROM adp_employees;
EMPLOYEE_ID TITLE SALARY
----------- ------------------------- ----------
1 PRESIDENT and COO 5000
2 VP, OPERATIONS 1450
3 VP, SALES 1400
4 VP, FINANCE 1450
5 VP, ADMINISTRATION 1550
SELECT employee_id, title, salary
FROM employees;
EMPLOYEE_ID TITLE SALARY
----------- ------------------------- ----------
1 PRESIDENT 2500
2 VP, OPERATIONS 1450
3 VP, SALES 1400
Yukarıda görüldüpü üzere iki tablomuz bulunmaktadır. Bunlardan biri employees bir diğeride adpemp tablosudur.
oracle 9i öncesinde
DECLARE
lv_adp_employee adp_employees.employee_id%TYPE;
CURSOR cur_adp_employee IS
SELECT employee_id, title, salary
FROM adp_employees;
CURSOR cur_employee IS
SELECT employee_id, title, salary
FROM employees
where employee_id = lv_adp_employee;
lv_cur_employee cur_employee%ROWTYPE;
lv_emp_insert PLS_INTEGER := 0;
lv_emp_update PLS_INTEGER := 0;
BEGIN
FOR lv_cur_adp_employee_rec IN cur_adp_employee LOOP
lv_adp_employee := lv_cur_adp_employee_rec.employee_id;
OPEN cur_employee; FETCH cur_employee INTO lv_cur_employee;
IF cur_employee%FOUND THEN
UPDATE employees
SET title = lv_cur_adp_employee_rec.title,
salary = lv_cur_adp_employee_rec.salary
WHERE employee_id =
lv_cur_adp_employee_rec.employee_id;
lv_emp_update := lv_emp_update + 1;
ELSE
INSERT INTO employees
(employee_id, title, salary)
VALUES
(lv_cur_adp_employee_rec.employee_id,
lv_cur_adp_employee_rec.title,
lv_cur_adp_employee_rec.salary);
lv_emp_insert := lv_emp_insert + 1;
END IF;
CLOSE cur_employee;
END LOOP;
DBMS_OUTPUT.PUT_LINE('Records Inserted: ' lv_emp_insert);
DBMS_OUTPUT.PUT_LINE('Records Updated: ' lv_emp_update);
END;
/
şeklinde yapmamız gerekirken
merge statementı ile birlikte
MERGE INTO employees dest
USING
(SELECT employee_id, title, salary
FROM adp_employees) orig
ON (dest.employee_id = orig.employee_id)
WHEN MATCHED THEN
UPDATE SET
dest.title = orig.title,
dest.salary = orig.salary
WHEN NOT MATCHED THEN
INSERT (dest.employee_id, dest.title, dest.salary)
VALUES
(orig.employee_id, orig.title, orig.salary);
5 rows merged.
bu işlem çok daha kolay ve perfomanslı bir hal almıştır.
Bilindiği üzere merge komutu iki recordu karşılaştırıp varsa update yoksa insert şeklinde davranır.
bir örnek senaryo ile açıklayalım
SELECT employee_id, title, salary
FROM adp_employees;
EMPLOYEE_ID TITLE SALARY
----------- ------------------------- ----------
1 PRESIDENT and COO 5000
2 VP, OPERATIONS 1450
3 VP, SALES 1400
4 VP, FINANCE 1450
5 VP, ADMINISTRATION 1550
SELECT employee_id, title, salary
FROM employees;
EMPLOYEE_ID TITLE SALARY
----------- ------------------------- ----------
1 PRESIDENT 2500
2 VP, OPERATIONS 1450
3 VP, SALES 1400
Yukarıda görüldüpü üzere iki tablomuz bulunmaktadır. Bunlardan biri employees bir diğeride adpemp tablosudur.
oracle 9i öncesinde
DECLARE
lv_adp_employee adp_employees.employee_id%TYPE;
CURSOR cur_adp_employee IS
SELECT employee_id, title, salary
FROM adp_employees;
CURSOR cur_employee IS
SELECT employee_id, title, salary
FROM employees
where employee_id = lv_adp_employee;
lv_cur_employee cur_employee%ROWTYPE;
lv_emp_insert PLS_INTEGER := 0;
lv_emp_update PLS_INTEGER := 0;
BEGIN
FOR lv_cur_adp_employee_rec IN cur_adp_employee LOOP
lv_adp_employee := lv_cur_adp_employee_rec.employee_id;
OPEN cur_employee; FETCH cur_employee INTO lv_cur_employee;
IF cur_employee%FOUND THEN
UPDATE employees
SET title = lv_cur_adp_employee_rec.title,
salary = lv_cur_adp_employee_rec.salary
WHERE employee_id =
lv_cur_adp_employee_rec.employee_id;
lv_emp_update := lv_emp_update + 1;
ELSE
INSERT INTO employees
(employee_id, title, salary)
VALUES
(lv_cur_adp_employee_rec.employee_id,
lv_cur_adp_employee_rec.title,
lv_cur_adp_employee_rec.salary);
lv_emp_insert := lv_emp_insert + 1;
END IF;
CLOSE cur_employee;
END LOOP;
DBMS_OUTPUT.PUT_LINE('Records Inserted: ' lv_emp_insert);
DBMS_OUTPUT.PUT_LINE('Records Updated: ' lv_emp_update);
END;
/
şeklinde yapmamız gerekirken
merge statementı ile birlikte
MERGE INTO employees dest
USING
(SELECT employee_id, title, salary
FROM adp_employees) orig
ON (dest.employee_id = orig.employee_id)
WHEN MATCHED THEN
UPDATE SET
dest.title = orig.title,
dest.salary = orig.salary
WHEN NOT MATCHED THEN
INSERT (dest.employee_id, dest.title, dest.salary)
VALUES
(orig.employee_id, orig.title, orig.salary);
5 rows merged.
bu işlem çok daha kolay ve perfomanslı bir hal almıştır.
8.07.2008
PLSQL bilinmesi gerekenler-6
12-PLSQL source code versioning:
ilk önce history bilgilerimiz tutacak bir tablo yaratalım.
CREATE TABLE source_history
(change_date DATE NOT NULL,
owner VARCHAR2(30) NOT NULL,
name VARCHAR2(30) NOT NULL,
type VARCHAR2(20),
line NUMBER NOT NULL,
text VARCHAR2(4000));
Daha sonra
CREATE OR REPLACE trigger source_history
AFTER CREATE ON DATABASE
BEGIN
INSERT INTO source_history
SELECT SYSDATE, owner, name, type, line, text
FROM dba_source
WHERE owner = ORA_DICT_OBJ_OWNER
AND name = ORA_DICT_OBJ_NAME
AND type = ORA_DICT_OBJ_TYPE;
END source_history;
/
COLUMN owner FORMAT a12
COLUMN name FORMAT a11
COLUMN line FORMAT 9999
COLUMN text FORMAT a60 WORD_WRAPPED
SELECT change_date, owner, name, type, line, text
FROM source_history
WHERE name = 'PIN_OBJECTS'
order by change_date, owner, name, type, line;
historymiz asağıdaki şekilde oluşacaktır.
CHANGE_DA OWNER NAME TYPE LINE TEXT
--------- ------------ ----------- ---------- ----- ------------------------------------------------------------
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 1 PROCEDURE pin_objects
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 2 (p_pin_flag_txt IN VARCHAR2 := 'P') IS
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 3 -- The p_pin_flag_txt is either 'P' for pin
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 4 -- or 'U' for unpin.
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 5 CURSOR cur_pin_objects IS
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 6 SELECT owner '.' owner,
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 7 object
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 8 FROM objects_to_pin
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 9 ORDER BY owner, object;
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 10 BEGIN
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 11 FOR cur_pin_objects_rec IN cur_pin_objects LOOP
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 12 IF p_pin_flag_txt = 'U' THEN
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 13 DBMS_SHARED_POOL.UNKEEP(cur_pin_objects_rec.owner
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 14 cur_pin_objects_rec.object, 'P');
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 15 ELSE
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 16 DBMS_SHARED_POOL.KEEP(cur_pin_objects_rec.owner
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 17 cur_pin_objects_rec.object, 'P');
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 18 END IF;
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 19 END LOOP;
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 20 END pin_objects;
ilk önce history bilgilerimiz tutacak bir tablo yaratalım.
CREATE TABLE source_history
(change_date DATE NOT NULL,
owner VARCHAR2(30) NOT NULL,
name VARCHAR2(30) NOT NULL,
type VARCHAR2(20),
line NUMBER NOT NULL,
text VARCHAR2(4000));
Daha sonra
CREATE OR REPLACE trigger source_history
AFTER CREATE ON DATABASE
BEGIN
INSERT INTO source_history
SELECT SYSDATE, owner, name, type, line, text
FROM dba_source
WHERE owner = ORA_DICT_OBJ_OWNER
AND name = ORA_DICT_OBJ_NAME
AND type = ORA_DICT_OBJ_TYPE;
END source_history;
/
COLUMN owner FORMAT a12
COLUMN name FORMAT a11
COLUMN line FORMAT 9999
COLUMN text FORMAT a60 WORD_WRAPPED
SELECT change_date, owner, name, type, line, text
FROM source_history
WHERE name = 'PIN_OBJECTS'
order by change_date, owner, name, type, line;
historymiz asağıdaki şekilde oluşacaktır.
CHANGE_DA OWNER NAME TYPE LINE TEXT
--------- ------------ ----------- ---------- ----- ------------------------------------------------------------
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 1 PROCEDURE pin_objects
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 2 (p_pin_flag_txt IN VARCHAR2 := 'P') IS
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 3 -- The p_pin_flag_txt is either 'P' for pin
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 4 -- or 'U' for unpin.
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 5 CURSOR cur_pin_objects IS
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 6 SELECT owner '.' owner,
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 7 object
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 8 FROM objects_to_pin
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 9 ORDER BY owner, object;
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 10 BEGIN
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 11 FOR cur_pin_objects_rec IN cur_pin_objects LOOP
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 12 IF p_pin_flag_txt = 'U' THEN
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 13 DBMS_SHARED_POOL.UNKEEP(cur_pin_objects_rec.owner
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 14 cur_pin_objects_rec.object, 'P');
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 15 ELSE
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 16 DBMS_SHARED_POOL.KEEP(cur_pin_objects_rec.owner
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 17 cur_pin_objects_rec.object, 'P');
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 18 END IF;
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 19 END LOOP;
27-JAN-07 TRIGGER_TEST PIN_OBJECTS PROCEDURE 20 END pin_objects;
3.07.2008
PLsql bilinmesi gerekenler -5
11-Audit OBJECTS:
önemli objeleri izleme. Bu iş her ne kadar admin tarafında yapılması gereken bir iş gibi gözuksede bazı durumlar yazılımcılık olmadan yapılamaz.
CREATE OR REPLACE TRIGGER create_object_trigger
AFTER CREATE ON DATABASE
BEGIN
INSERT INTO audit_object_mods
(mod_date, type_of_mod, mod_user,
instance_num, database_name,
object_owner, object_type, object_name)
VALUES
(sysdate, ora_sysevent, ora_login_user,
ora_instance_num, ora_database_name,
ora_dict_obj_owner, ora_dict_obj_type,
ora_dict_obj_name);
end;
/
tabi bu örnektende anlaşıldığı gibi daha önceden audit_object_mods isminde bir tablo yaratmamız gerekir.
CREATE OR REPLACE TRIGGER alter_object_trigger
AFTER ALTER ON DATABASE
BEGIN
INSERT INTO audit_object_mods
(mod_date, type_of_mod, mod_user,
instance_num, database_name,
object_owner, object_type, object_name)
VALUES
(sysdate, ora_sysevent, ora_login_user,
ora_instance_num, ora_database_name,
ora_dict_obj_owner, ora_dict_obj_type,
ora_dict_obj_name);
end;
/
Aşağıdaki şekildede raporlayabiliriz.
,
SET LINESIZE 130
SELECT mod_date, type_of_mod, mod_user, instance_num,
database_name, object_owner, object_type,
object_name
FROM audit_object_mods
ORDER BY mod_date, type_of_mod, object_owner,
object_type, object_name;
Bir başka örnekte ise plsql userının drop yapmasını önlemek mümkündür.
CREATE OR REPLACE TRIGGER stop_drop_trigger
BEFORE DROP ON plsql_user.SCHEMA
BEGIN
RAISE_APPLICATION_ERROR (
num => -20000,
msg => 'Obje drop yapamazsınız');
END;
/
SHOW USER
USER is "PLSQL_USER"
DROP TABLE temp;
drop table temp
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20000: Obje drop yapamazsınız
ORA-06512: at line 2
önemli objeleri izleme. Bu iş her ne kadar admin tarafında yapılması gereken bir iş gibi gözuksede bazı durumlar yazılımcılık olmadan yapılamaz.
CREATE OR REPLACE TRIGGER create_object_trigger
AFTER CREATE ON DATABASE
BEGIN
INSERT INTO audit_object_mods
(mod_date, type_of_mod, mod_user,
instance_num, database_name,
object_owner, object_type, object_name)
VALUES
(sysdate, ora_sysevent, ora_login_user,
ora_instance_num, ora_database_name,
ora_dict_obj_owner, ora_dict_obj_type,
ora_dict_obj_name);
end;
/
tabi bu örnektende anlaşıldığı gibi daha önceden audit_object_mods isminde bir tablo yaratmamız gerekir.
CREATE OR REPLACE TRIGGER alter_object_trigger
AFTER ALTER ON DATABASE
BEGIN
INSERT INTO audit_object_mods
(mod_date, type_of_mod, mod_user,
instance_num, database_name,
object_owner, object_type, object_name)
VALUES
(sysdate, ora_sysevent, ora_login_user,
ora_instance_num, ora_database_name,
ora_dict_obj_owner, ora_dict_obj_type,
ora_dict_obj_name);
end;
/
Aşağıdaki şekildede raporlayabiliriz.
,
SET LINESIZE 130
SELECT mod_date, type_of_mod, mod_user, instance_num,
database_name, object_owner, object_type,
object_name
FROM audit_object_mods
ORDER BY mod_date, type_of_mod, object_owner,
object_type, object_name;
Bir başka örnekte ise plsql userının drop yapmasını önlemek mümkündür.
CREATE OR REPLACE TRIGGER stop_drop_trigger
BEFORE DROP ON plsql_user.SCHEMA
BEGIN
RAISE_APPLICATION_ERROR (
num => -20000,
msg => 'Obje drop yapamazsınız');
END;
/
SHOW USER
USER is "PLSQL_USER"
DROP TABLE temp;
drop table temp
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20000: Obje drop yapamazsınız
ORA-06512: at line 2
Kaydol:
Kayıtlar (Atom)