progress-4gl
TEMP-TABLE
Zoeken…
Invoering
De TEMP-TABLE
is een zeer krachtige functie van Progress ABL. Het is een tijdelijke in-memory-tabel (meestal tenminste) die kan worden gebruikt voor het schrijven van complexe logica. Het kan worden gebruikt als invoer / uitvoerparameters voor procedures, functies en andere programma's. Een of meer tijdelijke tabellen kunnen de basis vormen voor een DATASET
(vaak ProDataset genoemd).
Bijna alles wat met een native Progress-databasetabel kan worden gedaan, kan met een tijdelijke tabel worden gedaan.
Een eenvoudige tijdelijke tabel definiëren
Dit is de definitie van een TEMP-TABLE
naam ttTempTable met drie velden. NO-UNDO
geeft aan dat ongedaan maken niet nodig is (dit is meestal wat u wilt doen, tenzij u echt het tegenovergestelde nodig hebt).
DEFINE TEMP-TABLE ttTempTable NO-UNDO
FIELD field1 AS INTEGER
FIELD field2 AS CHARACTER
FIELD field3 AS LOGICAL.
Een tijdelijke tabel met een index
Temp-tabellen kunnen (en moeten) worden gemaakt met indices als u van plan bent om er query's op uit te voeren.
Deze tabel heeft één index (index1) met één veld (veld1). Deze index is primair en uniek (wat betekent dat niet twee records dezelfde inhoud van veld1 kunnen hebben).
DEFINE TEMP-TABLE ttTempTable NO-UNDO
FIELD field1 AS INTEGER
FIELD field2 AS CHARACTER
FIELD field3 AS LOGICAL
INDEX index1 IS PRIMARY UNIQUE field1 .
Meer indexen - indices ...
U kunt meerdere indices definiëren voor elke tijdelijke tabel. Als u ze nodig hebt, definieer ze dan. Kortom, een index die overeenkomt met uw zoekopdracht en / of sorteervolgorde zal de prestaties helpen!
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.
Zoeken met index was ongeveer 70 keer sneller in vergelijking met geen index! Dit is natuurlijk maar één run, dus geen wetenschappelijk bewijs, maar uw indexopstelling heeft impact.
Temp-tabellen invoeren en uitvoeren
Het is heel eenvoudig om tijdelijke tabellen in en uit programma's, procedures en functies door te geven.
Dit kan handig zijn als u wilt dat een procedure een groter aantal gegevens verwerkt dan u eenvoudig kunt opslaan in een string of iets dergelijks. U kunt tijdelijke tabellen doorgeven als INPUT
, OUTPUT
en INPUT-OUTPUT
gegevens.
Een tijdelijke tabel invoeren en een andere uitvoeren:
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.
Resultaat:
fieldA--------fieldB--------
B A
C B
D C
Invoer-uitvoer van een tijdelijke tabel:
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.
Resultaat:
----------num1-- ----------num2-- -------response-
3 4 5.00
6 8 10.00
12 16 20.00
Overgaan naar functies
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.
Doorgeven aan programmabestanden
U geeft tijdelijke tabellen door aan en van andere .p-programma's op dezelfde manier als u ze doorgeeft aan andere procedures. Het enige verschil is dat zowel het aanroepende als het opgeroepen programma dezelfde tijdelijke declaratietabel moeten hebben. Een eenvoudige manier is om het tijdelijke tabelprogramma op te slaan in een derde bestand - een opname die in beide programma's wordt gebruikt.
Neem een bestand op dat de temp-tabeldefinitie bevat: / * ttFile.i * / DEFINE TEMP-TABLE ttFile NO-UNDO FIELD fName ALS KARAKTERFORMAAT "x (20)" FIELD isADirectory AS LOGICAL.
Programma dat alle bestanden in een tijdelijke tabel controleert. Zijn ze mappen?
/* 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.
Hoofdprogramma:
{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.
Resultaat:
fName----------------- isADirector
c:\temp\ yes
c:\Windows\ yes
c:\Windoose\ no