Recherche…


Introduction

Le TEMP-TABLE est une fonctionnalité très puissante de Progress ABL. C'est une table temporaire en mémoire (surtout du moins) qui peut être utilisée pour écrire une logique complexe. Il peut être utilisé comme paramètre d'entrée / sortie pour des procédures, des fonctions et d'autres programmes. Une ou plusieurs tables temporaires peuvent constituer la base d'un DATASET (souvent appelé ProDataset).

Presque tout ce qui peut être fait avec une table de base de données Progress native peut être fait avec une table temporaire.

Définir une table temporaire simple

C'est la définition d'un TEMP-TABLE nommé ttTempTable avec trois champs. NO-UNDO indique qu'aucune gestion d'annulation n'est nécessaire (c'est généralement ce que vous voulez faire, sauf si vous avez vraiment besoin du contraire).

DEFINE TEMP-TABLE ttTempTable NO-UNDO
    FIELD field1 AS INTEGER
    FIELD field2 AS CHARACTER
    FIELD field3 AS LOGICAL.

Une table temporaire avec un index

Les tables temporaires peuvent (et doivent) être créées avec des index si vous prévoyez d'exécuter des requêtes sur ces dernières.

Cette table a un index (index1) contenant un champ (field1). Cet index est primaire et unique (ce qui signifie que deux enregistrements ne peuvent pas avoir le même contenu que field1).

DEFINE TEMP-TABLE ttTempTable NO-UNDO
    FIELD field1 AS INTEGER
    FIELD field2 AS CHARACTER
    FIELD field3 AS LOGICAL
    INDEX index1 IS PRIMARY UNIQUE field1 .

Plus d'index - index ...

Vous pouvez définir plusieurs index pour chaque table temporaire. Si vous en avez besoin, définissez-les. Fondamentalement, un index correspondant à votre requête et / ou à votre ordre de tri aidera à la performance!

DEFINE TEMP-TABLE ttWithIndex NO-UNDO
    FIELD field1 AS INTEGER
    FIELD field2 AS CHARACTER
    FIELD field3 AS LOGICAL
    INDEX field1 field1.

DEFINE TEMP-TABLE ttWithoutIndex NO-UNDO
    FIELD field1 AS INTEGER
    FIELD field2 AS CHARACTER
    FIELD field3 AS LOGICAL.

DEFINE VARIABLE i              AS INTEGER     NO-UNDO.
DEFINE VARIABLE iWithCreate    AS INTEGER     NO-UNDO.
DEFINE VARIABLE iWithFind      AS INTEGER     NO-UNDO.
DEFINE VARIABLE iWithoutCreate AS INTEGER     NO-UNDO.
DEFINE VARIABLE iWithoutFind   AS INTEGER     NO-UNDO.

ETIME(TRUE).
DO i = 1 TO 1000:
    CREATE ttWithIndex.
    ttWithIndex.field1 = i.
END.
iWithCreate = ETIME.

ETIME(TRUE).
DO i = 1 TO 1000:
    CREATE ttWithoutIndex.
    ttWithoutIndex.field1 = i.
END.
iWithoutCreate = ETIME.

RELEASE ttWithIndex.
RELEASE ttWithoutIndex.

ETIME(TRUE).
DO i = 1 TO 1000:
    FIND FIRST ttWithIndex WHERE ttWithIndex.field1 = i NO-ERROR.
END.
iWithFind = ETIME.

ETIME(TRUE).
DO i = 1 TO 1000:
    FIND FIRST ttWithoutIndex WHERE ttWithoutIndex.field1 = i NO-ERROR.
END.
iWithoutFind = ETIME.

MESSAGE 
    "With index took" iWithFind "ms to find and" iWithCreate "ms to create" SKIP 
    "Without index took" iWithoutFind "ms to find and" iWithoutCreate "ms to create"
    VIEW-AS ALERT-BOX.

entrer la description de l'image ici

La recherche avec index était environ 70 fois plus rapide que celle sans index! Il ne s’agit là que d’un essai, et non d’une preuve scientifique, mais la configuration de votre index aura un impact.

Saisie et sortie de tables temporaires

Il est très simple de faire passer des tables temporaires dans et hors des programmes, des procédures et des fonctions.

Cela peut être pratique si vous souhaitez qu'une procédure traite un plus grand nombre de données que vous ne pouvez facilement stocker dans une chaîne ou un objet similaire. Vous pouvez passer des tables temporaires sous forme de données INPUT , OUTPUT et INPUT-OUTPUT .

Entrer une table temporaire et en générer une autre:

DEFINE TEMP-TABLE ttRequest NO-UNDO
    FIELD fieldA AS CHARACTER
    FIELD fieldB AS CHARACTER.

/* Define a temp-table with the same fields and indices */
DEFINE TEMP-TABLE ttResponse NO-UNDO LIKE ttRequest.

