A rekordtípus

A skalártípusok mindegyike beépített típus, a STANDARD csomag tartalmazza őket. Ezek tartományának elemei atomiak. Ezzel szemben az összetett típusok tartományának elemei mindig egy-egy adatcsoportot reprezentálnak. Ezeket a típusokat mindig felhasználói típusként kell létrehozni. Két összetett típuscsoport van. Az egyikbe tartozik a rekord, amely heterogén, összetett típus, a másikba tartozik az asszociatív tömb, a beágyazott tábla és a dinamikus tömb. Ez utóbbiakat összefoglaló néven kollekciótípusoknak hívjuk. A kollekciótípusokkal a 12. fejezet foglalkozik.

A rekord logikailag egybetartozó adatok heterogén csoportja, ahol minden adatot egy-egy mező tárol. A mezőnek saját neve és típusa van. A rekordtípus teszi lehetővé számunkra, hogy különböző adatok együttesét egyetlen logikai egységként kezeljünk. A rekord adattípus segítségével olyan programeszközöket tudunk deklarálni, amelyek egy adatbázistábla sorait közvetlenül tudják kezelni. Egy rekordtípus deklarációja a következőképpen történik:

TYPE név IS RECORD(

mezőnév típus [[NOT NULL] {:=|DEFAULT}kifejezés]

[,mezőnév típus [[NOT NULL] {:=|DEFAULT} kifejezés]]…);

A név a létrehozott rekordtípus neve, a továbbiakban deklarációkban a rekord típusának megadására szolgál.

A mezőnév a rekord mezőinek, elemeinek neve.

A típus a REF CURSOR kivételével bármely PL/SQL típus lehet.

A NOT NULL megadása esetén az adott mező nem veheti fel a NULL értéket. Ha futási időben mégis ilyen értékadás következne be, akkor kiváltódik a VALUE_ERROR kivétel. NOT NULL megadása esetén kötelező az inicializálás.

A :=|DEFAULT utasításrész a mező inicializálására szolgál. A kifejezés a mező kezdőértékét határozza meg.

Egy rekord deklarációjának alakja:

rekordnév rekordtípus_név;

1. példa

DECLARE
/* Rekorddefiníciók */
-- NOT NULL megszorítás és értékadás
TYPE t_aru_tetel IS RECORD (
kod NUMBER NOT NULL := 0,
nev VARCHAR2(20),
afa_kulcs NUMBER := 0.25
);
-- Az előzővel azonos szerkezetű rekord
TYPE t_aru_bejegyzes IS RECORD (
kod NUMBER NOT NULL := 0,
nev VARCHAR2(20),
afa_kulcs NUMBER := 0.25
);
-- %ROWTYPE és rekordban rekord
TYPE t_kolcsonzes_rec IS RECORD (
bejegyzes plsql.kolcsonzes%ROWTYPE,
kolcsonzo plsql.ugyfel%ROWTYPE,
konyv plsql.konyv%ROWTYPE
);
-- %ROWTYPE
SUBTYPE t_ugyfel_rec IS plsql.ugyfel%ROWTYPE;
v_Tetel1 t_aru_tetel; -- Itt nem lehet inicializálás és NOT NULL!
v_Tetel2 t_aru_tetel;
.
.
.

Egy rekord mezőire minősítéssel a következő formában tudunk hivatkozni:

rekordnév.mezőnév

2. példa

v_Tetel1.kod := 1;

Rekordot nem lehet összehasonlítani egyenlőségre vagy egyenlőtlenségre és nem tesztelhető a NULL értéke sem.

Komplex példa

DECLARE
  /* Rekorddefiníciók */
  -- NOT NULL megszorítás és értékadás
  TYPE t_aru_tetel IS RECORD (
    kod NUMBER NOT NULL := 0,
    nev VARCHAR2(20),
    afa_kulcs NUMBER := 0.25
  );
  -- Az előzővel azonos szerkezetű rekord
  TYPE t_aru_bejegyzes IS RECORD (
    kod NUMBER NOT NULL := 0,
    nev VARCHAR2(20),
    afa_kulcs NUMBER := 0.25
  );
  -- %ROWTYPE és rekordban rekord
  TYPE t_kolcsonzes_rec IS RECORD (
    bejegyzes plsql.kolcsonzes%ROWTYPE,
    kolcsonzo plsql.ugyfel%ROWTYPE,
    konyv plsql.konyv%ROWTYPE
  );
  -- %ROWTYPE
  SUBTYPE t_ugyfel_rec IS plsql.ugyfel%ROWTYPE;
  v_Tetel1 t_aru_tetel; -- Itt nem lehet inicializálás és NOT NULL!
  v_Tetel2 t_aru_tetel;
  v_Bejegyzes t_aru_bejegyzes;
  -- %TYPE
  v_Kod v_Tetel1.kod%TYPE := 10;
  v_Kolcsonzes t_kolcsonzes_rec;
  /* Függvény, ami rekordot ad vissza */
  FUNCTION fv(
    p_Kolcsonzo v_Kolcsonzes.kolcsonzo.id%TYPE,
    p_Konyv v_Kolcsonzes.konyv.id%TYPE
  ) RETURN t_kolcsonzes_rec IS
  v_Vissza t_kolcsonzes_rec;
  BEGIN
    v_Vissza.kolcsonzo.id := p_Kolcsonzo;
    v_Vissza.konyv.id := p_Konyv;
    RETURN v_Vissza;
  END;
BEGIN
  /* Hivatkozás rekord mezőjére minősítéssel */
  v_Tetel1.kod := 1;
  v_Tetel1.nev := 'alma';
  v_Tetel1.nev := INITCAP(v_Tetel1.nev);
  v_Kolcsonzes.konyv.id := fv(10, 15).konyv.id;
  /* Megengedett az értékadás azonos típusok esetén. */
  v_Tetel2 := v_Tetel1;
  /* A szerkezeti egyezőség nem elég értékadásnál */
  -- v_Bejegyzes := v_Tetel1; -- Hibás értékadás
  /* Rekordok egyenlőségének összehasonlítása és NULL tesztelése
  nem lehetséges */
  /* A következő IF feltétele hibás
  IF v_Tetel1 IS NULL
      OR v_Tetel1 = v_Tetel2
      OR v_Tetel1 <> v_Tetel2 THEN
    NULL;
  END IF;
  */
END;
/