The following programs demonstrate the use of the RDB$DB_KEY value expression in a record selection expression. The programs sort the EMPLOYEES relation in ascending order of employee ID. Then, using the first 100 records from the sorted EMPLOYEES relation, the programs build two arrays: rdb_key_array and rdb_ name_array. In building these arrays within a FOR statement, these programs create a one-to-one correspondence between the elements in the rdb_key_array and the rdb_name_array. Each time a new element is added to each of these arrays the next EMPLOYEES record from the sorted stream is printed. This one-to-one correspondence allows the programs to step through the EMPLOYEES records indirectly. This is demonstrated in the second FOR statement. The second FOR statement loops through the rdb_key_array in reverse order; each time the address of an array element in rdb_key_array is incremented, an EMPLOYEES record is accessed (also in reverse sorted order) and the employee's last name is printed.
1 – C Example
#include <stdio.h> DATABASE PERS = FILENAME "PERSONNEL"; main() { DECLARE_VARIABLE rdb_key_array[100] SAME AS EMPLOYEES.RDB$DB_KEY; DECLARE_VARIABLE rdb_name_array[100] SAME AS EMPLOYEES.LAST_NAME; int cnt = 0; READY PERS; START_TRANSACTION READ_ONLY; FOR FIRST 100 E IN EMPLOYEES SORTED BY E.EMPLOYEE_ID rdb_key_array[cnt] = E.RDB$DB_KEY; strcpy (rdb_name_array[cnt], E.LAST_NAME); printf("%s - 1st pass\n", E.LAST_NAME); ++cnt; END_FOR; for ( cnt = --cnt; cnt >= 0; --cnt) FOR E IN EMPLOYEES WITH E.RDB$DB_KEY = rdb_key_array[cnt] if ( strcmp( E.LAST_NAME, rdb_name_array[cnt]) != 0 ) printf("%s DOES NOT MATCH %s\n", E.LAST_NAME, rdb_name_array[cnt]); else printf("%s - 2nd pass\n", E.LAST_NAME); END_FOR; COMMIT; FINISH; }
2 – Pascal Example
program db_key (input,output); DATABASE PERS = FILENAME 'PERSONNEL'; type Rdb_Key_Type = BASED ON EMPLOYEES.RDB$DB_KEY; Rdb_Name_Type = BASED ON EMPLOYEES.LAST_NAME; var Rdb_Key_Array : ARRAY [1..101] OF Rdb_Key_Type; Rdb_Name_Array : ARRAY [1..101] OF Rdb_Name_Type; Cnt : INTEGER := 1; begin READY PERS; START_TRANSACTION READ_ONLY; FOR FIRST 100 E IN EMPLOYEES SORTED BY E.EMPLOYEE_ID Rdb_Key_Array[Cnt] := E.RDB$DB_KEY; Rdb_Name_Array[Cnt] := E.LAST_NAME; WRITELN(E.LAST_NAME, ' - 1st pass'); Cnt := Cnt + 1; END_FOR; for Cnt := Cnt - 1 downto 1 do FOR E IN EMPLOYEES WITH E.RDB$DB_KEY = Rdb_Key_array[Cnt] if E.LAST_NAME <> Rdb_Name_Array[Cnt] then writeln (E.LAST_NAME, 'DOES NOT MATCH', Rdb_Name_Array[Cnt]) else writeln (E.LAST_NAME, ' - 2nd pass'); END_FOR; COMMIT; FINISH; end.