/* A procedure that simply swap the values of fieldA and fieldB */
PROCEDURE swapFields:
    DEFINE INPUT  PARAMETER TABLE FOR ttRequest.
    DEFINE OUTPUT PARAMETER TABLE FOR ttResponse.

    FOR EACH ttRequest:
        CREATE ttResponse.
        ASSIGN 
            ttResponse.fieldA = ttRequest.fieldB
            ttResponse.fieldB = ttRequest.fieldA.
    END.
END PROCEDURE.

CREATE ttRequest.
ASSIGN ttRequest.fieldA = "A"
       ttRequest.fieldB = "B".

CREATE ttRequest.
ASSIGN ttRequest.fieldA = "B"
       ttRequest.fieldB = "C".

CREATE ttRequest.
ASSIGN ttRequest.fieldA = "C"
       ttRequest.fieldB = "D".

/* Call the procedure */
RUN swapFields ( INPUT  TABLE ttRequest
               , OUTPUT TABLE ttResponse).

FOR EACH ttResponse:
    DISPLAY ttResponse.
END.

Résultat:

fieldA--------fieldB--------

B             A
C             B
D             C

Entrée-sortie d'une table temporaire:

DEFINE TEMP-TABLE ttCalculate NO-UNDO
    FIELD num1     AS INTEGER
    FIELD num2     AS INTEGER
    FIELD response AS DECIMAL.

PROCEDURE pythagoras:
    DEFINE INPUT-OUTPUT PARAMETER TABLE FOR ttCalculate.

    FOR EACH ttCalculate:
        ttCalculate.response = SQRT( EXP(num1, 2) + EXP(num2, 2)).
    END.

END PROCEDURE.

CREATE ttCalculate.
ASSIGN ttCalculate.num1 = 3
       ttCalculate.num2 = 4.

CREATE ttCalculate.
ASSIGN ttCalculate.num1 = 6
       ttCalculate.num2 = 8.

CREATE ttCalculate.
ASSIGN ttCalculate.num1 = 12
       ttCalculate.num2 = 16.

/* Call the procedure */
RUN pythagoras ( INPUT-OUTPUT  TABLE ttCalculate ).

FOR EACH ttCalculate:
    DISPLAY ttCalculate.
END.

Résultat:

----------num1-- ----------num2-- -------response-

         3                4             5.00
         6                8            10.00
        12               16            20.00

Passage aux fonctions

DEFINE TEMP-TABLE ttNumbers NO-UNDO
    FIELD num1     AS INTEGER
    FIELD num2     AS INTEGER
    INDEX index1 num1 num2.

DEFINE VARIABLE iNum AS INTEGER     NO-UNDO.

/* Forward declare the function */
FUNCTION hasAPair RETURNS LOGICAL (INPUT TABLE ttNumbers) FORWARD.

DO iNum = 1 TO 100:
    CREATE ttNumbers.
    ASSIGN ttNumbers.num1 = RANDOM(1,100)
           ttNumbers.num2 = RANDOM(1,100).
END.

MESSAGE hasAPair(INPUT TABLE ttNumbers) VIEW-AS ALERT-BOX.


/* Function to check if two records has the same value in num1 and num2 */
FUNCTION hasAPair RETURNS LOGICAL (INPUT TABLE ttNumbers):

    FIND FIRST ttNumbers WHERE ttNumbers.num1 = ttNumbers.num2 NO-ERROR.
    IF AVAILABLE ttNumbers THEN
        RETURN TRUE.
    ELSE 
        RETURN FALSE.

END FUNCTION.

Passer aux fichiers de programme

Vous transmettez les tables temporaires vers et depuis d'autres programmes .p de la même manière que vous les transmettez à d'autres procédures. La seule différence est que l'appelant et le programme appelé doivent avoir la même déclaration de table temporaire. Un moyen simple consiste à stocker le programme de la table temporaire dans un troisième fichier - une inclusion utilisée dans les deux programmes.

Fichier d'inclusion contenant la définition de la table temporaire: / * ttFile.i * / DEFINE TEMP-TABLE ttFichier NON-UNDO FIELD fName AS FORMAT DE CARACTERE "x (20)" FIELD isAdirectory AS LOGICAL.

Programme vérifiant tous les fichiers d'une table temporaire. Sont-ils des répertoires?

/* checkFiles.p */
{ttFile.i}

DEFINE INPUT-OUTPUT PARAMETER TABLE FOR ttFile.

FOR EACH ttFile:
    FILE-INFO:FILE-NAME = ttFile.fName.

    IF FILE-INFO:FILE-TYPE BEGINS "D" THEN
        ttFile.isADirectory = TRUE.
END.

Programme principal:

{ttFile.i}

CREATE ttFile.
ASSIGN ttFile.fname = "c:\temp\".

CREATE ttFile.
ASSIGN ttFile.fname = "c:\Windows\".

CREATE ttFile.
ASSIGN ttFile.fname = "c:\Windoose\".

RUN checkFiles.p(INPUT-OUTPUT TABLE ttFile).

FOR EACH ttFile:
    DISPLAY ttFile.
END.

Résultat:

fName----------------- isADirector

c:\temp\               yes
c:\Windows\            yes
c:\Windoose\           no


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow