progress-4gl
TEMP-TABLE
Поиск…
Вступление
TEMP-TABLE
- очень мощная функция Progress ABL. Это временная в памяти (в основном, по крайней мере) таблица, которая может использоваться для написания сложной логики. Он может использоваться в качестве параметров ввода / вывода для процедур, функций и других программ. Одна или несколько temp-таблиц могут составлять основу DATASET
(часто называемого ProDataset).
Почти все, что можно сделать с помощью собственной таблицы базы данных Progress, можно выполнить с помощью temp-таблицы.
Определение простой временной таблицы
Это определение TEMP-TABLE
именем ttTempTable с тремя полями. NO-UNDO
указывает, что обработка отмены не требуется (обычно это то, что вы хотите сделать, если вам действительно не нужно обратное).
DEFINE TEMP-TABLE ttTempTable NO-UNDO
FIELD field1 AS INTEGER
FIELD field2 AS CHARACTER
FIELD field3 AS LOGICAL.
Временная таблица с индексом
Temp-таблицы могут (и должны) создаваться с индексами, если вы планируете запускать против них запросы.
Эта таблица имеет один индекс (index1), содержащий одно поле (поле1). Этот индекс является первичным и уникальным (это означает, что не две записи могут иметь одинаковое содержимое поля1).
DEFINE TEMP-TABLE ttTempTable NO-UNDO
FIELD field1 AS INTEGER
FIELD field2 AS CHARACTER
FIELD field3 AS LOGICAL
INDEX index1 IS PRIMARY UNIQUE field1 .
Больше индексов - индексы ...
Вы можете определить несколько индексов для каждой временной таблицы. Если они вам нужны - определите их. В основном индекс, соответствующий вашему запросу и / или порядку сортировки, поможет производительности!
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.
Поиск с индексом был примерно в 70 раз быстрее по сравнению с индексом! Это всего лишь один пробег, поэтому не научное доказательство, но ваша установка индекса повлияет.
Ввод и вывод временных таблиц
Очень просто передавать временные таблицы в и из программ, процедур и функций.
Это может быть удобно, если вы хотите, чтобы процедура обрабатывала большее количество данных, чем вы можете легко хранить в строке или аналогичной. Вы можете передавать временные таблицы как INPUT
, OUTPUT
и INPUT-OUTPUT
.
Ввод одной временной таблицы и вывод другой:
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.
Результат:
fieldA--------fieldB--------
B A
C B
D C
Ввод-вывод временной таблицы:
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.
Результат:
----------num1-- ----------num2-- -------response-
3 4 5.00
6 8 10.00
12 16 20.00
Переход к функциям
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.
Переход к файлам программы
Вы передаете временные таблицы в и из других .p-программ так же, как вы передаете их другим процедурам. Единственное отличие состоит в том, что и вызывающая, и вызываемая программа должны иметь одно и то же объявление temp-table. Один простой способ - сохранить программу temp-table в третьем файле - include, который используется в обеих программах.
Включить файл, содержащий определение временной таблицы: / * ttFile.i * / DEFINE TEMP-TABLE ttFile NO-UNDO FIELD fName AS CHARACTER FORMAT "x (20)" FIELD isADirectory AS LOGICAL.
Программа проверяет все файлы в таблице temp. Это каталоги?
/* 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.
Основная программа:
{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.
Результат:
fName----------------- isADirector
c:\temp\ yes
c:\Windows\ yes
c:\Windoose\ no