Sök…


Introduktion

TEMP-TABLE är en mycket kraftfull funktion i Progress ABL. Det är en tillfällig tabell i minnet (mestadels åtminstone) som kan användas för att skriva komplex logik. Det kan användas som input / output-parametrar för procedurer, funktioner och andra program. En eller flera temp-tabeller kan utgöra grunden för en DATASET (ofta kallad ProDataset).

Nästan allt som kan göras med en inbyggd Progress-databasstabell kan göras med en temp-tabell.

Definiera ett enkelt temp-bord

Detta är definitionen av en TEMP-TABLE namnet ttTempTable med tre fält. NO-UNDO indikerar att ingen ångra hantering behövs (det är vanligtvis vad du vill göra om du inte behöver motsatsen).

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

En temp-tabell med ett index

Temp-tabeller kan (och borde) skapas med index om du planerar att utföra frågor mot dem.

Denna tabell har ett index (index1) som innehåller ett fält (fält1). Detta index är primärt och unikt (vilket betyder att inte två poster kan ha samma fältinnehåll).

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

Fler index - index ...

Du kan definiera flera index för varje temp-tabell. Om du behöver dem - definiera dem. I grund och botten ett index som matchar din fråga och / eller sorteringsordning hjälper till att prestera!

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.

ange bildbeskrivning här

Sökningen med index var ungefär 70 gånger snabbare jämfört med inget index! Detta är naturligtvis bara en körning så inte ett vetenskapligt bevis, men din indexinställning kommer att påverka.

Mata in och mata ut temp-tabeller

Det är väldigt enkelt att skicka temp-tabeller in och ut ur program, procedurer och funktioner.

Detta kan vara praktiskt om du vill ha en procedur för att behandla ett större antal data än du enkelt kan lagra i en sträng eller liknande. Du kan skicka temp-tabeller som INPUT , OUTPUT och INPUT-OUTPUT data.

Lägga in ett temp-bord och mata ut ett annat:

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.

Resultat:

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

B             A
C             B
D             C

Matar in en temp-tabell:

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.

Resultat:

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

         3                4             5.00
         6                8            10.00
        12               16            20.00

Vidarebefordras till funktioner

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.

Skickar till programfiler

Du skickar temp-tabeller till och från andra .p-program på samma sätt som du skickar dem till andra procedurer. Den enda skillnaden är att både det anropande och det anropade programmet måste ha samma temp-tabelldeklaration. Ett enkelt sätt är att lagra temp-tabellprogrammet i en tredje fil - en inkludering som används i båda programmen.

Inkludera fil som innehåller temp-tabellsdefinition: / * ttFile.i * / DEFINE TEMP-TABLE ttFile NO-UNDO FIELD fName AS CHARACTER FORMAT "x (20)" FIELD isADirectory AS LOGICAL.

Program kontrollera alla filer i en temp-tabell. Är det kataloger?

/* 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.

Huvudprogram:

{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.

Resultat:

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

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


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow