Managing Schema Objects

Salam, Bloguma xoş gəlmisiniz!

Uzun müddətdən sonra çoxdandır yazdığım ancaq bir türlü paylaşa bilmədiyim yeni mövzumuzu sizinlə paylaşıram 🙂

Bugünkü mövzumuz bazada yaratdığımız obyektlərin idarə edilməsi və üzərində dəyişikliklərin edilməsi olacaq. Mövzu uzun olacağı üçün aşağıdakı hissələrdən ibarət olacaq:

  • Cədvəllərə sütunların əlavə edilməsi və dəyişdirilməsi
  • Cədvəlin sütunlarına DROP və SET UNUSED tətbiq etmək
  • Constraint-lər əlavə etmək
  • CREATE TABLE –ilə index-lərin yaradılması
  • Funksiya əsaslı index-lər(function based index)
  • FLASHBACK əməliyyatları
  • Xarici cədvəllərləri istifadə etmək(Use External Table)

 CƏDVƏLLƏRƏ SÜTUNLARIN ƏLAVƏ EDİLMƏSİ VƏ DƏYİŞDİRİLMƏSİ.

Bazada olan cədvəllərimizə bir müddətdən sonra yeni bir sütun əlavə etmək və ya cari strukturunda hər hansı dəyişiklik etmək kimi bir ehtiyacımız yarana bilər bu zaman bu ehtiyacımızı qarşılamaq üçün ALTER TABLE kimi bir ifadəyə ehtiyacımız olacaq. Ümumi sintaksisi bu şəkildədir:

ALTER TABLE table_name clause;

table_name – üzərində dəyisiklik edəcəyimiz cədvəlin adıdır.

clause ALTER TABLE ifadəsinin parametrlərindən biridir, mən əsasən bunlardan ADD MODIFY-dan bəhs edəcəyəm.

 

CƏDVƏLLƏRƏ SÜTUNLARIN  ƏLAVƏ EDİLMƏSİ

İlk öncə nümunə üçün bir cədvəl yaradaq sonra həmin cədvələ yeni sütun əlavə edək.

CREATE TABLE CRUISE_ORDERS(

CRUISE_ORDER_ID     NUMBER,

SALES_REP_ID            NUMBER);

Cədvəlimiz yaratdıqdan sonra adı ORDER_DATE , tipi VARCHAR2(20) olan yeni bir sütun əlavə edək.

ALTER TABLE CRUISE_ORDERS ADD (ORDER_DATE VARCHAR2(20));

Sütunlar əlavə edərkən constraint-lərin və DEFAULT-un istifadəsinə diqqət etmək lazımdır. ConstraintDEFAULT hər zaman verilən tipi təyin olunduqdan sonra yazılmalıdır. Məs:

ALTER TABLE CRUISE_ORDERS ADD (WEATHER_CODE DEFAULT 0 NUMBER(2));  — bu cür yazılış səhvdir.

ALTER TABLE CRUISE_ORDERS ADD (WEATHER_CODE NUMBER(2) DEFAULT 0); –düzgün formada yazılış.

NOT NULL constraintinə sahib olan sütun əlavə edirsinizsə bu zaman cədvəlinizdə mılumat varsa əlavə olaraq DEFAULT ifadəsindən istifadə etməlisinizki həmin sütundakı hər hansı sətir NULL dəyərə sahib olmasın. Məs:

ALTER TABLE CRUISE_ORDERS ADD FIRST_TIME_CUSTOMER VARCHAR2(5) NOT NULL; — bu yazılış o zaman doğrudur ki, CRUISE_ORDERS cədvəli daxilində məlumat olmasın.

ALTER TABLE CRUISE_ORDERS ADD FIRST_TIME_CUSTOMER VARCHAR2(5) DEFAULT ‘YES’ NOT NULL; — DEFAULT əlavə etməklə artıq biz cədvəlimizin daxilində məlumat olub olmadığını nəzərə almaya bilərik.

 

SÜTUNLARIN DƏYİŞDİRİLMƏSİ

Cədvəllərimizi yaratdıqdan bir müddət sonra cədvəlimizdəki sütunlarda bəzi dəyişikliklər etmək lazım gəlir bu zaman yenə ALTER TABLE ifadəsindən istifadə edəcəyik. Məs: CRUISE_ORDERS cədvəlində olan ORDER_DATE sütunun tipini dəyişək.

 

DESC CRUISE_ORDERS

Name                                Null?       Type

————————-            ——      ——-

CRUISE_ORDER_ID                  NUMBER

SALES_REP_ID                         NUMBER

ORDER_DATE                           VARCHAR2(20)

 

ALTER TABLE CRUISE_ORDERS MODIFY (ORDER_DATE DATE); — artıq ORDER_DATE “DATE” tipində məlumat qəbul edəcək.

Həmçinin sütunları dəyişərkən constraint-lərdən istifadə edə bilərik eyni zamanda yaratdığımız constraintlərə də adlar verə bilərik.

ALTER TABLE CRUISE_ORDERS MODIFY (ORDER_DATE DATE CONSTRAINT NN_CRUISE NOT NULL);

 

CARİ SÜTUNLARIN YENIDƏN ADLANDIRILMASI

Cədəllərimizi yaratdıqdan sonra sütunlardan hər hansı birnin adında dəyişiklik etmək istəyiriksə o zaman ALTER TABLE-in RENAME parametrindən istifadə edəcəyik. İndiyə kimi ALTER TABLE-in ADD MODIFY parametrlərinə baxmışdıq.

ALTER TABLE CRUISE_ORDERS RENAME COLUMN SALES_REP_ID TO SALES_AGENT_ID;

 

SÜTUNLARIN DROP və UNUSED EDİLMƏSİ

  • DROP

Cədvəlimizdə olan hər hansı sütunu silmək üçün ALTER TABLE-in parametri olan DROP və ya DROP COLUMN-dan istifadə edəcəyik.

ALTER TABLE ORDER_RETURNS DROP COLUMN CRUISE_ORDER_DATE; — yalnız 1 sütun drop edə bilər

ALTER TABLE ORDER_RETURNS DROP (CRUISE_ORDER_DATE); — mötərizə daxilində bir neçə sütun qeyd edə bilərsiniz.

Məs:

ALTER TABLE ORDER_RETURNS DROP (CRUISE_ORDER_DATE, FORM_TYPE, NAME_SUFFIX);

Qeyd: Cədvəldəki bütün sütunları DROP edə bilməssiniz, cədvəlin ən azı 1 sütunu olmalıdır.

Qeyd: Diqqət etməmiz gərəkən bir nüans daha var, bəzən cədvəllərimizidə olan bəzi sütunları DROP(silmək) edə bilmərik buna səbəbi isə həmin sütunun başqa bir cədvəl ilə foreign key – primary key əlaqəsində olması ola bilər. Məsələn bu cür əlaqədə olan 2 cədvəl yaradaq və onlardan birində sütun sildiyimiz(DROP) zaman hansı xəta baş verdiyini incələyək.

 

CREATE TABLE CRUISE_ORDERS(

CRUISE_ORDER_ID NUMBER,

ORDER_DATE DATE,

CONSTRAINT PK_CO PRIMARY KEY (CRUISE_ORDER_ID, ORDER_DATE)

);

CREATE TABLE ORDER_RETURNS(

ORDER_RETURN_ID NUMBER,

CRUISE_ORDER_ID NUMBER,

CRUISE_ORDER_DATE DATE,

CONSTRAINT PK_OR PRIMARY KEY (ORDER_RETURN_ID),

CONSTRAINT FK_OR_CO FOREIGN KEY

(CRUISE_ORDER_ID, CRUISE_ORDER_DATE)

REFERENCES CRUISE_ORDERS (CRUISE_ORDER_ID, ORDER_DATE)

);

Hal hazırda CRUISE_ORDERSORDER_RETURNS cədvəllərimizi yaratdıq və cədəllərimizlə yanaşı CRUISE_ORDERS cədvəli üzərində PK_CO adlı PRIMARY_KEYORDER_RETURNS cədvəli üzərində PK_OR adlı PRIMARY KEY, FK_CO_OR adlı FOREIGN KEY constraint-ləri yaratdıq hansı ki, FK_CO_OR constraint-i CRUISE_ORDERS cədvəlinə referans(müraciət) edir. Belə olan halda CRUISE_ORDERS cədvəlindəki CRUISE_ORDER_ID ORDER_DATE sütunlarını DROP edə bilməssiniz çünki bu sütunlar ORDER_RETURNS cədvəlindəki CRUISE_ORDER_ID, CRUISE_ORDER_DATE sütunlarının parent(ana) sütunlarıdır. Həmçinin foreign key constraintinin sahib olduğu sütunlar da digər cədvəl ilə əlaqədə olduğu üçün DROP edə bilməssiniz. Əgər etsəniz belə bir xəta ilə qarşılaşacaqsınız.

  • SET UNUSED

Cədvəlimizdəki sütunları DROP etmək əvəzinə bəzən UNUSED etmək daha sərfəli olur. UNUSED olunmuş sütun eynilə DROP olunmuş kimi davranır. DESC əmri ilə cədvəlinizin strukturuna baxdıqda UNUSED olunmuş sütunlar görünmür və ROLLBACK UNUSED olunmuş sütunları geri gətirə bilməz. Əgər sizin böyük həcmdə cədvəlləriniz varsa bu zaman siz sütunları DROP etdiyiniz zaman bazanın performansına daha çox mənfi təsir edəcək bu zaman UNUSED istifadə etmək daha sərfəlidir. Nəzərə almaq lazımdırki ORACLE SQL-də cədvəlin maksimum 1000 sütunu ola bilər və UNUSED olunmuş sütunlar bu 1000 sütuna daxildir.

Sİntaksis aşağıdakı kimidir:

ALTER TABLE ORDER_RETURNS SET UNUSED COLUMN CRUISE_ORDER_DATE; — yalnız 1 sütunu UNUSED edir

ALTER TABLE ORDER_RETURNS SET UNUSED (CRUISE_ORDER_DATE, FORM_TYPE, NAME_SUFFIX); — bir neçə sütunu UNUSED edir

UNUSED edilmiş sütunlara data dictionary-dəki view-lardan olan USER_UNUSED_COL_TABS vasitəsilə baxa bilərsiniz. Bu view hansı sütunların UNUSED olunduğunu bizə qaytarmır ancaq hansı cədvəllərdə UNUSED sütun olduğunu göstərir.

UNUSED etdiyiniz sütunları recover edə bilməssiniz ancaq onları bu şəkildə DROP edə bilərsiniz:

ALTER TABLE table_name DROP UNUSED COLUMNS;

Məs:

ALTER TABLE ORDER_RETURNS DROP UNUSED COLUMNS;

Bu kod icra edildikdən sonra ORDER_RETURNS cədvəlində olan bütün UNUSED sütunlar DROP ediləcək.

 

CONSTRAINTLƏR-in əlavə edilməsi

Əvvəlki yazılarımızda CREATE TABLE ifadəsi ilə constraintlərin necə əlavə edildiyini görmüşdük, indi isə ALTER TABLE ilə cədvəllərimizi yaratdıqdan sonra yaratmış olduğumuz sütunlara necə constraintlərin əlavə ediləcəyinə baxaq.

İlk öncə constraintləri CREATE TABLE ilə necə yaratdığımıza baxaq. Bunun üçün 2 üsul mövcuddur.

  • In-line təyin
  • Out-of-line təyin

In-line təyin:

CREATE TABLE CRUISE_ORDERS(

CRUISE_ORDER_ID NUMBER PRIMARY KEY,

SALES_AGENT_ID NUMBER NOT NULL,

ORDER_DATE DATE,

CONFIRMATION_DATE DATE);

Hal hazırda biz CRUISE_ORDER_ID sütununa PRIMARY_KEYSALES_AGENT_ID sütununa isə NOT NULL constraintlərini “In-line” olaraq təyin etdik.

 

Out-of-line təyin:

CREATE TABLE CRUISE_ORDERS(

CRUISE_ORDER_ID NUMBER,

SALES_AGENT_ID NUMBER NOT NULL,

ORDER_DATE DATE,

CONFIRMATION_DATE DATE

CONSTRAINT PK_CRUISE_ORDERS PRIMARY KEY(CRUISE_ORDER_ID));

Indi isə biz CRUISE_ORDER_ID sütununa PRIMARY_KEY constraintini “out-of-line”,  SALES_AGENT_ID sütununa isə NOT NULL constraintini “In-line” olaraq təyin etdik. NOT NULL constraintini “out-of-linetəyin edə bilməssiniz.

İn-line” və “out-of-line” təyin olunma həmçinin ALTER TABLE ifadəsi üçün də keçərlidir.

Məs: CRUISE_ORDERS cədvəlinə ALTER TABLE ilə PRIMARY KEY constraintini həm “in-line” həm də “out-of-line” formada əlavə edək:

 

CREATE TABLE CRUISE_ORDERS(

CRUISE_ORDER_ID NUMBER,

SALES_AGENT_ID NUMBER NOT NULL,

ORDER_DATE DATE,

CONFIRMATION_DATE DATE);

 

ALTER TABLE CRUISE_ORDERS MODIFY CRUISE_ORDER_ID PRIMARY KEY; — in line təyin

Və ya

ALTER TABLE CRUISE_ORDERS MODIFY CRUISE_ORDER_ID CONSTRAINT PK_NEW_CONSTRAINT PRIMARY KEY; — in line təyin– in line təyin

ALTER TABLE CRUISE_ORDERS ADD CONSTRAINT PK_NEW_CONSTRAINT PRIMARY KEY (CRUISE_ORDER_ID); — out-of-line təyin

Qeyd: Composite constraint(1-dən çox sütuna aid olanlar)-lari ancaq və ancaq out-of-line metodu ilə təyin edə bilərsiniz, in-line metod sizə bu mövzuda təəssüfki yardım edə bilməyəcək 🙂

Məs:

ALTER TABLE CRUISE_ORDERS ADD CONSTRAINT PK_NEW_CONSTRAINT PRIMARY KEY (CRUISE_ORDER_ID, SALES_AGENT_ID);

NOT NULL constraint-i əlavə edərkən diqqət etmək lazımdır, necə ki CREATE TABLE zamanı NOT NULLout-of-line” təyin olunmurdu eynilə ALTER TABLE ilə də NOT NULLout-of-line” təyin edilə bilməz.

ALTER TABLE CRUISE_ORDERS MODIFY CRUISE_ORDER_ID NOT NULL;

Və ya

ALTER TABLE CRUISE_ORDERS MODIFY CRUISE_ORDER_ID CONSTRAINT NN_CRUISE_ORDER_ID NOT NULL;

Ancaq bu cür yazılış səhvdir:

ALTER TABLE CRUISE_ORDERS ADD CONSTRAINT NN_THIS_IS_WRONG NOT NULL (CRUISE_ORDER_ID);

Əgər CHECK constraint-i əlavə etmək istəyirsinizsə o zaman belə yazmalı olacaqsınız:

ALTER TABLE CRUISE_ORDERS ADD CONSTRAINT CK_ORDER_DATE CHECK (ORDER_DATE <= CONFIRMATION_DATE);

Əgər FOREIGN KEY constraint-i əlavə etmək istəyirsinizsə o zaman belə yazmalı olacaqsınız:

ALTER TABLE CRUISE_ORDERS ADD CONSTRAINT FK_CRUISE_ORDERS_SALES_AGENTS FOREIGN KEY (SALES_AGENT_ID) REFERENCES SALES_AGENTS(SALES_AGENT_ID);

 

CONSTRAINTLƏRİN CƏDVƏLDƏN XARİC EDİLMƏSİ

DROP PRIMARY KEY

PRIMARY KEY constraint-ini cədvəldən xaric edərəkən diqqət etməmiz gərəkən nüanslar var. Əgər cədvəlinizdə yalnız və yalnız 1 PRIMARY KEY varsa o zaman bu cür yazılış işinizi görəcəkdir.

ALTER TABLE table_name DROP PRIMARY KEY options;

Options – əsasən aşağıdakı seçimlərdən ibarətdir.

  • CASCADE – asılı halda olan constraint-ləri cədvəldən xaric etmək üçün istifadə olunur. Məsən PRIMARY KEY(PK)FOREIGN KEY(FK) əlaqəli cədvəllərdə FK hər zaman PK-dan asılıdır və siz PK constraint-ini CASCADE istifadə etmədən cədvəldən xaric edə bilməssiniz və PK-nı xaric etdiyiniz zaman ona müraciət edən FK constraint-ləri də xaric etmiş olursunuz. Default(susmaya görə) olaraq “not cascade” işləyir.
  • KEEP INDEX və ya DROP INDEX

Bildiyimiz kimi PRIMARY KEY yaratdığımız zaman avtomatik index-də yaratmış oluruq və bu PRIMARY KEY constraint-ni DROP etdikdə yaranmış index-ində DROP edilib edilməyəciyini bu seçimlə təyin edirik. Default olaraq DROP INDEX seçimi işləyir.

Qeyd: CASCADE,  KEEP INDEX vəDROP INDEX seçimindən əvvəl isitifadə olunmalıdır.

DROP UNIQUE

UNIQUE constraint-i üçün də həmçinin PRIMARY KEY-də olan seçimlər(CASCADE,KEEP INDEX, DROP INDEX) keçərlidir.

Ümumi sintaksis:

ALTER TABLE table_name DROP UNIQUE (column1, column2, . . . ) options;

 

DROP NOT NULL

NOT NULL constraintini fiziki olaraq DROP edə bilmirik bunun yerinə MODIFY edib NULL-a çeviririk.

Ümumi sintaksis:

ALTER TABLE table_name MODIFY column_name NULL; 

Digər constraint-ləri DROP etmək üçün bu ümumi sintaksisi istifadə edə bilərsiniz.

ALTER TABLE table_name DROP CONSTRAINT constraint_name options;

Optionstək seçim var: CASCADE

 

CONSTRAINT-LƏRIN SIRADAN ÇIXARILMASI VƏ IŞƏ SALINMASI(disabling and enabling of constraints)

Bəzən bazada etdiyimiz dəyişikliklər zamanı bir və ya bir neçə constraint-lərin tələbi ödənmədiyi üçün bizə qadağa qoyması ilə qarşılaşırıq. Bu zaman həmin constraint-ləri DROP etmək yerinə müəyyən müddətlik işimizi bitirənə kimi DISABLE(sıradan çıxarmaq) etmək daha məqsədə uyğun hesab edilir.

 

DISABLE

Bir misal üzərindən izah edəcəyəm.

SHIPSPORTS cədvəllərimizə baxaq.

Gördüyümüz kimi PORTS cədvəlində PORT_ID, SHIPS cədvəlində isə SHIP_ID sütunu PRIMARY KEY constraintlərinə(PK_PORTS, FK_SHIPS) malikdirlər və həmçinin SHIPS cədvəlində HOME_PORT_ID sütunu FOREIGN KEY constraint(FK_SH_PO) vasitəsilə PORTS cədvəlindəki PORT_ID sütununa müraciət edir. Yəni burdan anladığımıza görə SHIPS cədvəlindəki HOME_PORT_ID sütununa giriləcək olan hər bir dəyər PORTS cədvəlindəki PORT_ID sütununda var olmalıdır. Bu cədvəlləri bu şəkildə yarada bilərsiniz:

CREATE TABLE PORTS(

PORT_ID NUMBER(7),

PORT_NAME VARCHAR2(20),

CONSTRAINT PK_PORTS PRIMARY KEY (PORT_ID));

 

CREATE TABLE SHIPS(

SHIP_ID NUMBER(7),

SHIP_NAME VARCHAR2(20),

HOME_PORT_ID NUMBER(7),

CONSTRAINT PK_SHIPS PRIMARY KEY (SHIP_ID),

CONSTRAINT FK_SH_PO FOREIGN KEY (HOME_PORT_ID) REFERENCES PORTS (PORT_ID));

 

INSERT INTO PORTS VALUES (50, ‘Jacksonville’);

INSERT INTO PORTS VALUES (51, ‘New Orleans’);

 commit;

INSERT INTO SHIPS VALUES (10, ‘Codd Royale’, 50);

commit;

İndi isə PORTS cədvəlindən PORT_ID-si 50 olan məlumatı silək:

DELETE FROM PORTS WHERE PORT_ID = 50;

 Error starting at line 1 in command:

DELETE FROM PORTS WHERE PORT_ID = 50

Error report:

SQL Error: ORA-02292: integrity constraint (EFCODD.FK_SH_PO) violated – child

record found

2292.00000 – “integrity constraint (%s.%s) violated – child record found”

*Cause: attempted to delete a parent key value that had a foreign dependency.

*Action: delete dependencies first then parent or disable constraint.

Bu xətaya səbəb yuxarıda da qeyd etdiyim kimi FOREIGN KEY constraint-inin tətbiq etdiyimiz sütunun müraciət etdiyi ana cədvəlin sütunundakı dəyərin mütləq var olmasının lazım olduğudur. Yəni FOREIGN KEY constraintini yaratdığımız sütunun müraciət etdiyi sütundan hər zaman asılılığı vardır ancaq bu asılılıq ana cədvəldə(PORTS) olan sütundakı dəyəri bala(child table(SHIPS) J ) cədvəldə istifadə etdiyimiz zaman yaranır yəni bala cədvəldə istifadə etmədiyimiz dəyərləri silə bilərik rahatlıqla. Məs:

 

DELETE FROM PORTS WHERE PORT_ID = 51;

1 rows deleted

 Aslılığı olan sətirləri silə bilmək üçün isə 2 cədvəl arasında yaratdığımız FOREIGN KEY constraintini DISABLE etmək kifayətdir.

 ALTER TABLE SHIPS DISABLE CONSTRAINT FK_SH_PO;

Bu üsulla ancaq adlarını bildiyimiz constraint-ləri DISABLE edə bilərik ancaq hər zaman bu adları ağlımızda tuta bilmərik, yəni bu üsul bir o qədər də effektiv deyil ancaq qüsursuz şəkildə sizin işinizi tamamlayacaqdır. Daha effektiv bir yol isə aşağıdakı kimidir:

ALTER TABLE table_name DISABLE validate_expression constraint_expression;

Sintaksisi incələdiyimiz zaman:

  • ALTER TABLE məcburidir
  • Table_name üzərində dəyişiklik edəcəyimiz cədvəlin adıdır
  • DISABLE məcburidir
  • Validate_expression- VALIDATE və ya NOVALIDATE kimi 2 seçim vardır. Default(susmaya görə) olaraq VALIDATE-dir.
  • Constraint_expression – 3 cür təyin edilə bilər:
  1. PRIMARY KEY
  2. UNIQUE(sütun1, sütun2 … )
  3. CONSTRAINT constraint_adı

Verilmiş cədvəldəki constraintlərin tiplərinə və eyni zamanda adlarına USER_CONSTRAINTS data dictionary-sini istifadə edərək baxa bilərsiniz.

SELECT CONSTRAINT_NAME, CONSTRAINT_TYPE FROM USER_CONSTRAINTS WHERE TABLE_NAME = ‘SHIPS’;

CONSTRAINT_NAME               CONSTRAINT_TYPE

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

PK_SHIPS                                      P

FK_SH_PO                                     R

P-PRIMARY KEY

R-FOREIGN KEY(Referential integrity)

C-CHECK və ya NOT NULL

Aşagıdakı şəkildə constraintlərin necə DISABLE edildiyinə baxa bilərsiniz.

 

ENABLE

Constraintləri DISABLE edib işimizi gördükdən sonra onları əvvəlki vəziyətinə gətirmək üçün ENABLE etmək lazımdır. Ancaq diqqət etməli olduğumuz bir nüans varki, əgər ENABLE etməyə çalışdığımız constraintin tətbiq edildiyi sütundakı məlumatlar bu constraint-ə ziddirsə o zaman biz xəta ilə qarşılaşacağıq və nəticədə constraint-i müvəffəqiyyətlə ENABLE edə bilməyəcəyik. Məsələn: Yuxarıda qeyd etdiymiz PORTSSHIPS cədvəllərinə baxdığımız zaman bu cədvəllərin bir-birinə PRIMARY KEY-FOREIGN KEY əlaqəsi ilə bağlı olduğunu görürük. Bu zaman əgər biz FOREIGN KEY-i DISABLE etsək və PORTS cədvəlindən SHIPS cədvəlində olan PORT_ID-ni silib yenidən FOREIGN KEY constraintini ENABLE etməyə çalışsaq xəta ilə qarşılaşacağıq çünki SHIPS cədvəlindəki HOME_PORT_ID sütunun dəyəri PORTS cədvəlindəki PORT_ID-də olmadığı üçün bu dəyər SQL tərəfindən “orphans(yetim)” olaraq görünəcək və SQL cədvəllərdə “orphans” sətirlərin olmasının qarşısını hər zaman aldığı üçün bizim ENABLE etmək cəhdimiz boşa çıxmış olacaq. Nəticə olaraq əgər DISABLE etdiyiniz constraint-ləri müvəffəqiyyətlə ENABLE etmək istəyirsinizsə constraint-i tətbiq edəcəyiniz sütun constraint-ə zidd dəyər saxlamamalıdır. Ümumi sintaksisi bu şəkildədir:

ALTER TABLE SHIPS ENABLE CONSTRAINT FK_SH_PO;

 CASCADE

Əgər cədvəliniz bir digər cədvəl ilə PRIMARY KEY-FOREIGN KEY(referential integrity) əlaqəsi ilə bir-birinə müraciət edirsə bu zaman siz bu cədvəllərdəki constraint-ləri DISABLE etmək üçün CASCADE ifadəsinə ehityac duyacaqsınız. Məsələn: Yenidən PORTS,SHIPS cədvəllərinə baxaq, PORTS cədvəlindəki PRIMARY KEY constraintini ilk öncə bu şəkildə DISABLE edək:

 

ALTER TABLE PORTS DISABLE PRIMARY KEY;

Error report:

SQL Error: ORA-02297: cannot disable constraint (EFCODD.PK_PORTS) – dependencies

exist

2297.00000 – “cannot disable constraint (%s.%s) – dependencies exist”

*Cause: an alter table disable constraint failed becuase the table has foriegn keys that are dpendent on this constraint.

*Action: Either disable the foreign key constraints or use disable cascade

 

Gördüyümüz kimi bu constraintdən asıllığı olan cədvəllərimiz olduğu üçün DISABLE əmri müvəffəqiyyətlə icra olunmadı, indi isə belə bir yol yoxlayaq:

 ALTER TABLE PORTS DISABLE PRIMARY KEY CASCADE;

Sorğu  icra olunduqdan sonra həm PORTS cədvəlindəki PRIMARY KEY həmdə SHIPS cədvəlindəki FOREIGN KEY DISABLE olmuş olacaq. Bu constraint-lər sonradan bir-bir ENABLE etmək lazımdır.

ALTER TABLE PORTS ENABLE PRIMARY KEY;

ALTER TABLE SHIPS ENABLE CONSTRAINT FK_SH_PO;

 

VALIDATE/NOVALIDATE

Constraintlərin ENABLE və ya DISABLE etdiyimiz zaman bir digər əlavə seçimlər olan VALIDATENOVALIDATE –dən istifadə edirik. Aşağıdakı cədvəldə daha ətraflı izah edəcəyəm:

 

Birləşmə Açıqlama
ENABLE VALIDATE Constraint-i ENABLE edir və mövcud sətirlərə tətbiq edir. Default olaraq VALIDATE-dir yəni ENABLE VALIDATE = ENABLE.
ENABLE NOVALIDATE Constraint-i ENABLE edir ancaq cədvəldəki mövcud sətirlərə tətiq etmir ancaq ENABLE olunduqdan sonra cədvələ daxil olan məlumatlara tətbiq edilir. Bir sözlə ENABLE olunmadan qaaq cədvəldə olan məlumatların constraint-ə zidd olaraq qalmasına icazə verir.
DISABLE VALIDATE Constraint-i DISABLE edir və həmin constraint-in aid olduğu index-ləridə DROP edir.
DISABLE NOVALIDATE DISABLE ilə eyni işi görür. Default olaraq NOVALIDATE-dir.

Oracle böyük həcmli cədvəllərlə işlədiyiniz zaman bu sıralamanı tövsiyə edir:

  • Constraint-i DISABLE edin default olaraq NOVALIDATE ilə
  • Məlumatlarınızı cədvəllərə yerləşdirin
  • ENABLE NOVALIDATE tətbiq edin
  • ENABLE VALIDATE tətbiq edin

Davamı olacaq…