progress-4gl
TEMP-TABLE
サーチ…
前書き
TEMP-TABLE
は、Progress ABLの非常に強力な機能です。これは、複雑なロジックを書くために使用できる一時的なメモリ内(ほとんどの場合は少なくともテーブル)です。プロシージャ、関数、およびその他のプログラムへの入出力パラメータとして使用できます。 1つまたは複数の一時テーブルがDATASET
(ProDatasetとも呼ばれます)の基盤を構成できDATASET
。
ネイティブのプログレスデータベーステーブルで実行できるほとんどのものは、テンポラリテーブルで実行できます。
簡単な一時テーブルの定義
これは、3つのフィールドを持つttTempTableという名前のTEMP-TABLE
定義です。 NO-UNDO
は、元に戻す処理が必要ないことを示します(これは、本当に逆の処理が必要でない限り、通常はやりたいことです)。
DEFINE TEMP-TABLE ttTempTable NO-UNDO
FIELD field1 AS INTEGER
FIELD field2 AS CHARACTER
FIELD field3 AS LOGICAL.
インデックス付きのテンポラリテーブル
テンポラリテーブルは、クエリを実行する予定の場合は、インデックスを使用して作成できます(また、作成する必要があります)。
このテーブルには、1つのフィールド(field1)を含む1つのインデックス(index1)があります。このインデックスはプライマリでユニークです(つまり、2つのレコードが同じ内容のフィールド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倍高速でした!これはコースの1つで、科学的な証拠ではありませんが、インデックス設定が影響を与えます。
テンポラリテーブルの入力と出力
テンポラリテーブルをプログラム、プロシージャ、関数の内外に渡すことは非常に簡単です。
これは、手続きが文字列などに簡単に格納できるよりも多くのデータを処理する場合に便利です。テンポラリテーブルは、 INPUT
、 OUTPUT
、およびINPUT-OUTPUT
データとして渡すことができます。
1つの一時テーブルを入力して別のテーブルを出力する:
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-プログラムとの間で一時テーブルを渡すのと同じ方法で他のプロシージャに渡します。唯一の違いは、呼び出し元プログラムと呼び出されたプログラムの両方が同じ一時テーブル宣言を持たなければならないことです。 1つの簡単な方法は、temp-tableプログラムを第3のファイルに格納することです。これは、両方のプログラムで使用されるインクルードです。
テンポラリテーブルの定義を含むファイルをインクルードする:/ * ttFile.i * / DEFINE TEMP-TABLE ttFile NO-UNDO FIELD fName AS CHARACTER FORMAT "x(20)" FIELDは、AS AS LOGICALとなります。
テンポラリテーブル内のすべてのファイルをチェックするプログラム。彼らはディレクトリですか?
/* 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