A PL/SQL programozási nyelv

PL/SQL műveletek

A PL/SQL blokk

 A PL/SQL blokk a következő utasításokat tartalmazhatja:

:= értékadás CLOSE kurzor lezárása (SQL utasítás) COMMIT tranzakció sikeres lezárása (SQL utasítás) DELETE adatok törlése az adatbázisban (SQL utasítás) EXIT kilépés a ciklusból FETCH rekord beolvasás a kurzorból (SQL utasítás) GOTO ugrás a megadott címkére IF feltételes elágazás INSERT adatok beszúrása az adatbázisba (SQL utasítás) LOCK TABLE táblák zárolása(SQL utasítás) LOOP ciklus szervező utasítás NULL üres utasítás OPEN kurzor nyitása (SQL utasítás) RAISE hibajelenség kiváltása ROLLBACK tranzakció visszagörgetése(SQL utasítás) SAVEPOINT tranzakció mentési pont(SQL utasítás) SELECT..INTO lekérdezés az adatbázisból(SQL utasítás) SET TRANSACTION tranzakció paraméterezés(SQL utasítás) UPDATE adatok módosítása az adatbázisban(SQL utasítás)


Az egyes műveletek végrehajtását számtalan segédfüggvény segíti, melyekkel többek között numerikus, karakterkezelési, dátumkezelési és konverziós műveletek végezhetők. Az utasítások felsorolásából is látszik, hogy a PL/SQL a külvilág felé zárt, csak az adatbázisban tárolt adatokhoz fér hozzá. Adatértékeket, mint például a változók tartalmát nem lehet vele a képernyőre, normál állományba kiírni, vagy a képernyőről, normál állományból beolvasni. Így például a SELECT utasításnak csak ProC-ből megismert SELECT...INTO formátuma használható. A SELECT eredményeit ablokk változóiban kell felfogni. Természetesen ezen értékek nem vesznek el örökre előlünk, a kapcsolatot a PL/SQL blokk és a külvilág között a kapcsolódó segédprogramok, mint például aSQLForms vagy az SQLPlus biztosítja.

Triggerek és a Pl/Sql blokk alkalmazása


A trigger egy olyan tevékenység, amelyet bizonyos, az adatbázis használatakor bekövetkező, események alkalmával kell végrehajtani. A triggereket a deklaratív hivatkozási integritás kiterjesztésére, komplex üzleti szabályok kezelésére, az adatok változásának követésére lehet használni. A tevékenységet leíró kód, a trigger törzse nem más, mint egy PL/SQL blokk. A triggerek működése a felhasználó számára átlátszó módon történik. A trigger lefutása automatikusan bekövetkezik, ha az adatbázis bizonyos tábláin egy insert, delete vagy update utasítás végrehajtódik. Ahhoz hogy egy táblán triggert hozhassunk létre, meg kell tudnunk változtatni a táblát. Ehhez vagy a tábla tulajdonosának kell lennünk vagy rendelkeznünk kell a táblára vonatkozó ALTER privilégiumokkal vagy az ALTER ANY TABLE rendszerprivilégiumokkal. A triggert SQL utasítással hozhatjuk létre (CREATE TRIGGER), de a trigger végrehajtható részét PL/SQL nyelven kell megírnunk. A triggerhez tartozik egy kiváltó (elsütő) művelet (INSERT, DELETE, UPDATE). A trigger egy objektumhoz (tábla vagy esetleg nézet) kötődik.
A trigger egy módosító művelet előtt vagy után fut le.
Trigger típusa:
Ha megadjuk a FOR EACH ROW opciót akkor a trigger minden sorra egyszer végrehajtódik. Az ilyen triggereket sor-triggernek hívjuk.
Ellenkező esetben csak utasításonként egyszer hajtódik végre a trigger. Ekkor a neve utasítás-trigger.
When feltétel csak sortriggerre adható meg. Ilyenkor a trigger csak azokra a sorokra fut le, amelyek kielégítik a feltételt. Triggerek engedélyezhetők vagy letilthatók (ALTER TRIGGER) Ha egy művelet több triggert is aktivizál akkor azok futási sorrendje nem garantált. Triggeren belül nem adható ki tranzakciókezelő utasítás. COMMIT, ROLLBACK, SAVEPOINT Az oszlopok régi és új értékére a PL/SQL blokkban úgy hivatkozhatunk mint host változókra. (kettőspont a változó előtt: :NEW.oszlop, :OLD.oszlop) BEFORE triggerben az új értéket meg is változtathatjuk és ekkor ez kerül be majd az oszlopba. AFTER trigger esetén ezt nem tehetjük meg. Egy AFTER trigger viszont már használhatja a ROWID-jét a sornak.

A triggerek fajtái

14 féle trigger létezik. A trigger fajtáit az adatbázis-műveletet, a trigger művelethez viszonyított végrehajtási ideje és a szint dönti el,amelyen a trigger végrehajtódik.

Végrehajtás ideje Művelet Szint
BEFORE INSERT sor
BEFORE INSERT utasítás
AFTER INSERT sor
AFTER INSERT utasítás
BEFORE UPDATE sor
BEFORE UPDATE utasítás
AFTER UPDATE sor
AFTER UPDATE utasítás
BEFORE DELETE sor
BEFORE DELETE utasítás
AFTER DELETE sor
AFTER DELETE utasítás
INSTEAD OF - sor
INSTEAD OF - utasítás

Sorszintű triggerek

A sorszintű triggerek egy tranzakción belül minden egyes sorra pontosan egyszer hajtódnak végre. Létrehozásuk a CREATE TROGGER parancs FOR EACH ROW utasításrészének megadásával történik.

Utasításszintű triggerek

Az utasításszintű triggerek minden tranzakcióra csak egyszer hajtódnak végre, függetlenül attól hogy hány sort dolgoznak fel. Ezeket a triggereket általában csak akkor használjuk, ha ha egy adott táblát feldolgozó teljes tranzakcióhoz akarunk valamilyen kiegészítést rendelni.

BEFORE és AFTER triggerek

Mivel a triggerek eseményekhez kapcsolódnak, lehetséges, hogy közvetlenül az adott esemény előtt vagy után fussanak le. Ha például egy beszúrandó sor egy oszlopát a triggerben akarjuk beállítani ,akkor BEFORE INSERT triggert kell alkalmaznunk, hogy elérje az új értéket. Egy AFTER INSERT trigger esetén a beszúrt értéket már nem tudjuk beállítani.

INSTEAD OF triggerek

Olyan műveletek, melyek azon műveletek helyett futnak le, amelyek aktivizálták őket. Például ilyen triggerekkel tudunk egy beszúrást átirányítani egy másik táblába, vagy egy adott nézethez tartozó több táblán ezzel tudjuk végrehajtani a módosítást.

A triggerek szintaxisa

CREATE [OR REPLACE] TRIGGER [FELHASZNÁLÓ.]trigger {BEFORE | AFTER | INSTEAD OF} {DELETE | INSERT | UPDATE [OF oszlop[, oszlop]...]} [OR {DELETE |INSERT |UPDATE [OF oszlop [,oszlop]...]}]... ON[felhasználó.]{tábla | nézet} FOR EACH {ROW | STATEMENT} [when (feltétel)] blokk;

Példák különböző triggerekre

CREATE OR REPLACE TRIGGER db_trg AFTER SERVERERROR OR LOGON OR STARTUP OR SUSPEND ON DATABASE DECLARE -- A PL/SQL blokknak lehet deklarációs része is i number; BEGIN null; END ; CREATE OR REPLACE TRIGGER db_trg2 BEFORE LOGOFF OR SHUTDOWN ON DATABASE BEGIN null; END ; CREATE OR REPLACE TRIGGER any_ddl_trg BEFORE DDL ON DATABASE BEGIN null; END ; CREATE OR REPLACE TRIGGER spec_ddl_trg BEFORE ALTER OR ANALYZE OR ASSOCIATE STATISTICS OR AUDIT OR CREATE OR DROP OR GRANT ON DATABASE BEGIN null; END ; CREATE OR REPLACE TRIGGER sajat_ddl_trg BEFORE DDL ON nikovits.SCHEMA BEGIN null; END ; CREATE OR REPLACE TRIGGER sajat_logon_trg AFTER LOGON ON SCHEMA BEGIN null; END ;

A következő triggert egy nézetre hívtuk meg, amely az összfizetéseket tartalmazza egy osztályra nézve. Ha az osztály neve (DNAME) változik, akkor a trigger megváltoztatja ezt a a DEPT táblában, ha pedig az összfizetés (SUMSAL) változik, akkor az adott osztály összes dolgozójának fizetése egyforma mértékben változik meg, úgy, hogy a változtatás utáni összfizetés az előre megadott összfizetéssel egyezik meg.

create table dept as select * From orauser.dept; create table emp as select * From orauser.emp; create or replace view dept_sal as select dname, sum(sal) sumsal from dept, emp where dept.deptno = emp.deptno group by dname; create or replace trigger Trigger3 instead of update on dept_sal for each row declare n_salary dept_sal.sumsal%type; n_dptcnt number; n_dptno dept.deptno%type; begin --Updating DNames update dept set dname = :new.dname where dname = :old.dname; --Selecting the # of employees of all groups in dept select dummy.empnumber, dummy.deptno into n_dptcnt, n_dptno from ( select deptno, count(empno) empnumber from emp group by deptno ) dummy, dept d where d.deptno = dummy.deptno and d.dname = :new.dname; n_salary := :new.sumsal / n_dptcnt; --Updating SumSalary and SAL from emp update emp set sal = n_salary where deptno = n_dptno; end Trigger3; /* A lekérdezés eredménye: update dept_sal set sumsal=45000; select sumsal from dept_sal; -- updateljuk az összfizetést és lekérdezzük a dept_sal sumsal nevű oszlopát. SUMSAL ---------- 45000 45000 45000 select sal from emp; -- lekérdezzük a sal nevű oszlopot az emp táblából. 9000 7500 7500 9000 7500 7500 15000 9000 15000 7500 9000 7500 9000 15000 */

Kurzorok

Egy SQL utasítás feldolgozásához az Oracle a memóriában egy speciális területet használ, melyet környezeti területnek hívunk. A környezeti terület információkat tartalmaz az utasítás által feldolgozott sorokról, lekérdezés esetén tartalmazza a visszaadott sorokat (amit aktív halmaznak nevezünk) és tartalmaz egy mutatót az utasítás belső reprezentációjára. Ez a mutató a kurzor.

A kurzor olyan eszköz, amellyel megnevezhetjük a környezeti területet, segítségével hozzáférhetünk az ott elhelyezett információkhoz és amennyiben az aktív halmaz több sort tartalmaz, azokat egyenként elérhetjük, feldolgozhatjuk.
A PL/SQL kétfajta kurzort kezel, az explicit és az implicit kurzort. A PL/SQL automatikusan felépít egy implicit kurzort minden DML utasításhoz, beleértve az olyan lekérdezéseket is, amelyek pontosan egy sort adnak vissza. A több sort visszaadó lekérdezések eredményének soronkénti kezeléséhez viszont explicit kurzort célszerű használnunk. Megjegyzendő, hogy az explicit kurzor hatékonysága általában rosszabb, mint az implicit kurzoré.
Egy explicit kurzor kezelésének négy lépése van, ezek az alábbiak:

Kurzorok használta

Kurzort deklarálni a PL/SQL blokk deklarációs részében tudunk, az alábbi szintaxissal:

CURSOR kurzornév [(paraméter[,paraméter]…)] [RETURN sortípus] IS select_utasítás;

Az alábbi példa mutatja be, hogy hogyan használjunk egy kurzort:

DECLARE CURSOR employee IS SELECT ename FROM emp; name emp.ename%TYPE; BEGIN OPEN employee; LOOP FETCH employee INTO name; EXIT WHEN employee%NOTFOUND; dbms_output.put_line(‘Dolgozo neve: ‘ || name); END LOOP; CLOSE employee; END;

Miután deklaráltuk a kurzort a deklarációs blokkban, a blokk törzsében nyissuk meg a kurzort az OPEN kulcsszó segítségével. Miután a kurzort megnyitottuk egy ciklussal tudunk végig iterálni az eredményhalmazon, hogy soronként dolgozhassuk fel azt.
Az éppen aktuális sort a FETCH kulcsszóval tudjuk elkérni egy olyan változóba, aminek a típusa megegyezik a kurzor eredményhalmazának a visszatérési értékével (tehát ha nem csak egy oszlopot ad vissza, akkor rekord kell). Meg kell adnunk egy kilépési feltételt is, ez rendszerint a kurzor érvénytelen memóriacímre mutatásának vizsgálata használatos, azaz az EXIT WHEN kurzornév%NOTFOUND utasítás.
A ciklus után amilyen sürgősen csak tudjuk, zárjuk be a kurzort, a CLOSE kurzornév parancs segítségével, hogy felszabadítsuk a lefoglalt erőforrásokat.

Kurzorok működése

A kurzorok nagy szolgálatot tesznek minden PL/SQL programozónak a mindennapokban, mert egyszerű és kényelmes használni őket, és nagyfokú sokoldalúságot biztosítanak a munkánk során. Érdemes azonban megismerni a pontos működésüket, mert ha úgy használunk egy kurzort, hogy nem ismerjük a korlátait, vagy esetleg (a kényelem miatt) nem törödünk azokkal, akkor a kódunk optimalizálatlan és lassú is lehet.

A kurzor valójában nem egy lekérdezés, sem egy tároló, hanem egy pointer, ami egy lekérdezés eredményhalmazának egy sorára mutat. Amikor megnyitunk egy kurzort az eljárásunkban, és lekérjük az eredményének a következő sorát a FETCH utasítással, akkor minden kurzor sor lekérdezés külön-külön küldődik el a kliensünktől a szervernek, hogy az parse-olja, lekérdezéstervet generáljon, végrehajtsa, az eredményhalmazt pedig visszaküldje a kliensnek. Mivel a PL/SQL eljárásunk PL/SQL kódot küld a szervernek, amit annak át kell alakítania SQL kóddá, majd ugyanezt visszafelé is, ezért rengeteg PL/SQL - SQL kontextusváltáson is keresztül megy a kódunk, ami nagyon sokat lassít a program hatékonyságán.
Ez a probléma főleg a régebbi Oracle verzióknál érezhető nagyon, 10g verzión például ez egy nem elhanyagolható dolog, amire igenis oda kell figyelnünk. Fontos kiemelni továbbá, hogy ahhoz, hogy az Oracle el tudja tárolni átmenetileg a lekérdezésünk eredményhalmazát, ahhoz több fajta erőforrást igénybe kell vennie, például zárakat, memóriát, akár még lemezterületet is. Ezért, ha nem akarjuk, hogy ez a sok erőforrás fölöslegesen maradjon lefoglalva hosszú ideig, akkor minnél hamarabb zárjuk be a kurzorunkat, minnél hamarabb bezárjuk a kurzort, annál jobb.
Nyitva tartani egy kurzort olyan, mint nyitva tartani a hűtőt.
Ok nélkül nem tesszük órákig, de ez nem jelenti azt, hogy sohasem kell kinyitnunk a hűtőt.

Mikor használjunk kurzort?

A kurzor arra való, hogy egy lekérdezés eredményhalmazát sorról sorra tudjuk feldolgozni.
Ez azt jelenti, hogy:

Ha tényleg a sorok nagy részét teljesen különbözően kell kezelni, akkor használj kurzort … Azonban a szerző tapasztalatból mondja, hogy az esetek egy tizedében indokolt valójában a kurzor használata, amikor azzal akarja egy kevésbé tapasztalt PL/SQL programozó elkezdeni a feladatot. Az esetek túlnyomó többségében meg lehet sima SQL-el is oldani a problémát, és szükségtelen kurzor.

Triggerek működése és használata

A triggerek nagyon sok munkát megspórolhatnak nekünk, és a használatuk kényelmes. Érdemes azonban épp úgy odafigyelni használatukra, mint a kurzoroknál, mert ha elárasztjuk az adatbázis triggerekkel, akkor nagyon komoly teljesítmény problémákkal kellhet majd szembenéznünk.
Oracle-ben a DML utasításokhoz rendelt FOR EACH ROW triggerek valójában kurzorok, így igaz rájuk a kurzorok minden hátulütője is. Egy FOR EACH ROW trigger puszta létezése is lelassíthatja a DML utasítások futásának az idejét tizedére is akár.
Az alábbi script Oracle 10g verzióban lett futtatva.

SQL> CREATE TABLE trigger_test (id INT NOT NULL); Table created Executed in 0,031 seconds SQL> INSERT 2 INTO trigger_test 3 SELECT level 4 FROM dual 5 CONNECT BY 6 level <= 1000000 7 / 1000000 rows inserted Executed in 1,469 seconds SQL> COMMIT 2 / Commit complete Executed in 0 seconds SQL> TRUNCATE TABLE trigger_test 2 / Table truncated Executed in 3 seconds SQL> CREATE TRIGGER trg_test_ai 2 AFTER INSERT 3 ON trigger_test 4 FOR EACH ROW 5 BEGIN 6 NULL; 7 END; 8 / Trigger created Executed in 0,094 seconds SQL> INSERT 2 INTO trigger_test 3 SELECT level 4 FROM dual 5 CONNECT BY 6 level <= 1000000 7 / 1000000 rows inserted Executed in 17,578 seconds

Látható, hogy beszúrtunk 1.000.000 sort egy táblába, ami másfél másodperc alatt lefutott. Ez után létrehoztunk egy üres triggert (olyan triggert, ami nem csinál semmit), majd megint beszúrtunk 1.000.000 sort a táblába, ami viszont a trigger miatt már 17 és fél másodpercig tartott, pedig a trigger még csak nem is végzett semmilyen műveletet. Ezt a lassulási lehetőséget minden képpen tartsuk szem előtt, ha triggert akarunk létrehozni az adatbázis egy táblájához!

SQL utasítások a PL/SQL-ben

Egy PL/SQL program szövegébe csak DML és tranzakcióvezérlő utasítások építhetők be, DDL utasítások nem. Bárhol használhatók, ahol végrehajtható utasítások állhatnak. Minden SQL utasítás alkalmazásához a PL/SQL a natív dinamikus SQL eszközét használja.

DML utasítások

A PL/SQL-ben a SELECT, DELETE, INSERT, UPDATE, MERGE utasítások speciális változatai használhatók.

SELECT INTO

A SELECT INTO utasítás egy vagy több adatbázistáblát kérdez le és a származtatott értéket változokba vagy egy rekordba helyezi el. Alakja:

SELECT [{ALL | {DISTINCT | UNIQUE}}] {* | select_kifejezés [, select_kifejezés] ... } {INTO {változónév [, változónév] ... | rekordnév} | BULK COLLECT INTO kollekciónév [, kollekciónév] ...} FROM {táblahivatkozás | (alkérdés) | TABLE(alkérdés1)} [másodlagos_név] [, {táblahivatkozás | (alkérdés) | TABLE(alkérdés1)} [másodlagos_név]}] ... további_utasításrészek;

DELETE

A DELETE utasítás egy adott tábla vagy nézet sorait törli. Alakja:

