Buscar..


Introducción

El TEMP-TABLE es una característica muy poderosa de Progress ABL. Es una tabla temporal en memoria (en su mayoría al menos) que se puede usar para escribir lógica compleja. Puede utilizarse como parámetros de entrada / salida para procedimientos, funciones y otros programas. Una o más tablas temporales pueden constituir la base de un DATASET (a menudo llamado ProDataset).

Casi todo lo que se puede hacer con una tabla nativa de la base de datos Progress se puede hacer con una tabla temporal.

Definiendo una tabla de temperatura simple

Esta es la definición de una TEMP-TABLE llamada ttTempTable con tres campos. NO-UNDO indica que no se necesita deshacer el manejo (esto suele ser lo que quieres hacer a menos que realmente necesites lo contrario).

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

Una tabla temporal con un índice.

Las tablas temporales pueden (y deben) crearse con índices si planea ejecutar consultas contra ellos.

Esta tabla tiene un índice (índice1) que contiene un campo (campo1). Este índice es primario y único (lo que significa que no dos registros pueden tener el mismo contenido de campo1).

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

Más índices - índices ...

Puede definir múltiples índices para cada tabla temporal. Si los necesitas, defínelos. ¡Básicamente, un índice que coincida con su consulta y / o orden de clasificación ayudará al rendimiento!

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.

introduzca la descripción de la imagen aquí

¡La búsqueda con índice fue aproximadamente 70 veces más rápida en comparación con ningún índice! Por supuesto, esto es solo una ejecución, por lo que no es una prueba científica, pero la configuración de su índice tendrá impacto.

Ingreso y salida de tablas de tiempo

Es muy sencillo pasar tablas temporales dentro y fuera de los programas, procedimientos y funciones.

Esto puede ser útil si desea que un procedimiento procese una mayor cantidad de datos de los que puede almacenar fácilmente en una cadena o similar. Puede pasar tablas temporales como datos de INPUT , OUTPUT y INPUT-OUTPUT .

Ingresando una tabla temporal y generando otra:

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.

Resultado:

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

B             A
C             B
D             C

Entrada-salida de una tabla temporal:

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.

Resultado:

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

         3                4             5.00
         6                8            10.00
        12               16            20.00

Pasando a funciones

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.

Pasando a archivos de programa

Pasa tablas de tiempo hacia y desde otros programas .p ​​de la misma manera que los pasa a otros procedimientos. La única diferencia es que tanto el programa que llama como el programa llamado deben tener la misma declaración de tabla temporal. Una forma fácil es almacenar el programa de tabla temporal en un tercer archivo, una inclusión que se usa en ambos programas.

Incluya el archivo que contiene la definición de la tabla temporal: / * ttFile.i * / DEFINE TEMP-TABLE ttFile NO-UNDO FIELD fName AS CHARACTER FORMAT "x (20)" FIELD isADirectory AS LOGICAL.

Programa de comprobación de todos los archivos en una tabla temporal. ¿Son directorios?

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

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

Resultado:

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

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


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow