Montag, 20. März 2017

Forms - mit PL/SQL alle Datensätze eines Blocks in eine PL/SQL-Tabelle laden

Während meines jetzigen Projektes hatte ich schon öfter folgende Aufgabe zu lösen: wie bekomme ich denn alle Records eines Datenblocks in eine PL/SQL-Tabelle ? Um damit z.B. andere Berechnungen durchzuführen, Plausibilitäten darüber laufen zu lassen oder andere Listen zu füllen.

Nachdem ich das ein paar Mal gemacht habe, wollte ich mein Vorgehen dabei zum Besten geben.
Wenn man den gesamten Code noch in ein Forms-Package steckt, ist die PL/SQL-Tabelle auch von anderen Codestellen anzusprechen und zu benutzen.

Dafür bastel ich mehr zu allererst einen Record, mit allen Feldern, die ich brauche und darauf basierend eine PL/SQL-Tabelle und eine konkrete Instanz der entsprechenden Speicherstruktur:

   TYPE mein_Record_T IS RECORD (
    Feld1         VARCHAR2(250),
    Feld2         NUMBER := 0,
    Feld3         VARCHAR2(5)
    );

TYPE meine_PLSQLTabelle_T IS TABLE OF mein_Record_T INDEX BY PLS_INTEGER;

meineKonkrete_PLSQLTabelle meine_PLSQLTabelle_T;

Und nun kann ich alle Datensätze des Blocks durchlaufen und in der Objekt-Struktur abspeichern:

  PROCEDURE Fuelle_meine_PLSQLTabelle(meinBlock_I IN VARCHAR2) IS
    meinIndex_V              NUMBER;
  BEGIN
    GO_BLOCK(meinBlock_I);
    FIRST_RECORD;
    LOOP
      meinIndex_V := meineKonkrete_PLSQLTabelle.COUNT;
    
      IF TRIM(NAME_IN(meinBlock_I || '.Feld1')) IS NOT NULL THEN
        meineKonkrete_PLSQLTabelle(meinIndex_V).Feld1 := NAME_IN(meinBlock_I || '.Feld1');
        meineKonkrete_PLSQLTabelle(meinIndex_V).Feld2 := NAME_IN(meinBlock_I || '.Feld2');
        meineKonkrete_PLSQLTabelle(meinIndex_V).Feld3 := NAME_IN(meinBlock_I || '.Feld3');
      END IF;
      
      EXIT WHEN :SYSTEM.LAST_RECORD = 'TRUE';
      NEXT_RECORD;
    END LOOP;     
  END Fuelle_meine_PLSQLTabelle;

Dieses Konstrukt konnte ich nun schon ein paar Mal gebrauchen, um mir das Leben mit Daten aus den Datenblöcken zu vereinfachen. Denn ich musste immer alle Daten haben, um damit z.B. andere Daten bewerten zu können. Wenn natürlich die Datenblöcke viele Daten enthalten, dauert der ganze Fetch entsprechend länger. Davon ist meine Maske aber nicht betroffen, und so helfen diese paar Zeilen Code mir ungemein.

Schöne Grüße
Holger