DELETE [FROM] {táblahivatkozás | (alkérdés) | TABLE(alkérdés1)} [másodlagos_név] [WHERE {feltétel | CURRENT OF kurzornév}] [RETURNING {egysoros_select_kifejezés [,egysoros_select_kifejezés]... INTO változó [,változó]...| többsoros_select_kifejezés [, többsoros_select_kifejezés]... [BULK COLLECT INTO kollekciónév [, kollekciónév]...]}];

INSERT

Az INSERT utasítás új sorokkal bővít egy megadott táblát vagy nézetet. Alakja:

INSERT INTO {táblahivatkozás | (alkérdés) | TABLE(alkérdés1) } [másodlagos_név] [(oszlop [, oszlop]...) ] {VALUES (sql_kifejezés [, sql_kifejezés]...) | rekord} [returning_utasításrész] | alkérdés2};

UPDATE

Az UPDATE utasítás megváltoztatja egy megadott tábla vagy nézet adott oszlopainak értékét. Alakja:

UPDATE {táblahivatkozás| (alkérdés) | TABLE(alkérdés1)} [másodlagos_név] SET{{oszlop={sql_kifejezés | (alkérdés2)} | (oszlop [,oszlop]...) = (alkérdés3)} [, {oszlop={sql_kifejezés | (alkérdés2)} | (oszlop [,oszlop]...) = (alkérdés3)}] ... | ROW = rekord} [WHERE { feltétel | CURRENT OF kurzornév}] [returning_utasításrész];

MERGE

A MERGE utasítás a többszörös INSERT és DELETE utasítások elkerülésére való. Alakja:

MERGE INTO tábla [másodlagos_név] USING {tábla|nézet|alkérdés} [másodlagos_név] ON (feltétel) WHEN MATCHED THEN UPDATE SET oszlop={kifejezés|DEFAULT} [, oszlop={kifejezés|DEFAULT}]... WHEN NOT MATCHED THEN INSERT (oszlop [, oszlop]...) VALUES ({DEFAULT|kifejezés [,kifejezés]...});

Tranzakciókezelés

Az Oracle működése közben munkameneteket kezel. Egy felhasználói munkamenet egy alkalmazás vagy egy Oracle-eszköz elindításával, az Oracle-hez való kapcsolódással indul. A munkamenetek egyidejűleg, párhuzamosan, az erőforrásokat megosztva működnek. Az adatintegritás megőrzéséhez az Oracle konkurenciavezérlést alkalmaz.
A konkurens adatok elérését zárakkal biztosítja az Oracle. Ez a zár átmenetileg tulajdonosi jogkört biztosít a felhasználó számára egy táblára, vagy egy tábla bizonyos soraira. Amíg a zárolás fennáll, addig más felhasználó nem hajtat végre módosítást az adatokon.
A tranzakció nem más, mint DML-utasítások sorozata, amelyek a munka egyik logikai egységét alkotják. Utasításainak hatása együtt jelentkezik. Sikeres végrehajtás esetén a módosítások véglegesítődnek. Ha valamilyen hiba folytán a tranzakció sikertelen, akkor visszagörgetődik, és az adatbázis állapota nem változik meg. Lehetőség van részleges visszagörgetésre is.

A tranzakció explicit végegesítésére a COMMIT utasítás szolgál. Alakja:

COMMIT [WORK];

A WORK csak az olvashatóságot szolgálja.
A COMMIT a tranzakció által okozott módosításokat átvezeti az adatbázisba és láthatóvá teszi más munkamenetek számára, felold minden zárat, és törli a mentési pontokat.

A SAVEPOINT utasítással egy tranzakcióban mentési pontokat helyezhetünk el. Ezek a tranzakció részleges visszagörgetését szolgálják. Alakja:

SAVEPOINT név;

A visszagörgetést a ROLLBACK utasítás végzi, alakja:

ROLLBACK [WORK] [TO [SAVEPOINT] mentési_pont];

Az egyszerű ROLLBACK utasítás érvényteleníti a teljes tranzakció hatását, oldja a zárakat és törli a mentési pontokat, és a tranzakció befejeződik.
Az Oracle minden INSERT, UPDATE, DELETE utasítás elé elhelyez egy implicit mentési pontot. Ha az utasítás sikertelen, akkor az Oracle automatikusan visszagörgeti.

Fontos, hogy egy PL/SQL blokk és a tranzakció nem azonosak. A blokk kezdete nem indít el tranzakciót, és a záró END sem jelenti a tranzakció végét.

A tranzakció tulajdonságai

Egy tranzakció tulajdonságait a SET TRANSACTION utsítással állíthatjuk be. Mindig a tranzakció az első utasításának kell lennie. Alakja:

SET TRANSACTION {READ ONLY | READ WRITE | ISOLATION LEVEL {SERIALIZABLE | READ COMMITTED} [NAME sztring]};

A READ ONLY csak olvasható tranzakciót indít el. Egy csak olvasható tranzakcióban SELECT INTO (FOR UPDATE nélkül), OPEN, FETCH, CLOSE, LOCK TABLE, COMMIT és ROLLBACK utasítások helyezhetők el.
A READ WRITE az aktuális tranzakciót olvasható-írható tranzakcióvá nyilvánítja. A tranzakcióban minden DML-utasítás használható.
Az ISOLATION LEVEL az adatbázist módosító tranzakciók kezelését adja meg. A READ COMMITTED az alapértelmezett, ennél szigorúbb szintet a SERIALIZABLE explicit megadásával írhatunk elő.
A NAME által a tranzakcióhoz hozzárendelt sztring hozzáférhető a tranzakció futása alatt, lehetővé teszi a monitorozást, vagy elosztott tranzakciók kezelését.

Explicit zárolás

Az Oracle automatikusan zárolja az adatokat, azonban a felhasználó is zárolhat explicit módon egy táblát vagy egy tábla bizonyos sorait.
A SELECT FOR UPDATE utasítással a kérdés által leválogatott sorok egy későbbi utasítás számára lefoglalásra kerülnek. Ezt akkor érdemes használni, ha biztosak akarunk lenni abban, hogy az adott sorokat nem módosítja más felhasználó a mi módosításunk előtt.
Ha olyan UPDATE vagy DELETE utasítást használunk, amelyikben szerepel CURRENT OF utasításrész, akkor a kurzorban kötelező a FOR UPDATE utasítás.
A LOCK TABLE segítségével egy vagy több táblát tudunk zárolni. Alakja:

LOCK TABLE tábla [,tábla] ... IN mód MODE [NOWAIT];

A mód lehet: ROW SHARE, ROW EXCLUSIVE, SHARE, SHARE UPDATE, SHARE ROW EXCLUSIVE, EXCLUSIVE.

Autonóm tranzakciók

Egy tranzakció elindíthat egy másik tranzakciót. Gyakori, hogy ezek az elindított tranzakciók az indított tranzakciótól teljesen elkülönülten működnek, az ilyen tranzakciók autonómok. Az autonóm tranzakció független, nincs megosztott zár, erőforrás a fő tranzakcióval. Előnye, hogy az újrafelhasználást segítő szoftverkomponensek állíthatók elő.
Létrehozására egy pragma szolgál, elhelyezhető egy rutin deklarációs részében. Alakja:

PRAGMA AUTONOMOUS_TRANSACTION;

Felhasználó által definiált zárak

Felhasználói zárak létrehozására a DBMS_LOCK csomag ad lehetőséget. Lefoglalhatunk egy új zárat megadott zárolási móddal, elnevezhetjük azt, hogy más munkamenetben is látható legyen, megváltoztatjuk a zárolás módját, és végül feloldhatjuk.
Segítségükkel kizárólagos hozzáférést biztosíthatunk egy adott eszközhöz, létrehozhatunk alkalmazás szintű olvasási zárat, érzékelhetjük egy zár feloldását vagy szinkronizációs eszközként kikényszeríthetjük az alkalmazások szekvenciális végrehajtását.