Digital PDFs
Documents
Guest
Register
Log In
AA-X023B-TK
November 1987
246 pages
Original
8.6MB
view
download
Document:
DATATRIEVE-11 Users Guide Nov87
Order Number:
AA-X023B-TK
Revision:
0
Pages:
246
Original Filename:
AA-X023B-TK_DATATRIEVE-11_Users_Guide_Nov87.pdf
OCR Text
DATATRIEVE-11 User's Guide Order No. AA-X023B-TK November 1987 This document tells how to use DATATRIEVE-I1. OPERATING SYSTEMS: RSX-IIM RSXIIM-PLUS RSTS/E MicrolRSX MicrolRSTS VMS with VAX-II RSX SOFTWARE VERSION: DATATRIEVE-II V3.2 digital equipment corporation, maynard, massachusetts The information in this document is subject to change without notice and should not be construed as a commitment by Digital Equipment Corporation. Digital Equipment Corporation assumes no responsibility for any errors that may appear in this document. The software described in this document is furnished under a license and may be used or copied only in accordance with the terms of such license. No responsibility is assumed for the use or reliability of software on equipment that is not supplied by DIGITAL or its affiliated companies. Copyright © 1983,1987 by Digital Equipment Corporation. All Rights Reserved. The postage-paid Reader's Comments forms at the end of this document request your critical evaluation to assist us in preparing future documentation. The following are trademarks of Digital Equipment Corporation: ~DmDDmD ™ ACMS CDD DATATRIEVE DEC DECnet DECUS Micro/RSTS Micro/RSX MicroVAX MicroVMS PDP RALLY Rdb/ELN Rdb/VMS ReGIS RSTS RSX TDMS TEAMDATA UNIBUS VAX VAXc1uster VAXinfo VAX Information Architecture VAXNMS VMS VT Contents Page How to Use This Manual Xl· 1 Introduction to DATATRIEVE-11 1.1 1.2 Description ofDATATRIEVE-ll DATATRIEVE Concepts and Terms · 1-1 · 1-1 Files . . . . . .. Record Definitions Domains . . . . . Data Dictionaries Commands and Statements Procedures . . . . .. Command Files .... DATATRIEVE Tables · 1-2 · 1-2 · 1-2 · 1-3 · 1-3 · 1-4 · 1-4 · 1-4 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.3 Components ofDATATRIEVE-ll · 1-5 1.3.1 1.3.2 1.3.3 1.3.4 · 1-5 · 1-5 · 1-6 · 1-6 Interactive DATATRIEVE The DATATRIEVE Distributed Server The DATATRIEVE-ll Call Interface . The DATATRIEVE-ll Remote Terminal Interface 2 Getting Started with DATATRIEVE 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 Invoking DATATRIEVE-ll . . . . Sample Domains, Records, and Data Files . QUERY.INI Startup File . . . . . . . . . Using READY, PRINT, and REPORT to Retrieve Data DATATRIEVE Input Line Prompts . . . . . . . . . . DATATRIEVE Syntax Line Prompts . . . . . . . . . DATATRIEVE Prompts for Storing and Modifying Values DATATRIEVE Error Messages . . . Ending Your DATATRIEVE Session . . . . . . . 2.9.1 2.9.2 2.9.3 2.10 2.11 Using the EXIT Command . . . . . . . . Exiting from DATATRIEVE with CTRL/Z Exiting from DATATRIEVE by Pressing CTRL/C Two Times · 2-1 2-2 · 2-2 · 2-3 · 2-4 · 2-5 · 2-5 · 2-5 · 2-6 ~ · 2-6 · 2-6 · 2-6 Using Help . . . . . . . . . . · 2-6 2.10.1 · 2-7 Using Advanced Help Guide Mode ..... . · 2-8 3 Creating Data Dictionaries 3.1 3.2 3.3 Contents of a Data Dictionary. Creating a Data Dictionary Changing Dictionaries . . . . · 3-1 · 3-2 · 3-2 iii 4 Defining Domains 4.1 4.2 4.3 Specifying Domain Names . . . . . . . . Defining a Simple RMS Domain. . . . . . U sing the SHOW Command with Domains · 4-1 · 4-2 · 4-3 5 Defining Records 5.1 5.2 5.3 Planning a Record Definition . . . . . . Getting Started and Naming a Record .. Defining the Parts of a Record Definition · 5-1 · 5-2 · 5-3 5.3.1 5.3.2 Specifying Level Numbers . . . Naming Fields . . . . . . . . . · 5-4 · 5-6 5.3.2.1 5.3.2.2 5.3.2.3 · 5-6 · 5-7 · 5-8 5-10 5-12 5-13 5.3.3 5.3.4 5.3.5 5.4 Restrictions for Field Names . Using Duplicate Field Names Using the Field Name FILLER U sing Field Definition Clauses . . . . . . Specifying Query Names . . . . . . . . . Specifying Word Boundary Alignment with the ALLOCATION Clause U sing the OCCURS Clause to Define Hierarchical Records 5-13 5.4.1 5.4.2 5.4.3 5.4.4 5-15 5-16 5-17 5-18 Defining Lists with a Fixed Number of Occurrences .. Defining Lists with a Variable Number of Occurrences Nesting Lists Within Lists to Form Sublists . Changing the Length of a List . . . . . . . . . . . . 6 Defining Files 6.1 6.2 Choosing a Sequential or an Indexed File · 6-1 6.1.1 6.1.2 Modifying and Deleting Records Summary of Differences . . . . · 6-2 · 6-2 Defining a File Using the DEFINE FILE Command · 6-3 6.2.1 6.2.2 Defining a Sequential File . . . . . . . . Defining an Indexed File . . . . . . . . . · 6-3 · 6-4 6.2.2.1 6.2.2.2 6.2.2.3 Using a Group Field as the Primary Key Defining Alternate Keys . . . . . . . . Summary of Rules for Defining Key Fields · 6-5 · 6-5 · 6-6 Optional Clauses with the DEFINE FILE Command · 6-6 6.2.3 7 Limiting Record Streams with Record Selection Expressions 7.1 7.2 7.3 iv Accessing All the Records in a Domain . . . . . . . . Specifying the Number of Records in the Record Stream Identifying Records with Conditional Expressions . . . · 7-4 7.3.1 7.3.2 7.3.3 · 7-6 · 7-7 Comparing Records by Pattern Recognition . . Grouping Records When Values Fall Within a Range Grouping Records by Reference to a Table . . . . . · 7-2 · 7-3 · 7-4 7.3.4 7.3.5 7.4 Summary of the Relational Operators . . . . . . . Setting Up Multiple Tests with Compound Booleans Sorting the Record Stream by Field Values · 7-7 · 7-8 · 7-9 8 Using Compound Statements 8.1 8.2 8.3 Using REPEAT to Combine Statements . . . . . . Using the FOR Statement . . . . . . . . . . . . Using BEGIN-END Blocks to Combine Statements · 8-1 · 8-3 · 8-4 8.3.1 8.3.2 8.3.3 8.3.4 · 8-4 · 8-5 · 8-5 · 8-6 BEGIN-END Blocks in FOR Statements . IF-THEN-ELSE Statements in BEGIN-END Blocks Using BEGIN-END Blocks in STORE Statements BEGIN-END Blocks in REPEAT Statements 9 Using DATATRIEVE Procedures 9.1 9.2 9.3 Defining a Procedure Invoking a Procedure. Contents of a Procedure . 9.3.1 9.3.2 9.3.3 9.4 9.5 9.6 9.7 9.8 9.9 Using Procedures to Locate Errors A Sample Procedure Nesting Procedures . U sing a Procedure in a Compound Statement Aborting Procedures Maintaining Procedures 9.9.1 9.9.2 9.10 Commands and Statements in Procedures Arguments and Clauses Comments in Procedures . Displaying Procedure Names . Displaying Complete Procedures Editing Procedures 9.10.1 Deleting Procedures · 9-1 · 9-2 · 9-3 · 9-4 · 9-4 · 9-5 · 9-6 · 9-7 · 9-9 9-10 9-12 9-13 9-14 9-14 9-14 9-15 10 Using DATATRIEVE COl!1mand Files 10.1 10.2 10.3 10.4 10.5 10.6 10.7 10.8 10.9 Creating a Command File . . . . Contents of a Command File . . 10-2 10-3 10.2.1 10.2.2 10-3 10-3 ADT, EDIT, SET GUIDE Comments.... Invoking a Command File 10-3 10.3.1 10.3.2 10-4 10-4 Invocation Command Lines Invoking a Command File from a Procedure Aborting Command Files Editing a Command File . . . . . . . . . . . . Sample Command File . . . . . . . . . . . . . Nesting Command Files Within Command Files. Using a Command File in a FOR or REPEAT Statement . Maintaining Command Files . . . . . . . . . . . . . . 10-5 10-5 10-6 10-7 10-8 10-9 v 11 Using DATATRIEVE Variables 11.1 11.2 11.3 Declaring Variables. . . . . Assigning Values to Variables. Local and Global Variables 11-1 11-2 11-3 Global Variables . . . Local Variables . . . 11-4 11-4 11.3.1 11.3.2 11.4 11.5 Using Variables to Assign Values to Fields Using Variables as Counters to Control Record Streams 11-5 11-6 12 Using DATATRIEVE Tables 12.1 12.2 12.3 12.4 A Sample Dictionary Table . . \ Creating Dictionary Tables Sample Dictionary Tables . Using the IN Relational Operator with DATATRIEVE Tables 12-1 12-3 12-4 12-5 12.4.1 12-5 Using a Table in a Record Selection Expression . 12.4.1.1 12.4.1.2 12.4.2 12.5 12.6 Using the Keyword VIA with DATATRIEVE Tables 12-5 12-6 12-6 DATATRIEVE Tables and Workspace Displaying Table Information . 12-7 12-7 Displaying Tables Editing Tables . . . Deleting Tables . . 12-7 12-8 12-9 Protecting Dictionary Tables 12-9 12.6.1 12.6.2 12.6.3 12.7 Using a Table to Set Conditions in an IF-THEN-ELSE Statement . . . . . . . . . . . . . . Using a VALID IF Clause with a Table to Validate Data 13 Defining and Using Views 13.1 13.2 Defining Views . . . . . 13-2 13.1.1 13.1.2 13.1.3 13-3 13-3 13-4 Views Using Subsets of Records Views Using Subsets of Fields . Views Using More Than One Domain . U sing a View Domain. . . . . . . . . . . 13-6 13.2.1 13-7 Using a View That Contains a List 14 USing Hierarchies 14.1 14.2 14.3 14.4 14.5 vi Retrieving Repeating Field Values with FIND and SELECT Statements Retrieving Repeating Field Values with Nested FOR Loops . . . . . . Retrieving Repeating Field Values with Inner Print Lists . . . . . . . Retrieving List Items with Nested RSEs - Eliminating Empty Print Lines . Retrieving Values from Sublists . . . . . . . . . . . . . . . . . . . . . . 14-3 14-4 14-5 14-9 14-11 15 Restructuring Domains 15.1 15.2 15.3 15.4 A Sample Domain . . . . . . . . . . . . . . . . . . . . . Changing Record and File Definitions and Using New Names 15-2 15-3 15.2.1 15.2.2 15.2.3 15-4 15-5 15-5 Storing Data from All the Records in the Old Domain Storing Data from a Subset of the Records in the Old Domain Deleting References to the Old Domain . . . . . . . Changing Record and File Definitions and Using Old Names. Changing the Organization of a Data File . . . . . . . . . . 15-5 15-8 16 Using the DATATRIEVE Editor 16.1 16.2 16.3 16.4 16.5 Invoking the Editor . Editor Modes . . . . Line Pointer .... Range Specification . Editor Commands DELETE Command EXIT Command .. INSERT Command QUIT Command . . REPLACE Command SUBSTITUTE Command TYPE Command . 16-5 16-6 16-6 16-8 16-9 16-10 16-11 Sample Editing Session . . . . . . 16-13 16.5.1 16.5.2 16.5.3 16.5.4 16.5.5 16.5.6 16.5.7 16.6 16-1 16-2 16-2 16-3 16-4 17 Optimizing Workspace and Response Time 17.1 17.2 17.3 17.4 Using Workspace . . . . . . . . . . . . . . Effect of READY and FINISH on Workspace. Techniques to Optimize Workspace . . . . . Techniques to Optimize Response Time . . . 17.4.1 17.4.2 Using the ALLOCATION Option of the DEFINE FILE Command Using Keyed Access Efficiently . . . . . . . . . . . . . . . . 17.4.2.1 17.4.2.2 17.4.2.3 17.4.2.4 17.4.3 Using EQUAL Rather Than CONTAINING . . . . Choosing Domains or Collections as Record Sources Ordering the Domains in Nested FOR Loops . . . . Restoring Indexed Files That Are Often Modified . . Avoiding Nested FOR Loops Followed by a Conditional Statement 17-1 17-1 17-5 17-6 17-6 17-6 17-7 17-8 17-8 17-8 17-9 18 Controlling Output 18.1 18.2 18.3 Changing the Columns-Page Setting 18-1 18.1.1 18.1.2 18.1.3 Increasing the Columns-Page Setting. Decreasing the Columns-Page Setting Determining the Number of Columns You Need for a Print Line. 18-1 18-2 18-3 Using the SET ABORT Statement . U sing the SET PROMPT Statement. . . . . . . . . . . . . . . . . . . 18-4 18-4 vii 19 Controlling Access to Dictionary Objects 19.1 Contents of an Access Control List 19-1 19.1.1 19.1.2 19.1.3 Sequence Numbers . Lock Types . . . . . . . . Keys .. . . . . . . ... 19-2 19-2 19-2 19.1.3.1 19.1.3.2 19-2 19-3 19.1.4 19.2 19.3 19.4 Password Keys UIC Keys 19-4 Access Privileges Creating Access Control Lists . Processing Access Control Lists in DATATRIEVE Maintaining an Access Control List . . . 19.4.1 19.4.2 19.4.3 19.4.4 19.4.5 Guidelines for Ordering Entries Assigning Privileges . . . . . . Displaying an Access Control List Adding Entries to an Access Control List Deleting Entries from an Access Control List 19-6 19-7 19-9 19-9 19-10 19-10 19-11 19-11 20 Maintaining Data Dictionaries 20.1 20.2 20.3 20.4 20.5 Displaying Dictionary Objects Modifying Dictionary Objects . Deleting Dictionary Objects . . Optimizing Disk Storage of Data Dictionaries with QCPRS Extracting Dictionary Content with the QXTR Utility . 20-2 20-2 20-4 20-4 20-6 A Name Recognition and Single Record Context A.l Establishing the Context for Name Recognition. A-I .. . . A-2 A.1.1 The Right Context Stack A.1.1.1 A.1.1.2 A.1.1.3 A.1.1.4 A.1.1.5 A.1.1.6 A.1.1.7 A.1.2 A.1.3 A.1.4 viii The Content of a Context Block . Global Variables Collections . Record Streams Local Variables VERIFY Clause in the STORE Statement VALID IF Clause in a Record Definition A-2 A-4 A-4 A-5 A-7 A-8 A-8 Using Context Variables and Qualified Field Names . A-8 A.1.2.1 A.1.2.2 Context Variables as Field Name Qualifiers . Other Field Name Qualifiers . . .. A-8 A-9 The Left Context Stack for Assignment Statements Examples of Context Variables in STORE and MODIFY Statements A-II A-13 A.2 Single Record Context . . . . . . . . . . . . . . . . . . . . . A-14 The SELECT Statement and the Single Record Context The CURRENT Collection as Target Record Stream The OF rse Clause and Target Record Streams FOR Statements and Target Record Streams. . . . A-14 A-20 A-21 A-23 A.2.1 A.2.2 A.2.3 A.2.4 Index Figures 5-1 5-2 5-3 5-4 5-5 5-6 5-7 5-8 5-9 9-1 12-1 17-1 17-2 17-3 17-4 19-1 A-1 Data Items in a Personnel Record PERSONNEL_REC Record Definition Four Parts of the SALARY Field . . . Level Numbers in the PERSONNEL Record Definition Valid Field Names for EMPLOYEE_REC U sing FILLER as a Group Field Name Query Names for PERSONNEL_REC . A Flat Record A Hierarchical Record . . . . . . . . Sample Procedure . . . . . . . . . . Code and Translation Pairs in a Dictionary Table Empty DATATRIEVE Workspace . . . Workspace with One Readied Domain . . . . . . Workspace with Two Readied Domains . . . . . Workspace When You Finish First Readied Domain Sample Access Control List . . . . . . . . . . . . Duplicate Field Names in YACHTS and OWNERS · 5-2 · 5-2 · 5-4 · 5-4 · 5-7 · 5-9 5-12 5-14 5-14 · 9-7 12-1 17-2 17-3 17-3 17-4 19-2 A-2 Tables 5-1 6-1 7-1 16-1 16-2 19-1 19-2 19-3 FieldClasses . . . . . . . . . . . . . . . . . A Comparison of Sequential and Indexed Files Conditional Comparisons for an RSE . . . . . Examples of Range Specifiers . . . . . . . . . Summary ofDATATRIEVE Editor Commands Access Privileges . . . . . . . . . . . . . . . Commands/Statements by Privilege. . . . . . Privilege Requirements by Command/Statement 5-12 · 6-2 · 7-7 16-3 16-4 19-4 19-5 19-10 ix How to Use This Manual This manual is a guide to the interactive use ofDATATRIEVE-l1. It explains how to define dictionaries and dictionary objects (domains, records, tables, and procedures), and gives examples of using compound statements, command files, views, and hierarchies. It also discusses the restructuring of domains and the control of input and output. In this manual, the DATATRIEVE-l1 software is referred to as DATATRIEVE. Intended Audience This manual is intended for people who: • Have read and tried the examples in the Introduction toDATATRIEVE-ll • Have experience using DATATRIEVE • Have experience in applications programming but are unfamiliar with DATATRIEVE For people who have no experience with DATATRIEVE, the Introduction to DATATRIEVE-ll provides a tutorial to the basic DATATRIEVE-l1 tasks. Structure This manual is divided into 20 chapters, an appendix, and an index: Chapter 1 Introduces the basic concepts ofDATATRIEVE-l1. Chapter 2 Describes how to enter and exit DATATRIEVE, display data, use various prompts, and how to use DATATRIEVE Help and Guide mode. Chapter 3 Describes data dictionaries and how to create or change them. xi xii· Chapter 4 Describes how to name and define domains. Chapter 5 Describes how to plan a record definition, the rules governing the definition, the optional clauses you can use to specify certain conditions, and the use of lists to define hierarchical records. Chapter 6 Describes the difference between indexed and sequential data files, compares their advantages, and explains how to define them. Chapter 7 Discusses record selection expressions (RSEs) and how to use them to select particular records from your database. Chapter 8 Describes the use of REPEAT, FOR, and BEGIN-END blocks to combine statements into compound statements. Chapter 9 Describes how to define and use DATATRIEVE procedures. Chapter 10 Describes how to create and use DATATRIEVE command files. Chapter 11 Discusses DATATRIEVE variables, the differences between local and global variables, and how to use them. Chapter 12 Describes the creation and use ofDATATRIEVE tables. Chapter 13 Describes how to define and use view domains to examine only part of one domain or to combine information from more than one domain. Chapter 14 Discusses how to use lists to retrieve data. Chapter 15 Explains how to change record and file definitions to restructure a domain. Chapter 16 Explains how to use the DATATRIEVE Editor. Chapter 17 Discusses the most effective ways of using your allotted workspace. Chapter 18 Describes ways to control the format of your output and how to use the SET ABORT and SET PROMPT commands. Chapter 19 Describes how to create, use, and maintain access control lists. Chapter 20 Describes how to modify and delete data dictionaries, optimize the disk storage space they use, and extract their contents. Appendix A Explains in detail the way DATATRIEVE establishes context, the context stacks, context variables, and single record context. Related Manuals For further information on the topics covered in this manual, see: • Introduction to DATATRIEVE-ll • DATATRIEVE-ll Call Interface Manual • DATATRIEVE-ll Reference Manual Conventions This section explains the special symbols used in this book: This symbol indicates the RETURN key. This symbol indicates the TAB key. > The right angle bracket symbol at the beginning of a new line, or by itself, represents the system prompt. Color Color in examples shows user input. WORD Uppercase words represent DATATRIEVE keywords. word Lowercase words are generic terms that indicate entries you must provide. {} Braces enclose clauses from which you must choose one alternative. [ ] Square brackets enclose optional clauses from which you can choose one or none. Horizontal ellipsis means you can repeat the previous item. Vertical ellipsis in an example means that information not directly related to the example has been omitted. xiii Introduction to DATATRIEVE-11 1 This chapter gives an overview ofDATATRIEVE-11 and explains its basic concepts and terms. 1.1 Description of DATATRIEVE-11 DATATRIEVE-II is an interactive tool for inquiry, update, and maintenance of information stored in data files. DATATRIEVE-II runs on any PDP-II computer with an RSX-IIM, RSX-IIM-PLUS, RSTS/E, Micro/RSX, or Micro/RSTS operating system. The commands and statements you use are common English words that have specific meaning within DATATRIEVE. With these commands and statements you can manipulate the information in selected data files. 1.2 DATATRIEVE Concepts and Terms DATATRIEVE-II uses concepts and terms that may not be familiar to you. These include: • Files, records, and domains • Data dictionaries • Commands and statements • Procedures 1-1 • Command files • Tables 1.2.1 Files A data file contains ordered data. The DATATRIEVE DEFINE FILE command creates a data file and allows you to specify some of the characteristics of the file. You can use your record definition to control the way DATATRIEVE handles the data in other data files. You can also use a number of different record definitions to work with the information stored in one data file. 1.2.2 Record Definitions The record is the basic unit of information management. It describes the relationship between logically connected data items and consists of one or more subunits called fields. DATATRIEVE uses both elementary and group fields. An elementary field contains an item of data. A group field contains group and elementary fields that are logically related. Thus, you might have an EMPLOYEE-NAME group field that contains the elementary fields FIRST-N"AME, MIDDLE_INITIAL, and LAST-N"AME. DATATRIEVE enables you to interpret the data in the fields ofa data record. The DATATRIEVE record definition controls the way you look at and interpret the information coded in your data files. In the field definition clauses in a DEFINE RECORD command, you specify the type offield, the length of each field, and the content of the fields - character strings, numbers, or dates. You can also control the format DATATRIEVE uses to display values from those fields. Note that in field names (like FIRST_NAME), this manual uses underscores (_). When you are using DATATRIEVE, you may use either underscores or hyphens (-) in record or field definitions. DATATRIEVE accepts hyphens as input but converts them to underscores before analyzing user input. To use a hyphen as a minus sign, put spaces before and after it. Otherwise, DATATRIEVE converts the minus sign to an underscore and issues an error message. Be consistent in your own practice. To avoid confusion when using the manuals, you may want to use underscores instead of hyphens. Whichever you use, Chapter 5 of this manual explains record definitions and field definition clauses. 1.2.3 Domains To manage the data in a file, you must explicitly connect that data file to a record definition. DATATRIEVE makes this connection with a domain. You use the DEFINE DOMAIN command to create a domain definition and to store that definition in your current data dictionary. 1-2 Introduction to DATATRIEVE-11 The domain definition establishes a name for the domain and associates that name with the names ofa record definition and a data file. When you use the name of the domain, you tell DATATRIEVE to use a particular record definition to interpret the data stored in a specific file. Do not confuse a domain with the data you want to manage. The data stored in the data file does not constitute the domain. You can erase old records and add new ones without disturbing the relationship between the data file and the record definition, which remains fixed. 1.2.4 Data Dictionaries A data dictionary is an RMS file that DATATRIEVE creates to store definitions. It stores tables, procedures, and the definitions of domains and records. 1.2.5 Commands and Statements You manage information with commands and statements based on the DATATRIEVE keywords described in this manual. Commands deal with the data dictionary and enable you to: o Create, change, and display definitions in the dictionary (DEFINE, SHOW, EDIT, DELETE, and EXTRACT) o Maintain the access control lists associated with those definitions (DEFINEP, SHOWP, and DELETEP) o Get access to domains (READY) • Release access to domains, variables, collections, and DATATRIEVE tables (RELEASE and FINISH) • Determine the way DATATRIEVE displays data on your terminal (SET) • Get online information about DATATRIEVE (HELP) • End your DATATRIEVE sessions (EXIT) Statements deal with data and enable you to: • Store records (STORE) • Form and manipulate groups of records (FIND, SELECT, DROP, and SORT) • Display data (PRINT, REPORT, and SUM) • Modify records (MODIFY) • Erase records (ERASE) • Declare variables and assign values (DECLARE and assignment) Introduction to DATATRIEVE-11 1-3 You can join statements to form compound statements in the BEGIN-END, FOR, IF-THEN-ELSE, REPEAT, and THEN statements. You cannot join commands with other commands or with statements. Furthermore, only statements may contain DATATRIEVE value expressions and record selection expressions. You can enter statements at other levels than command level (indicated by the DTR> prompt), but you can enter commands only at command level. If you are not sure whether a given keyword is a command or a statement, refer to the table showing an alphabetical summary of commands and statements in the DATATRIEVE-ll Reference Manual. 1.2.6 Procedures Most DATATRIEVE-11 applications involve sequences of commands and statements that you use again and again. To avoid retyping such a sequence, you can store it in your dictionary as a procedure. You can also use procedures within commands or statements. With the DEFINE PROCEDURE command, you give the sequence a name and enter both the name and the sequence into your dictionary. You invoke the procedure by entering a colon (:) and the procedure name. DATATRIEVE then interprets the content of the procedure just as though you had entered it at your terminal. 1.2.7 Command Files You can use command files in DATATRIEVE in much the way you use DATATRIEVE procedures. The primary difference between the two is that you store command files in your operating system directory and procedures in a DATATRIEVE dictionary. When you invoke a command file, DATATRIEVE displays the text of the file on your terminal. When you invoke a procedure, however, the procedure definition is not displayed on your terminal. 1.2.8 DATATRIEVE Tables DATATRIEVE tables perform two functions. They let you: • Specify one value and retrieve another that you have associated with the first • Validate data according to the presence or absence ofa data item in the table A table contains pairs of character strings. The first member of each pair is the code string and the second is the translation string. The last entry in the table can be an ELSE clause that specifies a default translation string. Thus your table might match department codes (such as A01) with department names (such as Accounting). If you enter a code not in the table, for example, the ELSE clause can specify a message to be displayed on your terminal telling you the code is not valid. 1-4 Introduction to DATATRIEVE-11 1.3 Components of DATATRIEVE-11 DATATRIEVE-II consists of four components on your PDP-II system: • Interactive DATATRIEVE-II The DTR.TSK task image allows you to access DATATRIEVE at your terminal. • The DATATRIEVE-II Distributed Server DDMF.TSK allows users on other DECnet nodes to use DATATRIEVE for accessing data files and data dictionaries on your node. • The DATATRIEVE-II Call Interface The DTCLIB.OLB object module library allows application programs in other high-level languages to call DATATRIEVE subroutines. The calls, through a local or remote server, give you access to DATATRIEVE data files and dictionaries. • The DATATRIEVE-II Remote Terminal Interface REMDTR.TSK is an interactive program that uses the Call Interface and the remote server. When you run REMDTR as a program, it looks as though you are running interactive DATATRIEVE on a remote node. The following sections describe these four components and tell you where to find information on each one. 1.3.1 Interactive DATATRIEVE When you invoke DATATRIEVE-II on a PDP-II system, yo~ are running DTR.TSK, the interactive DATATRIEVE task image. This program accepts DATATRIEVE commands and statements from the terminal and uses the terminal as the default output device. DTR.TSK allows you to access data stored in disk files as well as definitions stored in one of the data dictionaries on your system, usingDATATRIEVE commands and statements. The Introduction to DATATRIEVE-ll , the DATATRIEVE-ll Reference Manual, and this manual describe how to use interactive DATATRIEVE. 1.3.2 The DATATRIEVE Distributed Server The Distributed Data Manipulation Facility (DDMF), is also called the DATATRIEVE Distributed Server. It is a "slave" program. Another DATATRIEVE component sends it commands to execute, and it passes the results back to that component. DDMF can perform all the DATATRIEVE functions that DTR. TSK can perform, with the exception of the Application Design Tool (ADT) and Guide Mode. Introduction to DATATRIEVE-11 1-5 You use the Distributed Server in three ways: • VAX DATATRIEVE uses the Distributed Server on a PDP-II or VAX node to perform distributed operations. For example, when you type READY YACHTS AT FRODO in VAX DATATRIEVE, DATATRIEVE starts up DDMF on the node named FRODO and uses it to access definitions and data files on that node. • The DATATRIEVE-II Call Interface uses DDMF to give you access to data dictionaries and data files, allowing you to write application programs that call DATATRIEVE. • The DATATRIEVE-II Remote Terminal Interface uses DDMF through the Call Interface, allowing you to use your terminal to access DATATRIEVE on other nodes. 1.3.3 The DATATRIEVE-11 Callinteriace The Call Interface allows you to write high-level language programs that call DATATRIEVE, either on your own system or on another DECnet node. To use the Call Interface, you include calls to external DATATRIEVE subroutines in your program. When you build the task image, you link the program to the object module library DTCLIB.OLB. The subroutines pass information between the calling program and a local or remote DATATRIEVE Distributed Server. When you are running such a program, there are actually two task images active: • Your program linked to DTCLIB.OLB • DDMF, the DATATRIEVE Distributed Server that has been activated to serve your program - - - - - - - - - - - Note - - - - - - - - - - - You must have the DECnet software installed on your system before you can access DATATRIEVE on a remote node. The DATATRIEVE-ll Call Interface Manual tells you how to write programs that use the Call Interface. 1.3.4 The DATATRIEVE-11 Remote Terminallnteriace The DATATRIEVE-II Remote Terminal Interface (REMDTR) gives you interactive access to DATATRIEVE on other nodes. - - - - - - - - - - - Note - - - - - - - - - - - You must have the DECnet software installed on your system before you can use REMDTR. 1-6 Introduction to DATATRIEVE-11 To use the Remote Terminal Interface on both RSTS and RSX-IIM/M-PLUS systems, type RUN $REMDTR. If an error message is displayed, check with your system manager to make sure the program is installed. When REMDTR prompts you for a node name, you can type either a node name or a complete network address specification. The address specification includes a user name or account number and a password: Enter node naMe: MYVAX Ente r node nalTle: MYVAXIIMYNAME PASWRD II Enter node naMe: MYRSTS II 130,34 PASWRD II If you specify only the node name, you are logged in to the default DECnet account and may not have access to the data files or dictionaries you want. When you type the complete form of the specification, DECnet logs you into that account. After you have logged in successfully, you can use DATATRIEVE interactively on that node as if you were using DATATRIEVE on your own node, except that Guide Mode and ADT are not available. You can use the Remote Terminal Interface for copying dictionary definitions and data files across DECnet. It is also useful for testing a network path and determining the default characteristics ofDDMF, the DATATRIEVE Distributed Server, on a remote node. For more information on using the Remote Terminal Interface, see the DATATRIEVE-ll Call Interface Manual. Introduction to DATATRIEVE-11 1-7 Getting Started with DATATRIEVE 2 This chapter tells you how to start and stop DATATRIEVE. It also tells you how to: • Work with sample domains, records, and files included in the DATATRIEVE-ll installation kit • Use the PRINT and REPORT statements • Understand DATATRIEVE prompts • Interpret DATATRIEVE error messages • Use Help and Guide mode 2.1 Invoking DATATRIEVE-11 The way you start DATATRIEVE can vary from one system to another. If you cannot invoke DATATRIEVE using the method discussed in this section, contact the person in charge ofDATATRIEVE on your system. See your system manager for the exact invocation line for your system. Here is how to start the system if your invocation line is RUN $DTR: > RUN $DTRCffi) PDP-II DATATRIEVE, DEC Query and Report SYsteM I)ersion: 1)3.2, 13-NOI.J-87 Type HELP for help DTR> The startup banner in the previous example shows you that you have successfully invoked DATATRIEVE. 2-1 2.2 Sample Domains, Records, and Data Files The DATATRIEVE-II installation kit includes four sample domains: YACHTS, OWNERS, PERSONNEL, and FAMILIES. The domain definitions and the record definitions are in the system data dictionary. The following command creates a private dictionary for you called SAMPLE.DIC which resides in your current default directory. The command enters the domain and record definitions into the dictionary, and copies the data files into your directory. For RSTS/E and Micro/RSTS systems type: DTR> @LB:SETUP.DTRlliIT) DTR> For RSX, Micro/RSX, and VAX-II RSX systems type: DTR> @LB: [ 1 ,2] SET UP. DTRlliIT) DTR> To see that the sample domain and record definitions are in place, use the SHOW command: DTR> SHOW DOMAINS, RECORDSlliIT) DOITlains: FAMILIES KETCHES PERSONNEL PERSONNEL_SEQ YACHTS_SEQUENTIAL OWNERS SAILBOATS OWNERS_SEQUENTIAL YACHTS Records: OWNER_RECORD YACHT PERSONNEL_REC DTR> The results of this command vary from one system to another, but you should be sure that DATATRIEVE lists the needed domain and record definitions on your terminal. If you have difficulty, see the person responsible for DATATRIEVE-II on your system. 2.3 QUERY.lNI Startup File If you frequently start your DATATRIEVE session with the same series of commands and statements, you can use a command file to execute the commands and statements automatically each time you invoke DATATRIEVE. DATATRIEVE recognizes QUERY.INI as the default startup file. However, you can specify a different startup file at installation time if you choose. 2-2 Getting Started with DATATRIEVE DATATRIEVE first looks for a QUERY.INI file in your default directory. If one is there, DATATRIEVE executes the commands and statements it contains before it accepts any other input. If you would like to be in Guide mode as soon as you invoke DATATRIEVE, for instance, you can include the SET GUIDE command at the end of your QUERY.INI file. You can put a SET DICTIONARY command in the QUERY.INI file to automatically change your default data dictionary. You can ready domains you use frequently. Your QUERY.INI file, then, might include these lines: SET DICTIONARY MYDIC.DIC SET GUIDE READY YACHTS When you type your command to invoke DATATRIEVE, you are placed in your own dictionary and in Guide mode, and the YACHTS domain is readied. 2.4 Using READY, PRINT, and REPORT to Retrieve Data The basic keywords used to retrieve data are the READY command and the PRINT and REPORT statements. To display a complete domain, for example, first ready the domain. Then type PRINT followed by the domain name: DTR) READY PERSONNEL(6TI) OTR) PRINT PERSONNEL(6TI) ID STATUS FIRST NAME 00012 EXPERIENCED CHARLOTTE 00881 E}-{ PER I ENCED FRED 02843 E}{PER I ENCED CASS 12843 TRAINEE JEFF 32432 TRAINEE THOMAS 34458 TRAINEE HANK 38482 E}{PER I ENCED BILL 38485 E}{ PER I ENCED JOANNE 38485 EXPERIENCED DEE 48475 E}{PER I ENCED GAIL 48573 TRAINEE SY 48001 E}-{ PER I ENCED DAN 48843 TRAINEE BART 78823 E}-{ PER I ENCED LYDIA 83784 E}{ PER I ENCED JIM 84375 E}{PER I ENCED MARY 87288 E}{PER I ENCED LOUISE 87485 E}-{ PER I ENCED ANTHONY 87701 TRAINEE NATHANIEL 88001 E}{ PER I ENCED DAVID 80342 E}-{PER I ENCED BRUNO 81023 TRAINEE STAN 88028 EXPERIENCED RANDY LAST NAME DEPT START DATE SPIVA HOWL TERRY TASHKENT SCHWEIK MORRISON SWAY FREIBURG TERRICK CASSIDY KELLER ROBERTS HAMMER HARRISON MEADER NALEIJO DEPALMA IACOBONE CHONTZ LITELLA DONCH IKOIJ WITTGEN PODERESIAN TOP F11 D88 C82 F11 T32 T32 E48 D88 E48 T32 C82 D88 F11 T32 D88 G20 C82 F11 G20 C82 G20 C82 12-Sep-72 8-Apr-78 2-Jan-80 4-Apr-81 7-NOIJ-81 1-Mar-82 5-Ma}'-80 20-Feb-80 2-Ma}'-77 2-Ma}'-78 2-Au!1-81 7-Jul-78 4-AU!1-81 18-Jun-78 4-Apr-80 3-Jan-78 28-Feb-78 2-Jan-73 28-Jan-82 11-NoIJ-80 8-AU!1-78 23-Dec-81 24-Ma}'-78 SALARY SUP ID $75,882 00012 $58,584 00012 $28,808 38485 $32,818 87485 $28,723 00881 $30,000 87288 $54,000 00012 $23,808 48475 $55,828 00012 $55,407 00012 $31 1548 87288 $41 1385 87485 $28,382 38485 $40,747 00881 $41 1028 87288 $58,847 38485 $57,588 00012 $58,482 00012 $24,502 00881 $34,833 87288 $35,852 87485 $25,023 87288 $33,738 87485 DTR) Getting Started with DATATRIEVE 2-3 For an explanation of the various forms of the PRINT statement, see the Introduction toDATATRIEVE-ll and theDATATRIEVE-ll Reference Manual. To retrieve information in a report format, use the REPORT statement. This can provide you with a report title, a date, page numbers, and various statistical functions. In its simplest form, the report specification consists of a REPORT statement, followed by a PRINT statement specifying the fields you want to report, and an END_REPORT statement to conclude the specification: DTR) REPORT YACHTS WITH BUILDER = "ALBERG"(BTIJ RW) PRINT BOAT(BTIJ RW) END_REPORT(BTIJ 15-Nov-87 Page 1 MANUFACTURER ALBERG MODEL RIG LENGTH OI.'ER ALL 37 MK II KETCH 37 WEIGHT BEAM PRICE 20tOOO 12 $38t951 DTR) For a complete explanation of the DATATRIEVE-ll Report Writer, see the DATATRIEVE-ll Guide to Writing Reports. 2.5 DATATRIEVE Input Line Prompts Several types of prompts provide you with information during your interactive DATATRIEVE session. There are four types of input line prompts: 2-4 DTR> Marks the beginning of input lines and shows that DATATRIEVE is ready for your input CON> Prompts you to continue incomplete commands or statements and shows what DATATRIEVE expects next DFN> Prompts you to continue a partially complete DEFINE command RW> Prompts you to complete unfinished Report Writer statements and enter additional statements Getting Started with DATATRIEVE 2.6 DATATRIEVE Syntax Line Prompts When you press RETURN before completing a command or statement, DATATRIEVE prompts you with a phrase in square brackets telling you what sort of input it expects to satisfy the syntax of the command or statement. This example shows several of DATATRIEVE's syntax prompts: DTR> READY(illJ [Looking for Dictionary EleMent] CON> YACHTS(illJ DTR> FINDm [Loo~~ing for IIFIRST II t dOfrlain nafrle t or collection nafrle] CON> YACHTS WITH(illJ [Looking for Boolean expression] CON> LOA(illJ [Looking for relational operator (eqt gtt etc.)] CON> BETWEENm [Looking for a value expression] CON> 20(illJ [Looking for upper value of between] CON> AND(illJ [Looking for a value expression] CON> 30(illJ [5a records found] DTR> 2.7 DATATRIEVE Prompts for Storing and Modifying Values When you enter a STORE or MODIFY statement, DATATRIEVE usually prompts you to enter new information to be stored in the record, or to replace what was stored there previously. Unless the statement contains a USING clause, you are prompted to enter information for each field receiving a new value. The prompt is made up of the word "Enter" followed by the name of the field. It takes the following general form: Enter field-naMe: 2.8 DATATRIEVE Error Messages Error messages are DATATRIEVE responses to faulty syntax or an error in logic. When it detects an error, DATATRIEVE displays an error message and returns you to DATATRIEVE command level. All data items remain the same as they were before you made the error. The messages describe the error. For instance, when you use an undefined name in a PRINT command, DATATRIEVE responds with an error message: DTR) PRINT RUBINS(illJ Field IIRUBINS II is undefined or used out of context DTR) Getting Started with DATATRIEVE 2-5 2.9 Ending Your DATATRIEVE Session You can exit from DATATRIEVE by: • Entering the EXIT command • Pressing CTRL/Z • Pressing CTRL/C two times 2.9.1 Using the EXIT Command To end your DATATRIEVE session and return to the operating system command level, you can respond to the DTR> prompt with an EXIT command: DTR> E}<IT(lli) :> Entering the EXIT command at any other DATATRIEVE prompt is a syntax error. 2.9.2 Exiting from DATATRIEVE with CTRL/Z You can also end your DATATRIEVE session by entering CTRL/Z in response to the DTR> prompt: DTR> "2 > Entering CTRL/Z in response to any prompt other than DTR> returns you to DATATRIEVE command level (DTR». 2.9.3 Exiting from DATATRIEVE by Pressing CTRL/C Two Times If you enter one CTRL/C when DATATRIEVE is executing a command, DATATRIEVE aborts its operation. If you enter CTRL/C two consecutive times, the second aborts the task and returns you to your operating system command level. Either the EXIT command or CTRL/Z is a better way to exit than two CTRL/Cs, because EXIT and CTRL/Z do not abort the task. 2.10 Using Help DATATRIEVE offers two levels of help - basic and advanced. Basic help is information about elementary DATATRIEVE statements. Advanced help provides instructions on statements that you are likely to use after some experience with DATATRIEVE. To get information on the help topic itself, type HELP in response to the DTR> prompt. DTR> HELP(lli) 2-6 Getting Started with DATATRIEVE For a listing of the topics for which help is available, type: DTR> HELP HELPffilij The topics of greatest interest to the the follolAJing: GUIDE PRINT READY MODIFY beginning FIND STORE user are SORT E}<I T Help is al.lailable for the follolAJing topics: ABORT COMPUTED DEFINE DICTIONARY EDIT E}<TRACT FOR MODIFY PROCEDURE RELEASE SELECT SORT THEN DBMS ADT CONDITION DEFINEP DISPLAY EDIT-STRING FILE GUIDE OCCURS RANGE REPEAT SET STORE USAGE OWNER ASSIGNMENT DATE DELETE DOMAIN ERASE FIND HELP PIC READY REPORT SHOW SUM I.IALUE WITHIN BEGIN DECLARE DELETEP DROP E}<IT FINISH IF PRINT RECORD RSE SHOWP TABLE I.JI EW DTR> To get help on one of these topics, type HELP followed by the name of the topic and press the RETURN key. 2.10.1 Using Advanced Help For a listing of topics for which advanced help is available, type: DTR> HELP ADI.IANCED HELPffilij Advanced help is available for the following topics: CONDITION EDIT MODIFY RANGE SORT I.IALUE DICTIONARY EDIT-STRING OCCURS RECORD STORE I.JI EW DOMAIN FILE PRINT RSE TABLE DBMS FIND PROCEDURE SELECT USAGE DTR> To get advanced help on one of these subjects, type HELP ADVANCED followed by the name of the subject. Getting Started with DATATRIEVE 2-7 2.11 Guide Mode The self-explanatory Guide mode feature helps you: • While you are learning to use DATATRIEVE • Whenever you are unsure of the sequence of commands you need to accomplish your task ----------------------- Note ----------------------- To use Guide mode, you must have a video display terminal. It will not work on any hardcopy terminal. To get into Guide mode, type: DTR) SET GUIDE(ffi) DATATRIEVE then prompts you, step-by-step, for every operation you want to perform. If you need help, type a question mark (?). DATATRIEVE shows you a list of the possible commands and statements you can use to complete your task: DTR) SET GUIDE(ffi) Enter cOMMand, type? for help If you type?, the DATATRIEVE displays the following information: Enter cOMMand, type? for help The possible responses are: READY Make dOMain available SHOW Display status inforMation Return to norMal Datatrieve Notice that Guide mode automatically spells out entire words and phrases immediately after you type only one or two letters. You may find this somewhat startling at first, but you soon get used to it. Guide mode fills in the word as soon as you enter characters it recognizes. If you type R, it completes the word as READY. If you type RE, REA, and so on, it also echoes the word READY. You can get unexpected results with Guide mode if you are not careful, however. For example, suppose you want to ready a domain called EASELS. If you type REA, Guide mode does not expand the R to READY and the EA to EASELS. Rather, it interprets the EA as part of a READY command with no domain name supplied. To get the results you want, you could instead type REA EA, which would be expanded to READY EASELS. When you are ready to exit from Guide mode and return to regular DATATRIEVE, type LEAVE. The DTR> prompt means you are out of Guide mode. 2-8 Getting Started with DATATRIEVE Creating Data Dictionaries 3 Each time you invoke it, DATATRIEVE automatically connects you to a data dictionary - an RMS file that DATATRIEVE creates to store definitions and protection information. This chapter shows how to create a data dictionary. 3.1 Contents of a Data Dictionary A data dictionary contains the definitions and protection information for the following DATATRIEVE data structures: • Domains • Records • Procedures • Description tables Each definition describes the contents of the data structure: • A domain definition contains the name of the domain, the name of the record definition associated with the domain, and the file specification of the file containing the data for the domain. • A record definition contains the name of the record and a definition for each field in the record. • A procedure definition is the procedure itself, including the procedure name and all commands and statements in the procedure. • A table definition is the table itself, including its name and all code and description pairs. 3-1 Associated with each of these definitions is an access control list (ACL). It protects the one definition with which it is associated and restricts its use. Access control lists supplement the protection features of your operating system. 3.2 Creating a Data Dictionary You create a data dictionary using the DEFINE DICTIONARY command. The format of this command is: DEFINE DICTIONARY file-spec DEFINE DICTIONARY creates an empty indexed sequential RMS file that is suitable for use as a data dictionary. You supply the file specification, and the operating system creates an entry for it in your directory. You can choose any file extension when you create it. If you use the default file extension .DIC, you do not have to specify the file extension when referring to your dictionary file from DATATRIEVE command level. In addition, if you use the standard file extension, you can easily identify your dictionary files when you list your directory. When you enter a DEFINE DICTIONARY command, DATATRIEVE creates a file and establishes the new dictionary as your current data dictionary,just as if you had entered a SET DICTIONARY command: DTR> SHOW DICTIONARYffiITj The current dictionary is 5'1':[1 ,3JNEWQ.DIC DTR> DEFINE DICTIONARY MYDICffiITj DTR> SHOW DICTIONARYffiITj The current dictionary is SY:[1 ,37JMYDIC.DIC Note that because you did not specify any extension for the dictionary, DATATRIEVEassigned .DIC by default. You can begin entering definitions immediately. IfDATATRIEVE cannot create a file because, for example, you do not have write access to the disk, or the disk is not mounted, it prints a message on your terminal and leaves you connected to your current dictionary. 3.3 Changing Dictionaries When you invoke it, DATATRIEVE automatically connects you to a default data dictionary. At the time of installation, your system manager determines what the default dictionary will be for your system. At the beginning of your DATATRIEVE session, that dictionary is your current dictionary. To find out the name of your current dictionary, use the following command: DTR> SHOW DICTIONARYffiITj The current dictionary is 5'1':[1 ,37JMYDIC.DIC SHOW DICTIONARY prints the file specification of the current data dictionary. 3-2 Creating Data Dictionaries If you want to use a different dictionary, use the following format of the SET command: SET DICTIONARY file-spec To change from the default dictionary to another dictionary, you must specify at least one element of the file specification of the other data dictionary. For example, if you specify only the device name, DATATRIEVE searches that device for a directory with your project-programmer number (PPN) or user identification code (UIC) and a file named QUERY.DIC. IfDATATRIEVE does not find the file you specify, it prints an error message on your terminal and leaves you in your current dictionary. (At no time are you in DATATRIEVE without being in a data dictionary.) If you have readied a domain in your current dictionary and you change dictionaries, that domain is still available when you are in the new dictionary. This feature allows you to move records from that readied domain into another domain in the new current dictionary. If you want to return to the default data dictionary, issue the SET DICTIONARY command without a file specification: DTR> SET DICTIONARYm The following dialogue illustrates the setting and displaying of data dictionaries. Note that if you try to set a dictionary that you have not defined, DATATRIEVE prints an error message on your terminal. You must first define the dictionary with a DEFINE DICTIONARY command. Note also that DATATRIEVE returns the DFN> prompt when you omit the file specification from the DEFINE DICTIONARY command. In this example, DR1: represents the name of the device on which the default DATATRIEVE system dictionary resides. DR2: is the name of the device on which your file directory is stored: DTR> SHOW DICTIONARYm The current dictionary is DR1:[1 tZJQUERY.DIC DTR> SET DICTIONARY NEWDICm File "NEWDIC" not found DTR> DEFINE DICTIONARYm DFN> NEWDICm DTR> SHOW DICTIONARYm The current dictionary is DRZ:[ZOOt200JNEWDIC.DIC DTR> SET DICTIONARYm DTR> SHOW DICTIONARYm The current dictionary is DR1:[1 tZJQUERY.DIC DTR> Note that you do not need an explicit SET DICTIONARY command after entering DEFINE DICTIONARY NEWDIC, because that DEFINE sets the dictionary to NEWDIC automatically. Creating Data Dictionaries 3-3 Defining Domains 4 When you define a DATATRIEVE domain, the domain associates the names of a record definition and a data file with each other. When you use a domain name, you tell DATATRIEVE to use a particular record definition to interpret the data stored in a specific file. Do not confuse the domain with the data you want to manage using the domain. You can erase old records or add new ones to a data file without disturbing the relationship between the file and a record definition. That relationship is established when you define a domain and it remains fixed. This chapter explains how to define simple RMS domains. You can also use the Application Design Tool (ADT) to define domains, records, and files. For information on using ADT, see the Introduction to DATATRIEVE-ll. 4.1 Specifying Domain Names In the DEFINE DOMAIN command, you specify the name of a domain, the name of the record definition associated with the domain, and the file specification of the file containing the data for the domain. The domain name must: • Begin with a letter (A-Z) • Contain 31 characters or less • End with a letter (A-Z) or a digit (0-9) • Contain only letters, digits, dollar signs, hyphens, or underscores (A-Z, 0-9, $, -, or _) 4-1 DATATRIEVE enters the domain definition in your current dictionary directory. ----------------------- Note ----------------------- DATATRIEVE treats hyphens and underscores as identical characters. You may use either underscores or hyphens in the names you assign. When processing, DATATRIEVE automatically converts hyphens to underscores. When it returns the output, it shows underscores whether you have entered hyphens or underscores. To use a hyphen as a minus sign, put spaces before and after it. 4.2 Defining a Simple RMS Domain To define a domain, you associate the name of the domain with a record definition and file specification. The format for the DEFINE DOMAIN command follows: DEFINE DOMAIN domain-name USING record-name [(pa~;Wd) ] ON file-spec The domain name cannot duplicate a DATATRIEVE keyword or the name of any other element in the current data dictionary. The record name refers to the record definition to be associated with the domain. You can define the domain before you define the record. (See Chapter 5 for information on defining records.) An optional password can be used to check for E (execute) privilege for the record definition. If an asterisk prompt (*) is specified, DATATRIEVE prompts you for the password. Be sure to end the definition with a semicolon (;). If you omit the semicolon, DATATRIEVE prompts you for one with DFN>. The following rules apply to the DEFINE DOMAIN command: • It must be preceded by a DATATRIEVE command level prompt DTR>. • You cannot include a domain definition in a procedure. • You cannot invoke a procedure in a domain definition. • You cannot include a DEFINE DOMAIN command in a DATATRIEVE statement. Here is an example of the DEFINE DOMAIN command: DTR> DEFINE DOMAIN SCHEDULE USING SCHED_REC ON SCHEDi(@j DTR> This command enters the definition for SCHEDULE in your current dictionary. The domain uses a record definition called SCHED_REC and a data file called SCHED.DAT. The file extension .DAT is assigned to the data file by default. 4-2 Defining Domains 4.3 Using the SHOW Command with Domains You can use the SHOW command to see how a domain is defined. If you enter SHOW followed by the domain name, the text you used in the DEFINE DOMAIN command is displayed on your terminal. For example, you enter SHOW SCHEDULE, as follows, to see how the domain SCHEDULE is defined: DTR> SHOW SCHEDULE@ill DOMAIN SCHEDULE USING SCHED_REC ON SCHED; DTR> Note that the domain must be defined in your current default dictionary. (See Chapter 3 for information on dictionaries.) To see if a domain is in your dictionary, enter the SHOW DOMAINS command. This displays a listing of all domains in your default dictionary, as follows: DTR> SHOW DOMAINS@ill DOITlains: FAMILIES KETCHES OWNERS OWNERS_SEQUENTIAL SAILBOATS SCHEDULE YACHTS YACHTS_SEQUENTIAL DTR> Defining Domains 4-3 Defining Records 5 There are two ways to define a record in DATATRIEVE-l1. You can use the interactive Application Design Tool (ADT), and DATATRIEVE creates the record for you based on your responses to a series of questions. You can also define the record yourself with the DEFINE RECORD command. For simple records, the Application Design Tool is often an efficient way to complete your definition. See the Introduction to DATATRIEVE-ll for a sample ADT session. The DEFINE RECORD command, on the other hand, lets you use options not available through ADT. For instance, it lets you include clauses such as the COMPUTED BY clause, which asks DATATRIEVE to calculate the value of a field from the values of other fields or value expressions. This chapter explains how to set up a record definition using the DEFINE RECORD command. TheDATATRIEVE-ll Reference Manual contains additional information on defining records, including alphabetical listings of all clauses you can use in your record definitions. 5.1 Planning a Record Definition The first step in writing a DATATRIEVE record definition is to analyze your data. Decide what data items you need to manage, their relative importance, and ways to group related items. You might want to maintain your personnel files with DATATRIEVE, for example. As you analyze the information, you find that for each employee you want to include an identification number, status (experienced or trainee), name, department, starting ~ate, salary, and supervisor identification number. Your list of data items might look like that in Figure 5-1. 5-1 IDENTIFICATION NUMBER STATUS EMPLOYEE NAME DEPARTMENT START DATE SALARY SUPERVISOR'S IDENTIFICATION NUMBER Figure 5-1: Data Items in a Personnel Record With your DATATRIEVE installation kit, you receive a record called PERSONNEL_REC made up of the data items listed in Figure 5-1. The DATATRIEVE definition for that record appears in Figure 5-2. DTR> SHOW PERSONNEL_RECCBTIl RECORD PERSONNEL_REC USING 01 PERSON. 05ID 05 EMPLOYEE_STATUS 05 EMPLOYEE_NAME 10 FIRST_NAME 10 LAST_NAME 05 DEPT 05 START_DATE 05 SALARY 05 SUP_ID PIC IS 9(5). PIC IS X(ll) QUERY_NAME IS STATUS QUERY_HEADER IS "STATUS" I.JALID IF STATUS EQ "TRAINEE" tIE}-{PERIENCED" QUERY_NAME IS NAME. PIC IS }-«10) QUERY_NAME IS F_NAME. PIC IS }-{(10) QUERY_NAME IS L_NAME. PIC IS >nce USAGE IS DATE. PIC IS 9(5) EDIT_STRING IS $$$t$$$. PIC IS 9(5). DTR> Figure 5-2: PERSONNEL_REC Record Definition To write a DATATRIEVE record definition yourself, you provide the elements to transform a list of data items like that in Figure 5-1 into a formal record definition like that in Figure 5-2. The rest of this chapter tells you how to make such a change. 5.2 Getting Started and Naming a Record When you define a record, you begin by specifying the name of a record. You can define the record interactively by entering the DEFINE RECORD command at the DTR> prompt followed by the complete record definition. If you make a mistake, DATATRIEVE displays an error message and returns you to the DATATRIEVE command level without saving the definition. You must then retype it. 5-2 Defining Records t To avoid retyping, you can define the record in a procedure (see Chapter 9) or a command file (see Chapter 10). You can define your record, or only a few fields of the record, complete the definition (remember the semicolon), and then revise it later. You can use your text editor or the DATATRIEVE Editor to add additional fields or make whatever other changes you would like. To make the changes with your text editor: 1. Copy the record definition to a file, using the following statement: EXTRACT ON file-spec record-name 2. EXIT from DATATRIEVE 3. Use your text editor to make corrections in the record definition Notice the file begins with the commands DELETE record-name and DEFINE record-name. DATATRIEVE inserts these commands into the command file when you use the EXTRACT command. When you invoke the file, DATATRIEVE deletes the incorrect record definition and creates the corrected one. 4. Return to DATATRIEVE 5. Execute the command file just created by typing the at sign (@) and the file name See Chapter 16 for a description of the DATATRIEVE Editor. When you name the record, the name must: • Begin with a letter (A-Z) • Contain 31 characters or less • Contain only letters, digits, dollar signs, hyphens, or underscores (A-Z, 0-9, $, -, or _) • Not duplicate a DATATRIEVE keyword • Not duplicate the name of an existing dictionary object 5.3 Defining the Parts of a Record Definition Having named the record, you can define its parts. The complete record definition consists of one or more field definitions for fields like PERSON, EMPLOYEE_STATUS, and EMPLOYEE--NAME in Figure 5-2. Each field definition describes the field itself, with a name and a field definition clause. It also describes the field's relationship to other fields, with a level number. Follow the definition with a period. Figure 5-3 shows the four parts of the SALARY field in PERSONNEL-REC. Defining Records 5-3 Level Number Field Name 05 SALARY PIC IS 8(5) EDIT - STRING IS $$$t$$$f. - Two Field Definition Clauses - Period (.) Figure 5-3: Four Parts of the SALARY Field These are required parts of the field definition: • A level number specifying the field's relationship to other fields in the record • A field name identifying the field • A period (.) signifying the end of the field definition In addition, most field definitions contain clauses describing the information stored in the field. Among other things, field definitions can describe the size of a field, the type of information stored in it, and how the information will be displayed. In Figure 5-3, for example, the PIC (or PICTURE) clause describes the size of the SALARY field and the type of information which can be stored there, in this case a number with no more than five digits. The EDIT_STRING clause specifies that information in the SALARY field will be displayed in monetary format with a leading dollar sign ($) and a comma (,) in the appropriate place. Level numbers, field names, and field definition clauses are discussed in the following sections. 5.3.1 Specifying Level Numbers DATATRIEVE recognizes the levels offields in the record definition according to the level numbers you assign. The level number is the first element of a field definition. Level numbers are one- or two-digit numbers, ranging from the highest possible level, 1, to the lowest possible level, 65. Leading zeros, as in 01 or 05, do not affect the value of the level number. Figure 5-4 shows the level numbers for fields in the PERSONNEL record definition. 01 PERSON 05 ID 05 EMPLOYEE_STATUS 05 EMPLOYEE_NAME 10 FIRST_NAME 10 LAST_NAME 05 DEPT 05 START_DATE 05 SALARY 05 SUP_ID Figure 5-4: Level Numbers in the PERSONNEL Record Definition 5-4 Defining Records The level numbers apply to each group and elementary field: o Group fields contairi one or mote group or elementary fields. o Elementary fields contain one item of data and no other fields. The group field PERSON is the top-level field and the only field with the level number 01. Every record must have a top-level field. The group field EMPLOYEE_NAME, numbered 05, contains the elementary fields FIRST_NAME and LAST_NAME, numbered 10. The remaining fields, numbered 05 like the group field EMPLOYEE_NAME, are elementary fields at the same level as EMPLOYEE_NAME. If one of the elementary fields numbered 05 (DEPT, for example), were numbered 06, then that field would no longer be at the same level as the group field preceding it. If DEPT were numbered 06, then it would become a part of the group field EMPLOYEE_NAME. A group field is not just a marker of record structure and relationships among data items. A group field also gives you a way of using one name to refer to more than one field. You can access all the data in the PERSONNEL_REC record, for example, by using the group field PERSON. The following example shows how you can display all the data in a selected record in the PERSONNEL domain using the PERSON group field in aPRINT statement: DTR> READY PERSONNEL(@) DTR> FIND PERSONNEL(@) [23 records found] DTR> SELECT 3(@) DTR> PRINT PERSON(@) ID STATUS FIRST NAME 02843 EXPERIENCED CASS LAST NAME TERRY DEPT START DATE D88 2-Jan-80 SALARY SUP ID $28t808 38485 DTR> When you develop a record structure, keep in mind these four guidelines for using group and elementary fields: • A record definition must define at least one elementary field. • A record definition with more than one field definition must define a top-level group field that includes all other fields in the record. • A group field must contain at least one elementary field. • A group field can contain both elementary and group fields. Defining Records 5-5 Following are several rules for level numbers: • Level numbers need not be consecutive. Only the relative value of level numbers determines the relationship between fields. For example, the structure of the record would be no different from its present form if the fields numbered 05 had level numbers 02, and FIRST_NAME and LAST-N"AME had level numbers 47. Using similar increments in the numbers of successive levels is convenient but arbitrary. You do not have to use the same increment between levels. • Only the level numbers determine the relationships among fields. The examples of records in this book indent field names to show the relationships among levels of fields. Although indenting fields can make a record definition easy to read, it has no effect on the levels of fields and no effect on the relationships between fields. • You must use one number for all the fields at the same level in a group field, like FIRST_NAME and LAST-N"AME in PERSONNEL-REC. • The level number for a group field must be lower than the number for any field it contains. 5.3.2 Naming Fields You must name every field you define. You use field names to control the way DATATRIEVE retrieves, modifies, and stores data. If you do not specify a column header different from the field name, DATATRIEVE uses the field name as the column header when displaying data. 5.3.2.1 Restrictions for Field Names - The names you choose for fields must conform to the general restrictions for DATATRIEVE names, described in the DATATRIEVE-ll Reference Manual. In summary, the name: • Can consist of letters, digits, hyphens, dollar signs, and underscores • Must begin with a letter • Must not duplicate a DATATRIEVE keyword • Must be from 1 to 31 characters long • Must not duplicate the name of another dictionary object, domain, procedure, or table In most cases, DATATRIEVE displays an error message if you violate these rules. However, if you duplicate dictionary object names, you may not receive an error message or you may get unexpected results. For example, suppose you want to display the contents ofa field with the same name as a readied domain in your workspace. If you enter PRINT and the field name, DATATRIEVE associates the name with the domain rather than the field and displays the contents of the domain. DATATRIEVE associates the name with the field only ifit is the second name in a print list. 5-6 Defining Records You can continue a name from one input line to another by typing a hyphen at the end of the input line, pressing RETURN, and completing the name on the next line. To make the original information for the PERSONNEL record (Figure 5-1) conform to the rules for field names, change some of them. None of the names in the original information exceeds 30 characters, but several contain spaces, which are illegal characters in DATATRIEVE names. Figure 5-5 shows the necessary changes. IDENTIFICATION STATUS EMPLOYEE NAME DEPARTMENT START DATE SUPERVISOR'S IDENTIFICATION NUMBER --- 10 EMPLOYEE_STATUS EMPLOYEE_NAME FIRST_NAME LAST_NAME DEPT START_DATE SUP_ID Figure 5-5: Valid Field Names for EMPLOVEE_REC 5.3.2.2 Using Duplicate Field Names - DATATRIEVE does not require field names to be unique. You can have several fields in one record that have the same name. However, fields that share one name must be in different group fields. To refer to a field name that is a duplicate, prefix it with its group field name. The record is a field tree, not a simple linear list. No other field is equivalent to the top-level field. All other fields are at lower levels of the structure. The levels of the field tree define the relationships among group and elementary fields and determine the sequence DATATRIEVE follows in searching for the names of fields. In PERSONNEL-REC, the fields ID, EMPLOYEE_STATUS, EMPLOYEE-N"AME, DEPT, START-DATE, SALARY, and SUP--ID are at the same level, one level below the top-level PERSON. FIRST_NAME and LAST-N"AME are on the third level in the field tree. The following examples show some consequences of this structure: • If you specify EMPLOYEE_NAME.LAST-N"AME, DATATRIEVE looks at the field names in the group field EMPLOYEE-N"AME until it finds the desired field. When DATATRIEVE searches for the specified field, it finds the first field named EMPLOYEE-N"AME. Then it looks at the next level lower for the first field named L.aST-N"AME. DTR> FIND PERSONNELOO) [23 records found] DTR> SELECT 3(0) DTR> PRINT IDt EMPLOYEE_NAME.LAST_NAMEt SALARYOO) ID LAST NAME 02843 TERRY SALARY $28t80B DTR> Defining Records 5-7 If you had a duplicate field called LAST_NAME, perhaps under a group field SUP_NAME, you could use the tree structure to tell DATATRIEVE whether you wanted to print EMPLOYEE_NAME.LAST_NAME or SUP_NAME.LAST_NAME. • LAST_NAME, without any qualification, is also a valid and unique field name in PERSONNEL_REC because there is no duplicate for it in the present record. • If you tell DATATRIEVE to store a value in ID.FIRST_NAME, it does not find the field FIRST_NAME and does not store the value. It displays an error message that says: Field IIID.FIRST_NAME Il is undefined or used out of context In general, though you can have duplicate and even multiple field names, it is best to avoid duplicates. Unless you provide a qualified field name when referring to a duplicate field, DATATRIEVE retrieves the value of the first instance of the duplicate field name. If you intend to refer to an instance other than the first but do not specify it, you will receive the output of the first instance instead of what you intend. If you do choose to use duplicate or multiple field names, you should be careful to use qualified names when necessary. , 5.3.2.3 Using the Field Name FILLER - Sometimes you want to preserve fields in a data file without using them, usually for one of these reasons: • You may not need those fields for a particular application. • You may want to control the display of records so that you do not display certain data. • You may want to reserve space in the physical record of the data file. For these purposes, you can specify the keyword FILLER as the name of an elementary or group field. Like other fields, a field named FILLER must have a level number, and it can contain field definition clauses. Unlike other fields, the field name FILLER can belong to more than one field at the same"level in a group field. When you use the PRINT, LIST, MODIFY, STORE, REPORT, and SUM statements, DATATRIEVE ignores values in FILLER fields. When you use the DISPLAY statement, DATATRIEVE does display the values in FILLER fields. You cannot retrieve whole records or group fields containing a group field named FILLER. You can, however, retrieve values from the elementary and group fields included in a group field named FILLER. Each of those fields has its own valid name, and you can retrieve the value by specifying that name in a record selection expression, a print list, or a field list. Figure 5-6 shows a part of the YACHT record definition with FILLER in place of TYPE, the group field that contains MANUFACTURER and MODEL. It also shows the result of a SHOW FIELDS and two PRINT statements, one of the toplevel group field and one of an elementary field (MODEL) in the group field FILLER. 5-8 Defining Records Level numbers and field names of YACHT record with filler as group field 01 BOAT 03 FILLER 06 MANUFACTURER 06 MODEL 03 SPECIFICATIONS 06 RIG 06 LENGTH_OVER_ALL 06 DISPLACEMENT 06 BEAM 06 PRICE The effect of FILLER on SHOW FIELDS DTR> SHOW FIELDS(ffij YACHTS BOAT SPECIFICATIONS (SPECS) RIG [Character string] LENGTH_OVER_ALL (LOA) [Character string] DISPLACEMENT (DISP) [NuMber] BEAM [NUfrlb e r] PRICE [Nufrlber] DTR> The effect of FILLER as a group field on two PRINT statements DTR> FIND YACHTS; SELECT; PRINT(BTI) RIG LENGTH OI.IER ALL WEIGHT BEAM PRICE KETCH 37 20,000 $36,851 12 DTR) PRINT MODEL(ffij MODEL 37 MK II DTR> Figure 5-6: Using FILLER as a Group Field Name Defining Records 5-9 5.3.3 Using Field Definition Clauses DATATRIEVE handles the information in a field according to the type of data in the field definition. DATATRIEVE recognizes the following field definition clauses: • COMPUTED BY • EDIT_STRING • OCCURS • PICTURE • QUERY_HEADER • QUERY_NAME • REDEFINES • SIGN • USAGE • VALID IF When you write a DATATRIEVE record definition, use a PICTURE, USAGE, or COMPUTED BY clause to specify the type of data each elementary field contains. You can specify these classes of fields: • Alphanumeric Define an alphanumeric field with a PICTURE clause of the form PIC X(n), where n is an integer value describing the field width. The EMPLOYEE_STATUS field in the record PERSONNEL_REC, for instance, looks like this: 05 EMPLOYEE_STATUS PIC IS }-{(11). You can store any combination of characters in alphanumeric fields: letters, digits, and the special characters that are part of the DATATRIEVE character set. See the DATATRIEVE-ll Reference Manual for a definition of the DATATRIEVE character set. 5-10 Defining Records • Numeric You can store digits and an optional sign ( + or -) in numeric fields. DATATRIEVE assumes unsigned numbers to be positive in computations. In the YACHT record, DISPLACEMENT, BEAM, and PRICE are numeric fields. Define a numeric field with a PICTURE clause of the form PIC (n), where n is an integer value representing the field width, or with any of these USAGE clauses: - COMP (or INTEGER) - COMP-l (or REAL) - COMP-2 (or DOUBLE) - COMP-3 (or PACKED) - COMP-5 (or ZONED) USAGE clauses follow a field definition in the format: 08 EMPLOYEE_SALARY PIC IS 8(8) USAGE IS INTEGER. See the DATATRIEVE-ll Reference Manual for explanations of the internal storage for USAGE clauses. • Date Define a date field with the USAGE clause in the form USAGE IS DATE. You can store dates between 17-Nov-1858 and 28-Feb-2100 in a date field. You can use the values in date fields in some kinds of computations. For example, you can subtract one date from another to get the number of days elapsed between the two dates. • Computed by Define a computed by field with the COMPUTED BY clause. A computed by field in a record definition does not correspond to a field in the physical record stored in the data file and does not occupy space in a record. It specifies a value expression. For example, you can define a field named SALARY computed by multiplying the hourly pay of an employee (the WAGE field of the same record) by the number of hours worked (the HOURS field of the record). The field definition would be: 05 SALARY EDIT_STRING $$$8.88 COMPUTED BY WAGE * HOURS. DATATRIEVE computes the value of the field when you refer to it in a statement. Defining Records 5-11 An elementary field can belong to anyone of the four classes of fields - alphanumeric, numeric, date, or computed by. You do not need to use a clause to specify the data type for a group field. A group field is always alphanumeric. If you have stored only digits in a group field, you can use it in arithmetic computations. Table 5-1 summarizes the field classes and their content. Table 5-1 : Field Classes Field Type Class Elementary field Alphanumeric Any combination of characters Numeric Any combination of digits and optional plus ( + ) or minus (-) sign DATE A date COMPUTED BY None; the field definition specifies a value expression, but no value is stored in the record Alphanumeric The values of the fields contained in the group field Group-field 5.3.4 Content Specifying Query Names You can use the QUERY_NAME field definition clause to specify an alternative name for any field in your record definition. When you name a field, it is good to select a field name that is short enough to use easily but long enough to be meaningful, especially to other people who may use the record. At times, however, you may want to use an abbreviation or a memorable short name in place of the formal field name. For example, the YACHT record contains one field named LENGTH_OVER-ALL that is fifteen characters long. The name suggests the meaning of the data stored in that field and is therefore helpful to a person unfamiliar with the YACHTS domain. The field has a query name as well, LOA, to save you from having to type the complete name each time you refer to the field. You can use a query name in any DATATRIEVE statement where you can use the corresponding field name. Figure 5-7 shows a set of query names for PERSONNEL-REC. EMPLOYEE_STATUS EMPLOYEE_NAME FIRST_NAME LAST_NAME QUERY_NAME IS STATUS. QUERY_NAME IS NAME. QUERY_NAME IS F_NAME. QUERY_NAME IS L_NAME. Figure 5-7: Query Names for PERSONNEL_REC 5-12 Defining Records 5.3.5 Specifying Word Boundary Alignment with the ALLOCATION Clause The ALLOCATION clause determines which word boundary alignment DATATRIEVE uses when storing records in the data file. You can specify one of three kinds of alignment: • LEFT_RIGHT • MAJOR_MINOR • ALIGNED_MAJOILMINOR For explanations of the three word boundary alignments, see the DATATRIEVE-ll Reference Manual. If you do not specify otherwise, DATATRIEVE-ll uses LEFT-RIGHT alignment. If you attempt to use DATATRIEVE-ll on a data file created with an alignment other than LEFT_RIGHT, be sure to specify the matching alignment in the DATATRIEVE-ll record definition. VAX DATATRIEVE, for instance, uses MAJOR_MINOR as the default alignment. You must specify MAJOR-MINOR in your DATATRIEVE-l1 record definition if you wish to use a data file created on VAX DATATRIEVE. If the alignment in the record definition does not match the alignment in the data file, you receive this message: File and dOMain record 5.4 len~ths don't Match (D=57) Using the OCCURS Clause to Define Hierarchical Records At times, to save space in your record definition, you may want to define one or more fields as list fields. Compare, for instance, the following two sample output lines from the domain FAMILIES. The first does not use a list field but instead includes a separate field in the record for each child. The second does use a list field: DTR> PRINT FIRST 1 FAMILIES@) FATHER JIM MOTHER ANN KID NAME AGE KID NAME URSULA 7 RALPH KID NAME AGE URSULA RALPH 7 3 AGE 3 DTR> DTR> PRINT FIRST 1 FAMILIES@) FATHER JIM MOTHER ANN NUMBER KIDS 2 DTR> Defining Records 5-13 Records without lists are flat records, because the elementary fields in them are logically equivalent to each other. When you print a flat record, all the elementary fields display on the same line. Without an OCCURS clause, the record for FAMILIES can look like the one shown in Figure 5-8. 01 FAMILY_REC. 03 PARENTS. 06 FATHER PIC }-{ ( 10) • 06 MOTHER PIC X( 10) • 03 KIDS. 06 FIRST_KID. 08 KID_NAME PIC X(10). 08 AGE PIC 88 EDIT_STRING IS Z8. 06 SECOND_KID. 08 KID_NAME PIC X(10). 08 AGE PIC 88 EDIT_STRING IS Z8. Figure 5-8: A Flat Record When using an OCCURS clause, however, you can define a record with fields that are lists. A record containing a list or lists is not a flat record, but a hierarchical record. In hierarchical records, elementary fields are not alllogically equivalent to each other. The list field displays on the same line as the elementary fields with the same number, but the list items display on additional lines beneath the list field. With an OCCURS clause for KIDS, the record FAMILY-REC can look like the one in Figure 5-9, a sample record installed wi th your system. DTR> SHOW FAMILY_RECCBIfl RECORD FAMILY_REC 01 FAMILY. 03 PARENTS. 06 FATHER PIC X(10). 06 MOTHER PIC X(10). 03 NUMBER_KIDS PIC 88 EDIT_STRING IS Z8. 03 KIDS OCCURS 0 TO 10 TIMES DEPENDING ON NUMBER_KIDS. 06 EACH_KID. 08 KID_NAME PIC X(10) QUERY_NAME IS KID. 08 AGE PIC 88 EDIT_STRING IS Z8. DTR> Figure 5-9: A Hierarchical Record The OCCURS clause in the record definition creates the hierarchical structure. The clause can define a variable-length or a fixed-length list. The following two sections discuss fixed-length and variable-length lists for hierarchical records. 5-14 Defining Records 5.4.1 Defining Lists with a Fixed Number of Occurrences The OCCURS clause format for fixed length lists is OCCURS n TIMES, where n is the number of occurrences. If you define the record for FAMILIES using OCCURS 2 TIMES, the record definition looks like this: 03 KIDS_NAMES OCCURS 2 TIMES. 05 FIRST_NAME PIC X(10). 05 AGE PIC 99 EDIT_STRING IS Z9. The definition specifies that the group field KIDS_NAMES occurs twice. Each occurrence of KIDS-NAMES contains two fields, FIRST-NAME and AGE. When DATATRIEVE displays the fixed record, the output looks like this: DTR> PRINT FIRST 2 FAMILIES(@) FIRST NAME FATHER JIM JIM MOTHER ANN LOUISE AGE URSULA RALPH ANN JIM 7 3 31 29 DTR> You can use OCCURS n TIMES with an elementary or group field, and a record definition can contain any number of OCCURS clauses in this format. That is, an OCCURS clause can contain another fixed-length OCCURS clause. 03 KIDS_NAMES OCCURS 2 TIMES 05 FIRST_NAME PIC X(10). 05 AGE PIC 99 EDIT_STRING IS Z9. 05 NICKNAME PIC X(10) OCCURS 3 TIMES. If you define a hierarchical record with a list that occurs a fixed number of times, every record in the domain contains enough space to store the same number of list items. If the first two families had only one child, for instance, the FAMILIES domain with a fixed number of occurrences would print a blank line for the second child: DTR> PRINT FAMILIES(@) FIRST NAME FATHER MOTHER AGE JIM ANN URSULA JIM LOUISE ANNE 7 0 31 0 DTR> Defining Records 5-15 A field definition cannot contain both an OCCURS and a COMPUTED BY clause. That is, you cannot specify multiple occurrences of a COMPUTED BY field. 5.4.2 Defining Lists with a Variable Number of Occurrences Using the OCCURS clause in a field definition defines a hierarchical record that allows a variable number of list items from one record to another. This format lets you vary the number of list items in the records of a domain: OCCURS min TO max TIMES DEPENDING ON field-name The record definition for FAMILIES uses the OCCURS clause to define KIDS as a variable-length list. The KIDS variable-length list for FAMILY-REC is shown in Figure 5-9. The output of the PRINT command shows the relationship between NUMBER_KIDS and the fields KID_NAME and AGE. The values of KID-NAME and AGE appear as a list in records with more than one kid: DTR> PRINT FAMILIESffiITj FATHER NUMBER KIDS KID NAME URSULA RALPH ANNE JIM ELLEN DA1.JID ROBERT ANN JEAN CHRISTOPHR SCOTT BRIAN DA1.JID PATRICK SUZIE BEAU BROOKS ROBIN JAY WREN JILL 7 3 31 28 26 24 16 28 26 0 2 0 0 4 6 28 26 24 ERIC CISSY NANCY MICHAEL MARTHA TOM JEFF FRED LAURA CHARLIE HAROLD SARAH ERIC SCOTT 32 24 JIM ANN 2 JIM LOUISE 5 JOHN JULIE 2 JOHN ARNIE ELLEN ANNE 2 SHEARMAN TOM SARAH ANNE 2 BASIL MERIDETH 6 ROB JEROME DIDI RUTH 0 4 TOM BETTY 2 GEORGE LOIS 3 HAROLD SARAH 3 EDWIN TRINITA 2 DTR> 5-16 MOTHER Defining Records AGE 22 17 20 '?'? .:.....:.... 20 30 27 23 26 21 31 35 27 16 11 When you define a record with a variable-length list in it, you must put the list at the end of the record definition. You can use only one field with an OCCURS clause. That is, you cannot have an OCCURS clause within an OCCURS clause. If you attempt to define another field after an OCCURS clause and at the same level, you receive the following error message: ONLY Subordinate fields allowed after OCCURS DEPENDING ON 5.4.3 Nesting Lists Within Lists to Form Sublists Although you can use only one OCCURS clause in a record definition, you can define fixed-length lists within a variable-length list. In fact, you can include any number of OCCURS n TIMES clauses within a field defined with an OCCURS clause. This sample record definition with a sublist is an extension of the FAMILY record. The list PET occurs twice for each kid, so each kid in each family can record the data for two pets: DTR> SHOW PETS®0 DOMAIN PETS USING PET_REC ON PET.DAT; DTR> SHOW PET_REC®0 RECORD PET_REC 01 FAMILY. 03 PARENTS. 06 FATHER PIC X(10). 06 MOTHER PIC X(10). 03 NUMBER_KIDS PIC 88 EDIT_STRING IS Z8. 03 KIDS OCCURS 0 TO 10 TIMES DEPENDING ON NUMBER_KIDS. 06 EACH_KID. 08 KID_NAME PIC X(10) QUERY_NAME IS KID. 08 KID_AGE PIC 88 EDIT_STRING IS Z8. 08 PET OCCURS 2 TIMES. 13 PET_NAME PIC X(10). 13 PET_AGE PIC 88. DTR> READY PETS®0 DTR> PRINT FIRST 2 PETS®0 FATHER JIM JIM MOTHER LORAINE ANN KID NAME KID AGE PET NAME PET AGE GARY 24 SUE 23 URSULA 7 POP SODA MOUSE SHORTY SQUEEKY FRANK RALPH 3 03 04 03 08 03 07 00 00 NUMBER KIDS 2 2 Defining Records 5-17 5.4.4 Changing the Length of a List If you define -a record-with the OCCURS clause, you can change the number of occurrences in a list. If you specify the MAX clause when defining the data file, all records have enough space for the maximum number of occurrences, and you can always change the number of occurrences up to the limit you have set: DTR) DEFINE FILE FOR FAMILIES MAX If you do not specify the MAX clause when you define a sequential file, DATATRIEVE sets the length of each record when you store it. In that case, you cannot add examples to the list. You can always decrease the number of occurrences, though, and you can increase the number of occurrences back to the original number. If you do not specify the MAX clause and the file organization is indexed, you can still change the number of occurrences. The following example shows how to add items to a list. Because you are modifying an existing record, you use MODIFY rather than STORE to add items to the list: DTR> READY INDEXED_FAMILIES WRITE(@) DTR> FIND FIRST 1 INDE){ED_FAMILIESffiIT) [1 Record found] DTR> SELECT; PRINTffiIT) FATHER JIM MOTHER ANN NUMBER KIDS 2 KID NAME URSULA RALPH AGE 7 3 DTR> MODIFY NUMBER_KIDS(@) Enter NUMBER_KIDS: llffiIT) DTR> FIND KIDSffiIT) [ll records found] DTR> SELECT 3(@) DTR> MODIFY(@) Enter KID_NAME: NICKY(@) Enter AGE: 2ffiIT) DTR> SELECT llffiIT) DTR > ~10D I FY(@) Enter KID_NAME: TAM(@) Enter AGE: lffiIT) DTR> PRINT FIRST 1 INDE>~ED_FAMILIESffiIT) FATHER JIM MOTHER ANN NUMBER KIDS II KID NAME URSULA RALPH NICKY TAM AGE 7 3 2 DTR> For information on retrieving data from hierarchical records, see Chapter 14 in this manual. . 5-18 Defining Records Defining Files 6 The way you define a data file determines how much storage space the file occupies, how quickly you can retrieve data from the file, and whether you can change or duplicate data fields in that file. DATATRIEVE is based on RMS, the standard DIGITAL record and file management software facility. Based on how you define your data files, DATATRIEVE uses RMS to create, define, store, manipulate, and maintain information within your files. Your operating system documentation will give you more information onRMS. You can define two types of files in DATATRIEVE: • Sequential files, which store records in the order you enter them • Indexed files, which store records according to the order of a specified key field This chapter discusses the DEFINE FILE command, the choices you have when deciding whether to use sequential or indexed files, and other options available to you when you define a file in DATATRIEVE. 6.1 Choosing a Sequential or an Indexed File Sequential files require less storage space than indexed files but it often takes longer to retrieve data from sequential files. To retrieve records from a sequential file, DATATRIEVE searches records one by one according to their order in the file. To retrieve records from an indexed file, DATATRIEVE searches the file according to specified key fields. The key fields are searched first, regardless of their order in the data file. 6-1 Sequential organization is useful in certain applications. For example, if your records contain a date field and you frequently retrieve them in chronological order, it is often best to arrange the records in the order you stored them. You are likely to want sequential access to banking transactions, for example. D se sequential files for accessing large groups of records in the order you stored them. In other cases, sequential organization may be unnecessarily slow. When you use a record selection expression (RSE) to form a record stream or collection of records from a sequential file, DATATRIEVE has to start at the beginning of the file and read every record until it finds the ones that you request. If you use an RSE to form a record stream based on key fields, RMS searches through the index it maintains without having to read every record. If you need to access a small number of records distributed throughout a file, use an indexed file. 6.1.1 Modifying and Deleting Records Because of differences in file organization, you modify and delete records differently for sequential and indexed files. In a sequential file, you can use the MODIFY statement to change any field, but in an indexed file, you cannot modify the primary key field. You also cannot modify secondary key fields defined with the NO CHANGE clause explained in the section on optional clauses later in this chapter. RMS does not allow you to use the ERASE statement in a sequential file where sequence is the basis of the file organization. If you need to erase records from your data file, use an indexed file. You can, however, use the MODIFY statement on records in sequential files and change every field to zero or spaces depending on the data type. 6.1.2 Summary of Differences Table 6-1 summarizes the differences between sequential and indexed files. Table 6-1: A Comparison of Sequential and Indexed Files SEQUENTIAL FILE 6-2 INDEXED FILE Stores records in the order you create them Stores records according to the values in the primary key field Takes up less storage space than an indexed file Allows you to retrieve certain data faster than a sequential file does Allows you to modify any field Does not allow you to modify primary key field or any key field that has NO CHANGE attribute Requires you to use MODIFY instead of ERASE Lets you use ERASE statement Defining Files 6.2 Defining a File Using the DEFINE FILE Command DATATRIEVE can store and retrieve data using existing RMS data files, so it is compatible with other languages or utilities that use RMS. It can also create RMS files, including sequential files and multi key indexed files. The DEFINE FILE command forms an RMS data file for the domain you specify. It uses the format: DEFINE FILE [FOR] domain-name [,] ALLOCATION = SUPERCEDE n] [, ... ] L MAX { KEY = field-name-1 [([NO]CHANGE[,] [NO] DUP)]} [, ... ] The DATATRIEVE-ll Reference Manual also discusses the DEFINE FILE command. 6.2.1 Defining a Sequential File If you decide you want your data file to be sequential, follow these steps: 1. Before you define a data file, the associated domain and record definitions must be in your dictionary. You can use the SHOW command to be sure that they are in place: DTR> SHOW YACHTS_SEQUENTIAL, YACHTffiITj DOMAIN YACHTS_SEQUENTIAL USING YACHT ON YACHT.SEQ ; RECORD YACHT USING 01 BOAT. 03 TYPE. 06 MANUFACTURER PIC X(10) QUERY_NAME IS BUILDER. 06 MODEL PIC X(10). 03 SPECIFICATIONS QUERY_NAME SPECS. 06 RIG PIC ~«6) 1.IALID IF RIG EQ "SLOOP" ,"KETCH" ,"MS" ,"YAWL". 06 LENGTH_OVER_ALL PIC XXX VALID IF LOA BETWEEN 15 AND 50 QUERY_NAME IS LOA. 06 DISPLACEMENT PIC 99999 QUERY_HEADER IS· WE I GHT EDIT_STRING IS ZZ,ZZ9 QUERY_NAME IS DISP. 06 BEAM PIC 99. 06 PRICE PIC 99999 VALID IF PRICE>DISP*I.3 OR PRICE EQ 0 EDIT_STRING IS $$$,$$$. II II DTR> Defining Files 6-3 2. Use the DEFINE FILE command to define the file. For a sequential file, you need specify only the domain name in the DEFINE FILE command: DTR> DEFINE FILE FOR YACHTS_SECJlliill DTR> 3. Select the options you want to use with the file, as explained in the later section on optional clauses. 6.2.2 Defining an Indexed File You use the KEY clause in the DEFINE FILE command to create an indexed file. The clause creates an indexed file and specifies a field in the record definition to be an index key for the domain's data file. The first key field you name in the DEFINE FILE command is the primary key. All subsequent keys are alternate keys. If you decide you want your file to be indexed, first analyze your record definition to decide which field or fields you want to be key fields. You can designate only one primary key field, but you can name as many alternate key fields as you wish from the remaining fields in the record. DATATRIEVE searches the primary and alternate fields independently, so defining alternate keys does not slow performance for queries based on the primary key. To choose a primary key, decide which field of the record you are likely to name most often in queries. Make certain you will not want to change that field, because DATATRIEVE does not allow you to change the values in primary keys. Finally, look for a field that has a unique value for each record. Unless you specify otherwise, DATATRIEVE does not allow you to have the same value in more than one primary key field. For instance, you could not have two records in PERSONNEL with the ID 99883. You can use the DUP option to allow duplicates, as explained later in this chapter, but duplicate values slow performance. If you were setting up a PERSONNEL domain, you might predict that most users seeking information on an employee would base their search on the ID. You would not want to change identification numbers, and no two employees should have the same identification number. Consequently, ID uniquely identifies a record and is a good primary key for your PERSONNEL domain. This DEFINE FILE command would make ID the primary key for the indexed file PERSONNEL: DTR> DEFINE FILE FOR PERSONNEL, KEY=IDlliill DTR> 6-4 Defining Files 6.2.2.1 Using a Group Field as the Primary Key - If the field you use most often does not uniquely identify each record, you can find another field that, together with the first, does identify the record. Then designate a group field made up of the two fields as the primary key. In the domain YACHTS the elementary field MANUFACTURER does not uniquely identify a record. ALBIN, for instance, is the builder of three of the first five YACHTS: DTR) PRINT FIRST 5 YACHTS(@) MANUFACTURER MODEL RIG LENGTH OI.JER WEIGHT BEAM ALL ALBERG ALBIN ALBIN ALBIN AMERICAN 37 MK I I 79 KETCH SLODP SLOOP SLOOP SLOOP 37 28 30 27 28 BALLAD VEGA 28 PRICE 20,000 4,200 7,278 5,070 4,000 $38,951 $17,900 $27,500 $18,800 $9,895 12 10 10 08 08 DTR) The combination of MANUFACTURER and MODEL, however, is unique for each record. These two fields are defined as the group field TYPE in the YACHT record definition. Therefore, TYPE, which has no duplicate values, makes a suitable primary key. Note that when you use a group field as a primary key, you cannot modify any of the elementary fields in the group. In addition, note that BUILDER has been defined as a query name for MANUFACTURER in the YACHT record definition. This means you can use the shorter name BUILDER in place of MANUFACTURER in queries. If a group field is the primary key, list the field most commonly used in queries as the first elementary field in the group field. The field MANUFACTURER (BUILDER) appears in queries more frequently than MODEL, for example. When a group field such as TYPE is defined as a key field, keyed access will work only for queries involving the group field itself or the first elementary field in the group. With TYPE as the key field, DATATRIEVE conducts an indexed search for TYPE or BUILDER but a sequential search for the second elementary field, MODEL. If you want DATATRIEVE to use the first elementary field in a group field as a key, you must define that first field as either PIC X or PIC 9 in the group field definition. When you ready the domain, DATATRIEVE uses the group field as the key. If the first elementary field is anything but a simple numeric or character string, it is not treated as a key when the domain is readied. 6.2.2.2 Defining Alternate Keys - If there are additional fields that you often use in queries, you can define them as alternate keys. DATATRIEVE performs an indexed search when you refer to an alternate key in a query. Defining Files 6-5 You could make LENGTH_OVER-ALL an alternate key for YACHTS. Use this form of the DEFINE FILE command: DTR> DEFINE FILE FOR YACHTS KEY = TYPE. KEY = LOAm DTR> DATATRIEVE allows duplicate values for the alternate keys unless you specify otherwise with the NO DUP option explained in a later section on options. Chapter 17 in this manual tells how to use key fields for optimum processing. Summary of Rules for Defining Key Fields - To set up key fields that DATATRIEVE can process most efficiently, use these guidelines: 6.2.2.3 • When defining data, make the field most commonly used in queries the primary key. • If the most commonly used field does not uniquely identify a record, combine it with another field in a field group so that the group field identifies the record. • Avoid duplicate values of a primary key when possible because duplications slow performance. • If you decide to make a group field the primary key, list the field most commonly used in queries as the first elementary field. • If your record has other fields you often use with the primary key in queries, designate them as alternate keys. 6.2.3 Optional Clauses with the DEFINE FILE Command You can use the following options in your DEFINE FILE command for both sequential and indexed files: • ALLOCATION = n ALLOCATION in the DEFINE FILE command refers to the allocation of disk blocks to a file. If you do not specify an allocation for a sequential file that you create, DATATRIEVE allots zero blocks to the file and then assigns space as needed. For an indexed file, it allots a small space when you create the file and addi tional space as needed. If you know your file is going to be large, however, you can use the ALLOCATION == n clause to reserve storage space for the file and increase the speed at which you can store records: OTR> DEFINE FILE FOR YACHTS ALLOCATION DTR> = 2000m See Chapter 17 for a discussion of techniques for optimizing response time and workspace. 6-6 Defining Files • SUPERSEDE If you specify SUPERSEDE in your DEFINE FILE command, DATATRIEVE deletes the existing file with the same name and replaces it with the new one. Because RSTS/E systems keep only one version of a file, you must specify SUPERSEDE on RSTS/E systems when defining a file to replace one that already exists. If you do not, DATATRIEVE sends you an error message and does not create the new file: DrR) DEFINE FILE FOR YACHTSffiIfl File IIYACHT.DAT II alread}' exists DTR) On RSX systems, be sure that the complete file specification, including version number, duplicates the one you want to replace. Otherwise, DATATRIEVE keeps both the old and the new files. If the file you want to replace is YACHT.DAT;l, you would specify the replacement file as follows: DTR) DEFINE DOMAIN YACHTS USING YACHT ON YACHT.DAT;lffiIfl DTR) DEFINE FILE FOR YACHTS SUPERSEDEffiIfl DTR) • MAX As explained in Chapter 5, a record defined with the OCCURS clause allows you to vary the number of occurrences in a list. For a record with an OCCURS clause, use the MAX clause when defining the file. This reserves space in every record for the maximum possible number of list items. The record for FAMILIES, for instance, has this OCCURS clause: 03 KIDS OCCURS 0 TO 10 TIMES DEPENDING ON NUMBER_KIDS. If you request the MAX option when defining a file for FAMILIES, you reserve space for 10 kids in each record. Use this form of the command: DTR> DEF I NE FILE FOR FAM I LIES DTR) MM-{(8TI) If you do not specify the MAX clause when you define a sequential file, DATATRIEVE sets the length of each record when you store it. In that case, you cannot add additional elements to the list. You can decrease the number of occurrences and you can also increase the number of occurrences back to the original number. If you specify more than one option in the DEFINE FILE command, separate each from the next with a comma. You do not have to specify the options in any particular order. DTR> DEFINE FILE FOR FAMILIES SUPERSEDEt ALLOCATION DTR> 2000 t MA>~ffiIfl Defining Files 6-7 You can use these optional clauses with indexed files: • CHANGE or NO CHANGE The CHANGE or NO CHANGE clause determines whether or not you can modify the contents of the key field associated with the clause. To specify the CHANGE or NO CHANGE option, put the clause in parentheses after the name of the key field: DTR> DEFINE FILE FOR YACHTS KEY DTR> = TYPE (NO CHANGE)OO You cannot specify CHANGE for a primary key. CHANGE is in effect for alternate keys unless you specify otherwise . • DUP or NO DUP The DUP or NO DUP clause determines whether or not you can assign the same value to the specified key field in more than one record. Can more than one YACHTS record, for instance, have the value ALBIN for the key field BUILDER? NO DUP is the default for primary keys. However, DATATRIEVE allows you to specify DUP for primary keys. You may slow performance in retrieving records if you do so, because DATATRIEVE performs an indexed search to find the primary key and then a sequential search through the duplicates when it finds them. For alternate keys you can, by default, use duplicate values. You can specify NO DUP if you like, but eliminating duplicates from an alternate key field can limit the number of records you can store successfully. If you assigned RIG as an alternate key and specified the NO DUP option, for instance, you could store only four records in YACHTS: one sloop, one ketch, one yawl, and one MS. If you do not want duplicates and you do not want the alternate key values to change, put both sets of keywords in parentheses and separate them with a comma: KEY = field-name (NO DUP, NO CHANGE). This example defines an indexed file for YACHTS. It uses the group field TYPE as the primary key with the DUP option in effect, and RIG as an alternate key with the NO CHANGE option in effect: DTR> DEFINE FILE FOR YACHTS KEY = TYPE (DUP) tOO DFN> KEY = RIG (NO CHANGE)OO DTR> 6-8 Defining Files Limiting Record Streams with Record Selection Expressions 7 You define and store data so you can retrieve information in whatever form is most useful. You may want to perform any of these activities: • Display a group of records (PRINT or REPORT statements) • Form a temporary collection of records (FIND statement) • Update a group of records (MODIFY statement) To carry out any of these tasks, you must identify a record stream, that is, a group of records from a domain or collection. You form record streams with DATATRIEVE by specifying a record selection expression (RSE). By including various clauses in the RSE, you can determine the content of the record stream in several ways: • By specifying the number of records in the record stream (FIRST n clause) • By limiting the record stream to records that meet a conditional test (WITH clause) • By sorting the records according to the values of one or more fields (SORTED BY clause) This chapter presents many examples to teach you how to use RSEs. The examples use RSEs with the PRINT statement, but you may use them with FIND, REPORT, or other DATATRIEVE statements. In addition, see Chapter 14 for information about another form ofRSE that lets you access list items from hierarchical records. 7-1 7.1 Accessing All the Records in a Domain If a domain does not contain many records, you may be satisfied to display all of the records. You form one type of PRINT statement by typing PRINT followed by an RSE; for example: DTR> READY YACHTStllil DTR> PRINT YACHTStllil MANUFACTURER MODEL RIG LENGTH OVER ALL WEIGHT BEAM ALBERG ALBIN ALBIN ALBIN AMERICAN AMERICAN BAYFIELD BLOCK I • BOMBAY BUCCANEER BUCCANEER CB:C 37 MK I I 79 BALLAD I.JEGA 26 26-MS KETCH SLOOP SLOOP SLOOP SLOOP MS SLOOP SLOOP SLOOP SLOOP SLOOP SLOOP 37 26 30 27 26 26 32 39 31 27 32 31 20,000 4,200 7,276 5,070 4,000 5,500 9,500 18,500 9,400 5,000 12,500 8,650 12 10 10 08 08 08 10 12 11 08 10 09 $36,951 $17,900 $27,500 $18,600 $9,895 $18,895 $32,875 SLOOP SLOOP SLOOP SLOOP SLOOP 22 2,000 6,700 19,500 650 14,900 07 08 11 07 00 $3,564 $15,245 VENTURE WESTERLY WESTSAIL WINDPOWER WRIGHT 30/32 40 CLIPPER 270 320 CORI,IETTE 222 CENTAUR 32 IMPULSE SEAWIND I I 26 32 16 32 PRICE $23,950 $3,500 $34,480 DTR> The PRINT YACHTS statement gives a display of all the records in the YACHTS domain. The source for the RSE is YACHTS, the name of the domain. Each RSE must include a source for the records, either a domain name, collection name, or list name. For clarity, you may want to specify the keyword ALL when you want a record stream to include all the records in a domain. The keyword ALL is optional. For example, PRINT ALL YACHTS and PRINT YACHTS are equivalent. 7-2 Limiting Record Streams with Record Selection Expressions 7.2 Specifying the Number of Records in the Record Stream The keywords ALL and FIRST let you indicate the number of records in the record stream. To specify the number of records in the record stream, type FIRST followed by a number before typing the source for the RSE. For example: DTR> PRINT FIRST 5 YACHTS(@:) MANUFACTURER MODEL RIG LENGTH OI.IER ALL WEIGHT BEAM ALBERG ALBIN ALBIN ALBIN AMERICAN 37 MK I I 78 KETCH SLOOP SLOOP SLOOP SLOOP 37 26 30 27 26 BALLAD I)EGA 26 PRICE 20,000 a,200 7,276 5,070 a,ooo $36,851 $17,800 $27,500 $18,600 $8,885 12 10 10 08 08 DTR> In this case FIRST 5 YACHTS is the RSE. DATATRIEVE displays the first five records in YACHTS according to their order in the data file. An RSE can have either form: for a domain for a collection FIRST n domain-name FIRST n collection-name - where n is any number less than or equal to the total number of records in the domain or collection. Ifn is greater than the number of records in the source, DATATRIEVE gives you all the records that fulfill the RSE and does not display a message on your terminal. Limiting the record stream can be useful when you are testing procedures, complex RSEs, or report specifications. You can conduct your tests without having to wait for DATATRIEVE to display the complete set of records. Specifying the number of records can be useful, too, when you want to display a fixed number of those records that meet the requirements of the RSE: DTR> PRINT FIRST 5 YACHTS WITH PRICE NE O(@:) MANUFACTURER MODEL RIG LENGTH OI.IER ALL WEIGHT BEAM ALBERG ALBIN ALBIN ALBIN AMERICAN 37 MK I I 78 KETCH SLOOP SLOOP SLOOP SLOOP 37 26 30 27 26 BALLAD 1.IEGA 26 PRICE 20,000 a,200 7,276 5,070 a,ooo $36,851 $17,800 $27,500 $18,600 $8,885 12 10 10 08 08 DTR> Limiting Record Streams with Record Selection Expressions 7-3 7.3 Identifying Records with Conditional Expressions There are several ways to limit the number of records in the record stream. Often you are interested in grouping similar records together, regardless of their position in the domain or record stream. You can restrict the record stream to those records that satisfy a specified condition by using the WITH clause of the RSE. Different forms of the WITH clause specify different types of relationships between the values of the same field for different records. You can form record streams based on: • Patterns among the field values (EQUAL, NOT EQUAL, CONTAINING) • Field values that fall within a specified range (BETWEEN ... AND ... , LESS THAN, GREATER THAN) • Field values you can or cannot find in a table 7.3.1 Comparing Records by Pattern Recognition You can group records if the characters of a field value are equal or not equal to a specified value; for example: DTR> PRINT YACHTS WITH BUILDER MODEL RIG LENGTH OI.JER WEIGHT BEAM ALL BALLAD IJEGA SLOOP SLOOP SLOOP 26 30 27 MANUFACTURER ALBIN ALBIN ALBIN = IIALBINII([IT) 78 4t200 7t276 5t070 10 10 08 PRICE $17t800 $27t500 $18t600 DTR> This statement asks DATATRIEVE to examine each record of the YACHTS domain and display only those records with the value "ALBIN" for the BUILDER field. After testing each record of YACHTS, DATATRIEVE identifies and then displays each record that meets the specified condition. WITH BUILDER = "ALBIN" lets you limit the record stream to the records you wish to access. The expression, BUILDER = "ALBIN", is a Boolean expression. A Boolean expression controls a comparison between value expressions. A Boolean expression is either true or false depending on the values of the field and the value expression specified. The term that relates the value expressions is called a relational operator. In this example the relational operator is the equal sign (=). When you use EQUAL ( = ) or NOT EQUAL, you can list more than one value expression in the same Boolean expression. The following queries specify a group of value expressions for DATATRIEVE to compare with each field value. The 7-4 Limiting Record Streams with Record Selection Expressions comma here is equivalent to saying AND BUILDER =, so that the statement tells DATATRIEVE to print all yachts by Albin and all yachts by Alberg: DTR> PRINT YACHTS WITH BUILDER = "ALBIN" t "ALBERG" MANUFACTURER ALBIN ALBIN ALBIN ALBERG MODEL RIG LENGTH OI.IER ALL WEIGHT BEAM 78 BALLAD I)EGA 37 MK I I SLOOP SLOOP SLOOP KETCH 28 30 27 37 4t200 7t278 5t070 20tOOO 10 10 08 12 PRICE $17t800 $27t500 $18t800 $38t851 DTR> PRINT YACHTS WITH RIG NOT EQUAL "SLOOP" t "KETCH" MANUFACTURER AMERICAN EASTWARD FJORD LINDSEY ROGGER FD MODEL 28-MS HO MS 33 39 MIS RIG LENGTH OVER ALL WEIGHT BEAM MS MS MS MS MS 28 24 33 39 35 5t500 7tOOO 14tOOO 14t500 17t800 08 08 11 12 11 PRICE $18t885 $15t900 $35t900 DTR> Note that the EQUAL (=) and NOT EQUAL operators are case sensitive. They see uppercase and lowercase letters as different: DTR> FIND YACHTS WITH BUILDER "AI bin "ffiTI) [0 records found] DTR> FIND YACHTS WITH BUILDER "ALBIN"ffiTI) [3 records found] Because the builders' names are in uppercase letters in the data file but lowercase letters in the first query, DATATRIEVE did not find any record for a builder named "Albin". However, for "ALBIN", it found three records. On the other hand, the CONTAINING operator is indifferent to the case of the letters. It finds matches if there is agreement with all of the letters in the field value or with a substring derived from the field value. Thus the CONToperator finds the "ALBIN" record if you specify either "Albin" or "bin", a three letter substring: DTR> FIND YACHTS WITH BUILDER CONT "AIbin"ffiTI) [3 records found] DTR> PRINT YACHTS WITH BUILDER CONT "bin"ffiTI) MANUFACTURER ALBIN ALBIN ALBIN MODEL RIG LENGTH OI.IER ALL WEIGHT BEAM 79 BALLAD VEGA SLOOP SLOOP SLOOP 28 30 27 4t200 7t278 5t070 10 10 08 PRICE $17t900 $27t500 $18t800 DTR> Limiting Record Streams with Record Selection Expressions 7-5 DATATRIEVE finds and displays each record that contains the substring "bin" in the value for BUILDER. Note that another difference between EQUALS and CONTAINING is that DATATRIEVE can optimize EQUALS if the field is an RMS key, but it cannot optimize for CONTAINING. The CONTAINING operator always reads every record in the file. The EQUALS operator does not have to read each record if the field is a key. 7.3.2 Grouping Records When Values Fall Within a Range DATATRIEVE allows you to use a variety of relational operators to test whether a field value for a record falls within a specified range. These operators are GREATER_THAN (> or GT), GREATEILEQUAL (GE), LESS_THAN « or LT), LESS_EQUAL (LE), and BETWEEN (BT): DTR> PRINT YACHTS WITH PRICE GREATER_THAN 50000(@) MANUFACTURER MODEL RIG LENGTH Ot.JER ALL WEIGHT BEAM CHALLENGER ISLANDER OLYMPIC £11 FREEPORT ADVENTURE KETCH KETCH KETCH £11 £11 £12 PRICE 26,700 22,000 2£1,250 $51 ,228 $5£1,870 $80,500 13 13 13 DTR> PRINT YACHTS WITH PRICE GREATER_EQUAL 50000(@) MANUFACTURER MODEL RIG LENGTH Ot.JER ALL WEIGHT BEAM CHALLENGER ISLANDER NORTHERN OLYMPIC £11 FREEPORT 37 ADt.JENTURE KETCH KETCH KETCH KETCH £11 £11 37 £12 PRICE 26,700 22,000 111,OOO 2£1,250 $51 ,228 $5£1,870 $50,000 $80,500 13 13 11 13 DTR> Note the difference between the two record streams. Northern, priced at exactly $50,000, appears when the Boolean expression is PRICE GREATER-EQUAL 50000, but it does not appear when you use the GREATER-THAN operator. The LESS_THAN and LESS-EQUAL operators work in a similar manner. The LESS_EQUAL operator includes a record if its field is either less than or equal to the value expression specified. The BETWEEN operator is the equivalent of the GREATER-EQUAL and LESS-EQUAL operators combined. It searches for records with field values that are within the range specified or equal to either of the value expressions that determine the range. For the BETWEEN operator to work, the range must go from a smaller value to a larger one. In the following example, the Boolean 7-6 Limiting Record Streams with Record Selection Expressions expression identifies a record stream that includes records with values for PRICE between $50,000 and $90,000: DTR> PRINT YACHTS WITH PRICE BETWEEN 50000 AND 80000CBIf) MODEL RIG LENGTH OVER ALL WEIGHT BEAM FREEPORT KETCH KETCH KETCH KETCH 41 41 37 42 MANUFACTURER CHALLENGER ISLANDER NORTHERN OLYMPIC 41 37 ADtJENTURE PRICE 26,700 22,000 14,000 24,250 $51 ,228 $54,870 $50,000 $80,500 13 13 11 13 DTR> 7.3.3 Grouping Records by Reference to a Table Some domains are associated with dictionary tables containing code strings that correspond to values in a field in the record. You can form an RSE that causes DATATRIEVE to look up the field value in the table. You can use the relational operator IN to compare the contents of a field with the code strings in a dictionary table or domain table. If there is a match on the code string in the table, DATATRIEVE includes the record in the record stream. Two queries using table-based RSEs are FIND YACHTS WITH RIG IN RIG_TABLE and FIND YACHTS WITH RIG NOT IN RIG_TABLE. See Chapter 12 for a discussion of tables. 7.3.4 Summary of the Relational Operators Table 7-1 summarizes all of the relational operators available to form Boolean expressions in the WITH clause of an RSE. Table 7-1: Conditional Comparisons for an RSE Type of Comparison Relationship of Values in Boolean Pattern recognition Exact match (case sensitive) Relational Operator Boolean Expression = BUILDER = "ALBIN" "ALBIN" = BUILDER EQUAL EQ No match (case sensitive) NE NOT_EQUAL NOTE QUAL BUILDER NE "ALBIN" "ALBIN" NE BUILDER Substring matches (not case sensitive) CaNT CONTAINING BUILDER CaNT "bin" Substring does not match (not case sensitive) NOT CaNT NOT CONTAINING BUILDER NOT CaNT "bin" (continued on next page) Limiting Record Streams with Record Selection Expressions 7-7 Table 7-1: Conditional Comparisons for an RSE (Cont.) Type of Comparison Relationship of Values in Boolean Relational Operator Boolean Expression Value within a range Value is greater than > GT GREATER_THAN PRICE> 50000 50000 > PRICE Value is greater than or = GE GREATER-EQUAL PRICE GE 50000 50000 GE PRICE < PRICE < 20000 20000 < PRICE Value is less than Look up in table Record stream empty 7.3.5 LT LESS_THAN Value is less than or = LE LESS-EQUAL PRICE LE 20000 Value is between the two values or = to one BT BETWEEN PRICE BETWEEN 30000 AND 54000 Field value is in the table IN table-name RIG IN RIG_TABLE Field value is not in the table NOT IN table-name RIG NOT IN RIG_TABLE Record stream is not empty ANYrse FAMILIES WITH ANY KIDS Record stream is empty NOTANYrse FAMILIES WITH NOT ANY KIDS Setting Up Multiple Tests with Compound Booleans Thus far, each Boolean expression imposed just one test for records to be included in the record stream. To set up multiple or complex tests for records, you can join two or more Boolean expressions together. Expressions that join Booleans are Boolean operators. There are four Boolean operators: AND, OR, NOT, and BUT. With AND, OR, and BUT you canjoin two or more Boolean expressions together to form a single Boolean expression. NOT allows you to reverse the value of a Boolean expression. If you link Boolean expressions with AND or BUT, the resulting Boolean expression is true only if all the Booleans linked with AND or BUT are true. If you link Boolean expressions with OR, the resulting Boolean expression is true if any one of the Booleans linked with OR is true. If you precede a Boolean expression with NOT, the resulting Boolean expression is true if the Boolean expression following NOT is false. 7-8 Limiting Record Streams with Record Selection Expressions The following example shows the use of the Boolean operator: DTR> PRINT YACHTS WITH RIG = MS OR LOA = 3800 MANUFACTURER AMERICAN BLOCK I • EASTWARD FJORD LINDSEY PEARSON ROGGER FD MODEL 28-MS 40 HO MS 33 38 38 MIS RIG LENGTH OIJER ALL WEIGHT BEAM MS SLOOP MS MS MS SLOOP MS 28 38 24 33 .38 38 35 5,500 18,500 7,000 14,000 14,500 17,000 17,800 08 12 08 11 12 12 11 PRICE $18,885 $15,800 $35,800 DTR> The query displays data on all yachts that have a RIG that is MS or an LOA equal to 39. For DATATRIEVE to include a record in the record stream, it must find that the record from YACHTS satisfies either condition or both. 7.4 Sorting the Record Stream by Field Values When you use a PRINT statement to display a record stream, the primary key defined for the data file determines the order of the records. However, you can use the SORTED BY clause of the RSE to sort the record stream in a different order. For example, the records in YACHTS are already sorted by BUILDER, the first part of the primary key (TYPE) for the data file. If you are interested in the length of the boats, you can sort the records by LOA. To break down each length yacht by weight, specify DISP, the query name for displacement, as an additional sort key. The following query first sorts the YACHTS records according to LOA and DISP, then limits the record stream to the first five records: DTR> FIND YACHTS SORTED BY LOA, DISP(@j [113 records found] DTR> PRINT FIRST 5 CURRENToo MANUFACTURER MODEL RIG LENGTH OI.JER ALL WEIGHT BEAM WINDPOWER CAPE DORY ENCHILADA SAN JUAN IJENTURE IMPULSE TYPHOON 20 21 21 SLOOP SLOOP SLOOP SLOOP SLOOP 18 18 20 21 21 850 1 ,800 2,300 1 ,250 1 ,500 07 08 07 07 07 PRICE $3,500 $4,285 $2,823 DTR> Limiting Record Streams with Record Selection Expressions 7-9 The SORTED BY clause takes precedence over the original sort order for the record stream. It does not change the file organization of the records. The SORTED BY clause enables you to produce reports with data records organized into groups. Certain fields will control how the organization of these reports takes place. For more information on control group reports, see the DATATRIEVE-ll Guide to Writing Reports. 7-10 Limiting Record Streams with Record Selection Expressions Using Compound Statements 8 When you want to do something in DATATRIEVE that involves definitions in a data dictionary, you usually need to use a DATATRIEVE command. When you want to manipulate data in a dictionary, you usually use DATATRIEVE statements, such as STORE, MODIFY, PRINT, and FIND. You can enter individual statements or combine them into compound statements. You can enter statements at DATATRIEVE command level (the DTR> prompt), in procedures, or in command files. You can also enter individual commands at DATATRIEVE command level, in procedures, or command files. However, you cannot combine DATATRIEVE commands into compound commands, mix commands and statements to form compound statements, or include commands in BEGIN-END blocks. Table 5-1 in the DATATRIEVE-ll Reference Manual tells you whether a DATATRIEVE keyword is used in commands or statements. This chapter describes the use of compound statements, REPEAT and FOR statements, and BEGIN-END blocks. 8.1 Using REPEAT to Combine Statements Often you want to use the same DATATRIEVE statement over and over. For instance, if you are storing five new boats into the domain YACHTS, you could ready the domain for WRITE access and then repeat the instruction STORE YACHTS five times. 8-1 By using a compound statement, however, you can combine the STORE statement with a REPEAT statement and then type the STORE statement only once for the five records. The following example shows a frequent use of a compound statement - combining STORE with REPEAT: DTR> READY YACHTS WRITEm DTR> REPEAT 3 STORE YACHTSm Enter MANUFACTURER: HOBIEm Enter MODEL: CATm Enter RIG: SLOOpm En t e r LENGTH OIJER ALL: 22m Enter DISPLACEMENT: llOOOm Enter BEAM: 8m Enter PRICE: 6500m Enter MANUFACTURER: RIDGEm Enter MODEL: ACTm Enter RIG: SLOOpm En t e r LENGTH OI.JER ALL: 22m Enter DISPLACEMENT: 3500m Enter BEAM:@ID m Enter PRICE:(ffiID m Enter MANUFACTURER: ROBERTSm Enter MODEL: Zllm Enter RIG: SLOOpm En t e r LENGTH OIJER ALL: 25m Enter DISPLACEMENT: ll500m En t e r BEAM: 10m Enter PRICE: 7500m DTR> Prompts are repeated for each field in the record until data is stored in the specified number of records or until you end the operation by entering CTRL/Z. When you use a REPEAT statement with MODIFY, PRINT, and REPORT statements, you may also want to use a prompting value expression (*.prompt). You probably do not want to PRINT, MODIFY, or REPORT on a single record more than once. However, you can use a prompting value expression to supply new information each time a statement is repeated. The following example uses the prompting value expression with a REPEAT loop: DTR> SET NO PROMPTm DTR> READY YACHTSm DTR) REPEAT *.IINUMBER OF TIMES TO REPORTllm CON> BEGINm CON> REPORT FIRST 1 YACHTS WITH LOA = *.IITHE LOAllm RW> PRINT BOATm RW> END REPORTm CON> ENDm Enter NUMBER OF TIMES TO REPORT: 2m Enter THE LOA: 37m (continued on next page) 8-2 Using Compound Statements 23-0ct-S7 Page 1 MODEL RIG LENGTH OIJER ALL 37 MK I I KETCH 37 MANUFACTURER ALBERG WEIGHT BEAM PRICE 20tOOO 12 $36t851 Enter THE LOA: 36ru 23-0ct-S7 Page 1 MANUFACTURER CABOT MODEL 36 RIG LENGTH OIJER ALL WEIGHT BEAM SLOOP 36 15tOOO 12 PRICE DTR> A compound statement can include any DATATRIEVE statement except FIND, SELECT, DROP, RELEASE, or SORT. Note that if you follow the REPEAT statement with a procedure, DATATRIEVE repeats only the first statement in the procedure. To repeat the complete procedure, you must use a BEGIN-END block, described in a later section in this chapter. Note also that a procedure in a REPEAT statement cannot include DATATRIEVE commands. 8.2 Using the FOR Statement You can use a FOR statement when you want to access individual fields more than once. Suppose you want to supply a price for yachts with no price listed. You do not want to change all the fields in the target records. You want to change only the price field for specific yachts. First, form a collection of the boats you want to modify. Then, use a FOR statement to modify the target records: DTR> SET NO PROMPTru DTR> READY YACHTS MODIFYru DTR> FIND FIRST 3 YACHTS WITH PRICE [3 records found] DTR> PRINT ALLru MANUFACTURER BLOCK I • BUCCANEER BUCCANEER MODEL 40 270 320 Oru RIG LENGTH OIJER ALL WEIGHT BEAM SLOOP SLOOP SLOOP 38 27 32 lSt500 5tOOO 12t500 PRICE 12 OS 10 DTR> FOR CURRENTru CON> MODIFY USING PRICE = DISP * 1 .3 + 5000ru DTR> PRINT CURRENTru (continued on next page) Using Compound Statements 8-3 MANUFACTURER BLOCK I • BUCCANEER BUCCANEER MODEL ao 270 320 RIG LENGTH OI.IER ALL WEIGHT BEAM PRICE SLOOP SLOOP SLOOP 38 27 32 $28t050 $11t500 $21 t250 18t500 5tOOO 12t500 12 08 10 DTR> 8.3 Using BEGIN-END Blocks to Combine Statements Another way to combine statements is the BEGIN-END block, which causes DATATRIEVE to treat several statements as one statement. BEGIN-END blocks are especially useful within FOR, STORE, and REPEAT statements. 8.3.1 BEGIN-END Blocks in FOR Statements You can, for instance, use a BEGIN-END block in a FOR statement to modify the price field in specific records. The BEGIN-END block lets you include two PRINT statements within the MODIFY statement - the first to display the unchanged records, the second to show the records after DATATRIEVE has modified them: DTR> DTR> DTR> CON> CON> CON> CON> CON> CON> SET NO PROMPT([IT) READY YACHTS WRITE([IT) FOR YACHTS WITH PRICE O([IT) MODIFY USING([IT) BEGIN@) PRINT([IT) PRICE = *."NEW PRICE"([IT) PRINT([IT) END([IT) MANUFACTURER MODEL RIG BLOCK I. ao SLOOP Enter NEW PRICE: 28050([IT) MANUFACTURER MODEL RIG LENGTH OI.IER ALL WEIGHT BEAM 38 Using Compound Statements 12 LENGTH OI.IER ALL WEIGHT BEAM BLOCK I. ao SLOOP 38 BUCCANEER 270 SLOOP 27 Enter NEW PRICE: az Execution terMinated by operator DTR> 8-4 18t500 18t500 5,000 PRICE 12 08 PRICE $28t050 8.3.2 IF-THEN-ELSE Statements in BEGIN-END Blocks You can include an IF-THEN-ELSE statement with a prompting expression within the block to allow you to decide whether or not to modify each record stream: DTR> SET NO PROMPTffiITj DTR> FOR FIRST 3 YACHTS WITH PRICE = OffiITj CON> BEGINffiITj CON> IF *."'1' TO MODIFY PRICE, N TO SKIP" CONT "Y"ffiITj CON> THEN MODIFY PRICE ELSEffiITj CON> PRINT "NO CHANGE"ffiITj CON> ENDffiITj Enter Y TO MODIFY PRICE, N TO SKIP: Y ffiITj Enter PRICE: 23a58 ffiITj Enter Y TO MODIFY PRICE, N TO SKIP: N ffiITj NO CHANGE Enter Y TO MODIFY PRICE, N TO SKIP: N ffiITj NO CHANGE DTR.> Conversely, if there are several DATATRIEVE statements required in the THEN and ELSE clauses, include them in BEGIN-END blocks. 8.3.3 Using BEGIN-END Blocks in STORE Statements Often you may want to include a number of lines in the BEGIN-END block. The following example shows how to use: • A BEGIN-END block within the STORE statement • A prompting value expression to request user response • A BEGIN-END block in a VERIFY clause • A VERIFY clause with a USING clause to allow you to decide whether or not to store the record displayed in the PRINT statement • A context variable (A) to establish DATATRIEVE context See Appendix A for more information on DATATRIEVE context. DTR> READY YACHTS WRITEffiITj DTR> STORE A IN YACHTS USINGffiITj CON> BEGINffiITj CON> BUILDER = *.BUILDERffiITj CON> MODEL = *.MODELffiITj CON> RIG = *.RIGffiITj CON> LOA = *.LENGTHffiITj CON> DISP = *. \.>JEI GHTffiITj CON> BEAM = *.BEAMffiITj CON> PRICE = DISP * 1.3 + BEAM * 100ffiITj CON> END t.IER I FY US I NGffiITj CON> BEGINffiITj CON> PRINT A.BOAT, SKIPffiITj CON> IF *.CONFIRMATION CONT "N" THENffiITj CON> ABORT "BAD RECORD"ffiITj CON>, ENDffiITj DTR> Using Compound Statements 8-5 When you press RETURN to enter the compound statement, DATATRIEVE prompts for each of the fields in the YACHT record, then requests a confirmation: Enter BUILDER: CRIS-CRAFT(@) Enter MDDEL: (ffiID (@) Enter RIG: KETCH(@) Enter LENGTH: 32(@) Enter WEIGHT: 8t725(@) En t e r BEAM: 10(@) MANUFACTURER MDDEL CRIS-CRAFT RIG LENGTH DI.JER ALL WEIGHT BEAM KETCH 32 Enter CONFIRMATION: N(@) ABORT: BAD RECORD DTR> FIND YACHTS WITH BUILDER [0 records found] 8.3.4 8t725 10 PRICE MANUFACTURER $12t3a3 CRIS-CRAFT CRIS-CRAFT(@) BEGIN-END Blocks in REPEAT Statements If you want to repeat a sequence of statements, use a BEGIN-END block inside a REPEAT" statement. Suppose you wanted to store 50 new yachts using the MANUFACTURER, LOA, DISPLACEMENT, and PRICE fields. You could use the following BEGIN-END block to repeat the sequence of prompting statements: DTR> SET NO PROMPT(@) DTR> READY YACHTS WRITE(@) DTR> REPEAT 50 STORE YACHTS USING(@) CON> BEGINffiIT) CON> MANUFACTURER *.MANUFACTURER(@) CON> LOA *.LOA(@) CON> DISPLACEMENT *.DISPLACEMENT(@) CON> PRICE *.PRICE(@) CON> END(@) Enter MANUFACTURER: GRAMPIAN(@) Enter LOA: aO(@) Enter DISPLACEMENT: laOO(@) Enter PRICE: 23a56(@) Enter MANUFACTURER: HIGGINS(@) Enter LOA: 37(@) En t e r DISPLACEMENT: 1375(@) Enter PRICE: la765(@) DTR> For information on invoking a procedure in a REPEAT statement, see Chapter 9. Because statements that use BEGIN-END blocks can be quite long, it is often useful to put them into DATATRIEVE procedures so that you can edit and reuse them without having to retype them. The next chapter explains how to use procedures. 8-6 Using Compound Statements Using DATATRIEVE Procedures 9 Often you want to execute the same series of commands and statements over and over again, and you may want to have other users execute those same commands and statements. Unless you use procedures, you have to retype the input each time. By using procedures, however, you can develop the series of steps once and then simply invoke the procedure each time you want to do the same steps over again. A procedure is a fixed sequence ofDATATRIEVE commands and statements you create, name, and store in your data dictionary. A procedure can also contain portions of a command or statement, such as a complex value expression. 9.1 Defining a Procedure For almost any series of statements you use over and over again, you can save yourself time by defining a single procedure. For example, you repeatedly perform a simple query to display information about the manufacturers of large yachts: DTR) READY YACHTSlliD) DTR) FIND BIGGIES IN YACHTS WITH LOA GT ao SORTED BY BUILDERlliD) [8 records found] DTR) PRINT ALLlliD) (continued on next page) 9-1 MANUFACTURER CHALLENGER COLUMBIA GULFSTAR ISLANDER NAUTOR NEWPORT OLYMPIC PEARSON MODEL Lll Lll Lll FREEPORT SWAN Lll Lll S ADI.IENTURE LllB RIG LENGTH OI)ER WEIGHT BEAM ALL KETCH SLOOP KETCH KETCH SLOOP SLOOP KETCH KETCH Lll Lll Lll Lll Lll Lll Ll2 Ll2 26,700 20,700 22,000 22,000 17,750 18,000 2L1,250 21 ,000 13 11 12 13 12 11 13 13 PRICE $51 ,228 $Ll8,LlBO $LI 1 ,350 $5L1,B70 $80,500 DTR> Rather than type this query repeatedly, you can put it into a procedure. To define a procedure, enter the DEFINE PROCEDURE command at DATATRIEVE command level. After typing the keywords DEFINE PROCEDURE, enter a name for the procedure and press RETURN. DTR> DEFINE PROCEDURE BUILDERSillITl DATATRIEVE then prompts with DFN> to indicate that it expects a procedure definition. Enter the commands or statements that form the procedure definition. DATATRIEVE continues to prompt with DFN> until you enter the keyword END_PROCEDURE on a line by itself. DTR> DEFINE PROCEDURE BUILDERSillITl DFN> DFN> DFN> DFN> END_PROCEDUREillITl DTR> As soon as you enter END_PROCEDURE, DATATRIEVE stores the procedure definition in your current dictionary. It checks the syntax of the DEFINE PROCEDURE statement, not that of the statements the procedure contains. DATATRIEVE checks for syntax errors in those statements only when you invoke the procedure. 9.2 Invoking a Procedure· You invoke a procedure by preceding its name with a colon: :procedure-name The content of a procedure determines where you can invoke it. In general, you can invoke a procedure anywhere you can use the commands or statements contained in the procedure. For example, if the procedure contains only complete DATATRIEVE commands and statements, you can invoke it at the DATATRIEVE command level. DTR> :BUILDERSillITl Note that you cannot invoke a procedure during an ADT, EDIT, or GUIDE mode session or in a domain, record, or table definition. 9-2 Using DATATRIEVE Procedures In addition, when DATATRIEVE executes a procedure, you do not see the commands and statements in the procedure or the system messages that are normally displayed. You see only the output that follows the last statement or command in the procedure. In the following example, the only output is in response to FIND YACHTS SORTED BY DESC PRICE, the last statement in the procedure EXPENSIVE: DTR> SHOW E}< PENS !l.JE~ PROCEDURE EXPENSIVE READY YACHTS FIND YACHTS SORTED BY DESC PRICE END_PROCEDURE DTR> : E}< PENS !l.JE~ [113 records found] DTR> If you follow the FIND statement with another statement, you no longer receive the message about the number of records found: DTR> SHOW E}< PENS I l,JE~ PROCEDURE EXPENSIVE READY YACHTS FIND YACHTS SORTED BY DESC PRICE PRINT FIRST 5 CURRENT END_PROCEDURE DTR> : E}< PENS I l,JE~ MANUFACTURER MODEL RIG OLYMPIC ISLANDER CHALLENGER NORTHERN COLUMBIA ADVENTURE FREEPORT KETCH KETCH KETCH KETCH SLOOP al 37 al LENGTH OVER ALL WEIGHT BEAM a2 al al 37 al 2a,250 22,000 28,700 la,OOO 20,700 13 13 13 11 11 PRICE $80,500 $5a,870 $51 ,228 $50,000 $a8,a80 DTR> 9.3 Contents of a Procedure A procedure can contain any number of the following DATATRIEVE elements: • Full DATATRIEVE commands and statements • Command and statement clauses and arguments • Comments Using DATATRIEVE Procedures 9-3 9.3.1 Commands and Statements in Procedures You might define a procedure containing complete DATATRIEVE commands and statements. This one, for instance, finds and displays the biggest yachts in the domain: DTR> DEFINE PROCEDURE BIG_YACHTS(5ill DFN> FIND BIGGIES IN YACHTS WITH LOA GT ao SORTED BY BUILDER(5ill DFN> PRINT ALL(5ill DFN> END_PROCEDURE(5ill DTR> When you execute the procedure BIG_YACHTS, the results are the same as entering the FIND and PRINT statements at the DATATRIEVE command level, indicated by the DTR> prompt: DTR> READY YACHTS(5ill DTR> :BIG_YACHTS(5ill MANUFACTURER CHALLENGER COLUMBIA GULFSTAR ISLANDER NAUTOR NEWPORT OLYMPIC PEARSON MODEL al al al FREEPORT SWAN al al S ADVENTURE a18 RIG LENGTH OI.IER ALL WEIGHT BEAM KETCH SLOOP KETCH KETCH SLOOP SLOOP KETCH KETCH al al al al al al a2 a2 28,700 20,700 22,000 22,000 17,750 lS,OOO 2a,250 21,000 13 11 12 13 12 11 13 13 PRICE $51,22S $aS,a80 $al,350 $5a,870 $SO,500 DTR> 9.3.2 Arguments and Clauses Besides full commands and statements, a procedure can contain fragments of statements or commands. It can contain an argument or clause from a command or statement. For example, a procedure can contain a record selection expression: DTR> DEFINE PROCEDURE BIG_YACHTS_RSE(5ill DFN> BIGGIES IN YACHTS WITH LOA GT ao SORTED BY BUILDER(5ill DFN> END_PROCEDURE(5ill DTR> Having separated the record selection expression from the FIND statement, you can use the procedure name as the argument of a FIND statement: DTR> FIND :BIG_YACHTS_RSEru [S records found] DTR> 9-4 Using DATATRIEVE Procedures In fact, you can use this procedure in any command or statement containing an RSE argument, such as the PRINT statement: DTR> PRINT ALL :BIG_YACHTS_RSE(BTI) MANUFACTURER MODEL RIG LENGTH DI.IER ALL WEIGHT BEAM CHALLENGER COLUMBIA GULFSTAR ISLANDER NAUToR NEWPORT OLYMPIC PEARSON al al al FREEPORT SWAN al al S ADI.IENTURE a19 KETCH SLOOP KETCH KETCH SLOOP SLOOP KETCH KETCH al al al al al al a2 a2 2Gt700 20t700 22tOOO 22tOOO 17t750 lStOOO 2at250 21 tOOO 13 11 12 13 12 11 13 13 PRICE $51 t22S $aSta90 $alt350 $5at970 $SOt500 You can begin a procedure with the end fragment of a command or statement and include other whole commands or statements. You can also end a procedure with the beginning fragment of a command or statement after a series of complete commands and statements. 9.3.3 Comments in Procedures A comment contains explanatory information for you or other users that DATATRIEVE does not interpret as input. To put a comment in a procedure, put an exclamation point (I) before the information that you want to include. When you invoke a procedure, DATATRIEVE processes it without displaying the contents of the procedure. To display the comments, use the SHOW command with the procedure name. You could, for instance, put a comment into the procedure BIG_YACHTS_QUERY. The results of the procedure are the same as without the comment. But when you use a SHOW command, you can see the explanatory comment: DTR> SHOW BIG_YACHTS_QUERY SET ABORT DECLARE LENGTH PIC 99 VALID IF LENGTH GT 35. !THIS PROCEDURE SHOWS YACHTS GE SPECIFIED LENGTH LENGTH = *.IIMIN LoA II IF LENGTH GT a2 THEN ABORT liND BOATS THAT BIG II FIND BIGGIES IN YACHTS WITH LOA GE LENGTH SORTED BY BUILDER PRINT BUILDERt RIGt LoAt PRICE OF BIGGIES END_PROCEDURE DTR> Using DATATRIEVE Procedures 9-5 9.4 Using Procedures to Locate Errors When you invoke a procedure, DATATRIEVE processes the contents of the procedure. Ifit finds an error, it issues a message. Suppose, for instance, you created the following long procedure: DTR) DFN) DFN) DFN) DFN) DFN) DFN) DFN) DFN) DFN) DFN) DFN) DFN) DFN) DEFINE PROCEDURE WAGE_REPORT REPORT WAGES SET REPORT_NAME = WEEKLY WAGE REPORT SET COLUMNS_PAGE = 70 PRINT LAST_NAMEt GROSS_PAYt FICAt FEDERAL_TAXt STATE_TAXt GROSS_PAY - (FICA + FEDERAL_TA~< + STATE_TA~O*("NET PAY JI ) USING $$t$$$.99 AT BOTTOM OF REPORT PRINT SKIP 2t COL 1 t IITOTAL: II t TOTAL GROSS_PAY USING $$$t$$$.99t TOTAL FICA USING $$$t$$$.99t TOTAL FEDERAL_TAX USING $$$t$$$.99t TOTAL STATE_TAX USING $$$t$$$.99t TOTAL (GROSS_PAY - (FICA + FEDERAL_TAX + STATE_TAX» USING $$$t$$$.99 DFN) END_REPORT DFN) END_PROCEDURE DTR) If you have made any errors, DATATRIEVE stops executing when it finds the first error and sends you an error message, as in this example: DTR) :WAGE_REPORTm Invalid coluMn header or report naMe (WEEKLY) DTR) EDIT WAGE_REPORTm Edit the procedure to place quotation marks around "WEEKLY WAGE REPORT". Then try the procedure again: DTR) :WAGE_REPORTm Field IIWAGES" is undefined or used out of context DTR) EDIT WAGE_REPORTm To correct this second error, edit the procedure to place the READY WAGES com- . mand before the REPORT statement. Then invoke the procedure again: DTR> :WAGE_REPORTm Enter COLUMNS PER PAGE: 80m (continued on next page) 9-6 Using DATATRIEVE Procedures WEEKLY WAGE REPORT 23-0ct-87 Pa!1e LAST NAME BLAKE DUNN HILL CHONTZ MOONY STARK TOTAL: FEDERAL 1 GROSS PAY FICA TM~ $1 tOOO. 00 $1 t500.00 $500.00 $999.99 $1 t900.98 $9t500.00 $103.86 $145.87 $52.93 $103.85 $145.87 $145.87 $204.77 $297.98 $79.75 $204.76 $375.98 $999.84 $.01 $54.32 $32.98 $57.90 $75.90 $106.90 $691.36 $lt001.83 $334.34 $633.48 $1 t303.23 $15t400.97 $698.25 $2t163.08 $328.01 $12t211.63 STATE TA}< NET PAY $8t247.39 DTR> 9.5 A Sample Procedure You can create your own procedures now using the example in Figure 9-1 as a model. The following is a procedure that uses the Report Writer to write a summary report of yacht data: DTR> DFN> DFN> DFN> DFN> DFN> DFN> DFN> DFN> DFN> DFN> DFN> DFN> DFN> DFN> DFN> DFN> DTR> DEFINE PROCEDURE YACHT_SUMMARym SET ABORTm PRINT "THIS REPORT REQUIRES AN ESTABLISHED COLLECTIONt"m PRINT "SORTED BY LOA AND BEAM."oo PRINT "HAI,IE YOU ESTABLISHED A COLLECTION?"oo IF *."YES OR NO" CONTAINING "N" THEN ABORT "COLLECTION NEEDED."oo REPORT ON *. "OUTPUT DEI,IICE OR FILE"m SET REPORT _NAME=" E}<AMPLE: REPORT FROM A PROCEDURE "001 SET LINES_PAGE=55t COLUMNS_PAGE=60oo PRINT BUILDERt MODELt LOAt BEAMt PRICEoo AT BOTTOM OF LOA PR I NT SK I P t COL 30 "AI)ERAGE PR I CE =" tOO AI,IERAGE (PR I CE) t SK I Poo AT BOTTOM OF REPORT PRINT COL 17t"NUMBER OF BOATS = "tOO COL 35 t COUNT t SKIP t "AI,IERAGE PRICE OF ALL BOATS =" tOO AI,IERAGE (PR I CE) 001 END_REPORToo END_PROCEDUREm Figure 9-1: Sample Procedure This example illustrates some statements that are particularly useful in procedures: • Use the PRINT statement to display a message when the procedure is invoked . • The prompting value expression *."YES OR NO" requires a response to the question: HAVE YOU ESTABLISHED A COLLECTION? The Boolean expression CONTAINING checks the user's response to the question. If the response is N or NO, the procedure aborts. Using DATATRIEVE Procedures 9-7 DTR> :YACHT_SUMMARYffiill THIS REPORT REQUIRES AN ESTABLISHED COLLECTION, SORTED BY LOA AND BEAM. HAVE YOU ESTABLISHED A COLLECTION? Enter YES OR NO: NOffiill ABORT: COLLECTION NEEDED DTR> • If you answer YES to the first prompt, but you do not actually have a current collection, the Report Writer aborts the procedure and prints an error message: DTR> :YACHT_SUMMARYffiill THIS REPORT REQUIRES AN ESTABLISHED COLLECTION, SORTED BY LOA AND BEAM. HAVE YOU ESTABLISHED A COLLECTION? Enter YES OR NO: YESffiill A current collection has not been established. DTR> • The prompting value expression *. "OUTPUT DEVICE OR FILE" allows you to select the device or file to contain the report when DATATRIEVE executes the procedure. • If you make a collection of YACHTS with LOA between (and including) 36 and 37 and price not equal to zero, DATATRIEVE displays the following report on your terminal: DTR> READY YACHTSffiill DTR> FIND YACHTS WITH LOA BETWEEN 36 37 AND PRICE NE Offiill [5 records found] DTR> SORT CURRENT BY LOA, BEAMffiill DTR> :YACHT_SUMMARYffiill THIS REPORT REQUIRES AN ESTABLISHED COLLECTION, SORTED BY LOA AND BEAM. HAVE YOU ESTABLISHED A COLLECTION? Enter YES OR NO: YESffiill Ente r OUTPUT DEtJICE OR FILE: TI:ffiill EXAMPLE: REPORT FROM A PROCEDURE MANUFACTURER ISLANDER I • TRADER MODEL 36 37 01-Apr-1987 Pa!1e 1 LENGTH Ot.JER ALL BEAM PRICE 36 36 11 12 $31 ,730 $39,500 AVERAGE PRICE IRWIN NORTHERN ALBERG $35,615 37 MARK I I 37 37 MK I I 37 37 37 11 11 12 $36,950 $50,000 $36,951 (continued on next page) 9-8 Using DATATRIEVE Procedures $a 1 ,300 AVERAGE PRICE NUMBER OF BOATS = 5 AVERAGE PRICE OF ALL BOATS 9.6 $38,028 Nesting Procedures A nested procedure is a procedure within another procedure. The following procedure calculates the price per pound of a boat and assigns a column header and edit string for that value expression: DTR> DEFINE PROCEDURE PRICE_PER_POUND@] DFN> PRICE/DISPLACEMENT ("PRICE"/"PER"/"POUND") USING $$8.88@] DFN> END_PROCEDURE@] DTR> You cannot invoke this procedure by itself, but you can invoke the PRICE_PER-POUND procedure in another procedure that prints the builder, model, and price per pound of all boats in the CURRENT collection, as follows: DTR> DEFINE PROCEDURE PRICE_REPORT®] DFN> PR I NT ALL BU I LDER, MODEL, : PR I CE_PER_ POUNDru DFN> END_PROCEDURE@] DTR> When you invoke the procedure PRICE-REPORT, DATATRIEVE displays three fields for each YACHTS record. First the builder and model are displayed as a result of the procedure's PRINT statement. Then the PRICE-PER-POUND procedure is called to compute and format the price/displacement before it is displayed. The following example uses the BIG_YACHTS procedure to establish the CURRENT collection and PRICE-REPORT to print a short report: DTR> :BIG_YACHTS; :PRICE_REPORTru MANUFACTURER MODEL RIG LENGTH OI.JER ALL WEIGHT BEAM CHALLENGER COLUMBIA GULFSTAR ISLANDER NAUTOR NEWPORT OLYMPIC PEARSON al al al FREEPORT SWAN al al S ADVENTURE a18 KETCH SLOOP KETCH KETCH SLOOP SLOOP KETCH KETCH al al al al al al a2 a2 28,700 20,700 22,000 22,000 17,750 18,000 2a,250 21 ,000 13 11 12 13 12 11 13 13 PRICE $51 ,228 $a8,a80 $a 1 ,350 $5a,870 $80,500 (continued on next page) Using DATATRIEVE Procedures 9-9 MANUFACTURER MODEL PRICE PER POUND CHALLENGER COLUMBIA GULFSTAR ISLANDER NAUTOR NEWPORT OLYMPIC PEARSON al al al FREEPORT SWAN al al S ADI.IENTURE a19 $1.92 $2.3a $1. 88 $2.50 $0.00 $0.00 $3.32 $0.00 DTR> E~n T(@) When nesting procedures, do not let a procedure invoke itself. You can create an infinite loop. (Should you create such a loop, press CTRL/C two times to stop your process.) 9.7 Using a Procedure in a Compound Statement To execute a procedure a number of times, you can invoke it in a REPEAT or FOR statement. You should be careful when invoking a procedure in these statements, however. For example, the following procedure appears to be correct but produces unexpected results: DTR;:' SHOW E~< 1(@) PROCEDURE E~< 1 FOR YACHTS WITH PRICE = 0 AND LOA BT 16 AND 23 PRINT BUILDERt MODELt LOA PRINT IIPrinting Test Record END_PROCEDURE ll DTR> REPEAT 3 :EXl MANUFACTURER MODEL ENCHILADA 20 23/ SPECIA ERICSON SAN JUAN 21 ENCHILADA 20 23/ SPECIA ERICSON SAN JUAN 21 ENCHILADA 20 23/ SPECIA ERICSON SAN JUAN 21 Printing Test Record LENGTH OI.IER ALL 20 23 21 20 23 21 20 23 21 Only the FOR statement in the EXl procedure is repeated. The PRINT statement is executed only once at the very end. When DATATRIEVE encounters the first complete statement in a procedure, it assumes that the REPEAT statement is also complete. Therefore, it repeats only the first statement in the procedure and executes each of the remaining statements once. 9-10 Using DATATRIEVE Procedures To repeat the entire procedure, enclose the procedure call or the procedure definition in a BEGIN-END block. For example, the following sequence of statements puts a procedure in a BEGIN-END block and repeats the procedure three times: DTR> REPEAT 3 BEGIN(BQ) [LooKing for stateMent] CON> : E}<1(BQ) CON> END(BQ) MANUFACTURER MODEL ENCHILADA 20 ERICSON 23/ SPECIA SAN JUAN 21 Printing Test Record ENCHILADA 20 ERICSON 23/ SPECIA SAN JUAN 21 Printing Test Record ENCHILADA 20 ERICSON 23/ SPECIA SAN JUAN 21 Printing Test Record LENGTH OI.IER ALL 20 23 21 20 23 21 20 23 21 The following example uses a FOR statement, includes a BEGIN-END block in the procedure, and invokes the procedure in a REPEAT statement: DTR> SHOW E}-(3(BQ) PROCEDURE E}{3 FOR YACHTS WITH PRICE = 0 AND LOA BT 16 AND 23 BEGIN PRINT BUILDER, MODEL, LOA PRINT IIPrint Test Record END END_PROCEDURE ll DTR> REPEAT 3 : EX3(BQ) MANUFACTURER ENCHILADA Print Test ERICSON Print Test SAN JUAN Print Test ENCHILADA Print Test ERICSON P r i n t Test SAN JUAN Print Test ENCHILADA Print Test MODEL 20 Record 23/ SPECIA Record 21 Record 20 Record 23/ SPECIA Record 21 Record 20 Record LENGTH OI.IER ALL 20 23 21 20 23 21 20 (continued on next page) Using DATATRIEVE Procedures 9-11 23/ SPECIA ERICSON 23 Print Test Record SAN JUAN 21 21 Print Test Record DTR> If you invoke a procedure in a FOR statement, you must use the same technique. Enclose the call or the procedure definition in a BEGIN-END block as in the following example: DTR> SHOW PRICE_REPORT2@] PROCEDURE PRICE_REPORT2 PRINT BUILDER, MODEL, :PRICE_PER_POUND END_PROCEDURE DTR> DTR> FOR YACHTS WITH PRICE GT 20000 AND LOA LT 29@] [LooKin~ for stateMent] CON> BEGIN@] [LooKin~ for stateMent] CON> :PRICE_REPORT2@] [LooKin~ for statelTlent or IIENDII] CON> END@] MANUFACTURER MODEL PRICE PER POUND CAPE DORY SABRE 28 28 $2.97 $2.aa DTR> Remember that if you use a procedure in a loop, do not include a FIND, SELECT, DROP, or RELEASE statement. These statements cannot appear in BEGINEND blocks. 9.8 Aborting Procedures You can abort a procedure by including a SET ABORT statement in the procedure definition. If the abort conditions arise and SET ABORT is in effect, DATATRIEVE aborts the procedure and prints a message on your terminal. If SET NO ABORT is in effect, DATATRIEVE aborts the command or statement that contains the ABORT but continues to execute the other commands and statements in the procedure. 9-12 Using DATATRIEVE Procedures The default setting in DATATRIEVE is SET ABORT. You can ensure that SET ABORT is in effect by including that statement in the procedure definition: DTR) DFN) DFN) DFN) DFN) DFN) DFN) DFN) DFN) DF N) DFN) DTR) DEFINE PROCEDURE BIG_YACHTS_QUERY®) SET ABORT®) DECLARE LENGTH PIC 88®) 1.IALID IF LENGTH GT 35.®) LENGTH = *."MIN LoA"®) IF LENGTH GT 42®] THEN ABORT liND BOATS THAT BIG"ffiill FIND BIGGIES IN YACHTS WITH LOA GE LENGTH®] SORTED BY BUILDERffiill PRI NT BUI L0 ER, RIG., LOA, PRIC E 0 FBI GGI ES®] END_PROCEDURE®] If you invoke BIG_YACHTS_QUERY and supply a length of 35 or smaller, DATATRIEVE reprompts you for a valid length. If you supply a length greater than 42, the procedure aborts, prints the specified abort message, and returns you to DATATRIEVE command level: DTR) :BIG_YACHTS_QUERY®] Enter MIN LOA: 35®] Validation error for LENGTH Re-enter MIN LOA: 43®] ABORT: NO BOATS THAT BIG ExeclItion terlrlinated b}' IABoRT" statelrlent DTR) If you assign a value between 36 and 42 to length, DATATRIEVE prints the appropriate collection: DTR) :BIG_YACHTS_QUERYffiill Enter MIN LOA: 38®] MANUFACTURER RIG LENGTH ol.IER ALL BLOCK I • CHALLENGER COLUMBIA GULFSTAR ISLANDER LINDSEY NAUToR NEWPORT OLYMPIC PEARSON PEARSON SLOOP KETCH SLOOP KETCH KETCH MS SLOOP SLOOP KETCH SLOOP KETCH 38 41 41 41 41 38 41 41 42 38 42 PRICE $51,228 $48,480 $41 ,350 $54,870 $35,800 $80,500 9.9 Maintaining Procedures You can maintain the procedures stored in your default dictionary directory with the SHOW, EDIT, and DELETE commands. Using DATATRIEVE Procedures 9-13 9.9.1 Displaying Procedure Names You can list the names of all procedures in your default directory with the SHOW command: DTR} SHOW PROCEDURES(@) Procedures: BIG MS_SEARCH BIG_YACHTS_QUERY PHONE_REP TEST CHEAP YACHT_SUMMARY DTR> 9.9.2 Displaying Complete Procedures If you want to display a procedure on your terminal, you can use the SHOW command and specify the name of the procedure to be displayed: DTR} SHOW MS_SEARCH(@) PROCEDURE MS_SEARCH READY YACHTS FIND YACHTS WITH RIG = "MS" FOR CURRENT PRINT BUILDER, (BU I LDER I..JI A COM PANY _ TABLE) (" ADDRESS END_PROCEDURE II ) DTR} 9.10 Editing Procedures You can correct an error with the DATATRIEVE Editor. Invoke the Editor with the following command at the DTR> prompt: EDIT procedure-name When you find the error, use the DATATRIEVE Editor to correct it or follow this sequence: 1. EXTRACT the procedure from DATATRIEVE to a command file on your system using the following statement: EXTRACT ON file-spec procedure-name Use the file extension .CMD in the file specification to distinguish the extracted file as a command file. 2. Exit from DATATRIEVE. 3. Use the text editor you normally use on your system to revise the command file containing the procedure. 4. Return to DATATRIEVE. 5. ·Invoke the command file by typing the at sign (@) and the name of the file to bring the corrected procedure into DATATRIEVE. 9-14 Using DATATRIEVE Procedures See the following chapter for information on DATATRIEVE command files and Chapter 16 in this manual for information on DATATRIEVE Editor commands. 9.10.1 Deleting Procedures You can delete a procedure from your dictionary with the DELETE command: DTR> SHOW PROCEDURES@m Procedures: BIG MS_SEARCH BIG_YACHTS_QUERY PHONE_REP CHEAP YACHT_SUMMARY DTR> DELETE BIG HBTIl DTR> SHOW PROCEDURES@m Procedures: BIG_YACHTS_QUERY PHONE_REP CHEAP YACHT_SUMMARY MS_SEARCH DTR> Note that the DELETE command must end with a semicolon C;). You should maintain a backup copy of your procedure, especially ifit is a long one. Use the DATATRIEVE EXTRACT command to copy your procedure to a command file for backup. Once you have a backup copy, you can always recover the procedure if you happen to delete it accidentally. The following example illustrates how you can create a backup file, delete a procedure, and replace it without ever leaving DATATRIEVE: DTR> SET COLUMNS_PAGE = BO@m DTR> SHOW PROCEDURES@m Procedures: BIG_YACHTS BIG_YACHTS_QUERY BREAK_REP CTRL EXPENSIVE FAM_REC INFLATION_REPORT MULTIPLE_PRINT MULTIPLE_STORE NEW_YACHTS P PAGE_HEADER PICKBOATS R SALARY_REPORT SALARY_REPORTl SALARY_TOTALS SUM TAB_TEST TITLE_PAGE V WAGE_REPORT XP YACHTS_REPORT YACHT_PER_LB DTR>- E}<TRACT ON SAI,)B 1GB I G_ YACHTS_QUERY@m DTR> DELETE BIG_YACHTS_QUERY;@m DTR>- SHOW PROCEDURES@m BP F JOB_HISTORY NME PRICE_INCREASE SALARY_REPORT2 TEST_WAGE WP YACHT_PRICE Procedures: BIG_YACHTS E}<PENS I liE JOB_HISTORY NME PRICE_INCREASE SALARY_REPORT2 TEST_WAGE WP YACHT_PRICE BP F MULTIPLE_PRINT P R SALARY_TOTALS TITLE_PAGE XP BREAK_REP FAM_REC MULTIPLE_STORE PAGE_HEADER SALARY_REPORT SUM I,) YACHTS_REPORT CTRL INFLATION_REPORT NEW_YACHTS PICKBOATS SALARY_REPORTl TAB_TEST WAGE_REPORT YACHT_PER_LB (continued on next page) Using DATATRIEVE Procedures 9-15 DTR> @SAI.JB I G DELETE BIG_YACHTS_OUERY; IIBIG_YACHTS_OUERY II has not been defined in the dictionary DEFINE PRDCEDURE BIG_YACHTS_OUERY SET ABORT DECLARE LENGTH PIC 88 VALID IF LENGTH GT 35. LENGTH = *.IIMIN LOA II I F LENGTH. GT 42 THEN ABORT liND BOATS THAT BIG II FIND BIGGIES IN YACHTS WITH LOA GE LENGTH SORTED BY BUILDER PRINT BUILDER, RIG, LOA, PRICE OF BIGGIES END_PROCEDURE DTR> SHOW PROCEDURES@0 Procedures: BIG_YACHTS BIG_YACHTS_OUERY BP BREAK_REP CTRL EX PENS I IJE F FAM_REC INFLATION_REPORT JOB_HISTORY MULTIPLE_PRINT MULTIPLE_STORE NEW_YACHTS NME P PAGE_HEADER PICKBOATS PRICE_INCREASE R SALARY_REPORT SALARY_REPORTl SALARY_REPORT2 TAB_TEST SALARY_TOTALS SUM TEST_WAGE TITLE_PAGE V WAGE_REPORT WP YACHT_PER_LB XP YACHTS_REPORT YACHT_PRICE DTR> :BIG_YACHTS_OUERYffiITj Enter MIN LOA: ···z Execution terMinated by operator DTR> 9-16 Using DATATRIEVE Procedures Using DATATRIEVE Command Files 10 Many people use DATATRIEVE by typing in single commands in the form @ENTERC or :MONTHLY_REPORT and then watching the results scroll on their screens. Someone else has prepared a command file or procedure for them. Within the command file or procedure are the DATATRIEVE commands and statements to carry out a given task. Command files are much like procedures. Both contain fixed sequences of DATATRIEVE commands and statements and both allow you to execute frequently used operations. They have the following differences: • You invoke a command file by typing the at sign (@) before the file specification, a procedure by typing a colon (:) before the procedure name. • You store the procedures in your dictionary. You can see your procedures with a SHOW PROCEDURES command from within DATATRIEVE. Your command files, on the other hand, reside outside DATATRIEVE in your operating system directory. You must exit from DATATRIEVE and use operating system commands to display them. • You edit procedures with the DATATRIEVE Editor, command files with your operating system editor. • When you invoke command files, you see the command statements and comments echo on your terminal. You can use command files for the following purposes: • To create a startup command file that will automatically execute certain commands and statements each time you invoke DATATRIEVE. Default name for the file is QUERY.INI. See Chapter 2. • To create and then invoke command files to add definitions of dictionary objects to your dictionary. 10-1 • To use as backup files of your dictionary. If something happens to corrupt the dictionary and you need to restore the definitions it previously contained, you can use your backup files of domain, record, table, and procedure definitions. DATATRIEVE executes the command file and returns to your operating system's command level. • To process files in batch mode. You can include invocation command lines to execute DATATRIEVE commands and statements. • To develop and test a procedure you want to store in your dictionary: 1. Put the steps of the procedure into a command file. Do not yet include the DEFINE PROCEDURE command. 2. Execute the command file from your operating system's command level. 3. The steps in the command file will appear on the screen and stop at the point where an error occurs. Use the message to help you decide what is wrong with the series of statements you have entered. 4. When you have eliminated all errors from the command file, insert a DEFINE PROCEDURE statement at the beginning of the file and an END_PROCEDURE statement at the end of the file. If you have an earlier version of the procedure or another element with the same name that you do not need any more, insert a DELETE command and the file name before the DEFINE PROCEDURE statement. Be careful not to delete anything important, however. 5. Execute the command file by typing an at sign (@) and the file name to load the procedure into your dictionary. 10.1 Creating a Command File You create a command file at the operating system level with a text editor. Invoke an editor and enter the sequence ofDATATRIEVE commands and statements just as you would in DATATRIEVE. Do not include DATATRIEVE prompts such as DTR>, CON>, DFN>, or RW> , only the commands and statements you enter following a prompt. When you complete the sequence of commands and statements and exit from the editor, your operating system stores the command file in your system directory. It is usually a good idea to specify .CMD as the file extension of a DATATRIEVE command file. Because it is the default file extension, you do not have to type the .CMD extension when you invoke the command file in DATATRIEVE. For example, to invoke the command file HELLO.CMD in DATATRIEVE, you can type the following: DTR> @HELLO 10-2 Using DATATRIEVE Command Files 10.2 Contents of a Command File A command file can contain any DATATRIEVE command or statement. 10.2.1 ADT, EDIT, SET GUIDE You can include ADT, EDIT, or SET GUIDE commands in a command file. DATATRIEVE places you in ADT, edit, or Guide mode and displays an ADT, edit, or Guide prompt. You cannot include a response to the Guide prompt in your command file, however. The file can contain only commands or statements. DATATRIEVE executes the next line in the command file only after you exit from the DATATRIEVE Editor, Guide mode, or ADT. Even if that line is a valid response to an ADT, edit, or Guide mode prompt, DATATRIEVE displays an error message and returns you to DATATRIEVE command level unless it is a valid DATATRIEVE command or statement. 10.2.2 Comments You can include comments in a command file by placing an exclamation point (!) before each comment line. Comments echo on your terminal when you invoke the file. If your command file defines a procedure and you put comments into the procedure definition, DATATRIEVE stores the comments in the dictionary along with the rest of the definition. DATATRIEVE displays those comments when you invoke the command file. When you invoke the procedure, however, DATATRIEVE does not display the comments on your terminal. 10.3 Invoking a Command File To invoke a command file that you have catalogued in your directory, precede the file specification with an at sign (@). To invoke a command file, enter the invocation on a line by itself. For RSTS systems, use this format: @device:[PPN]filename.cmd For RSX systems, use this format: @device:[UIC]filename.cmd;version If the file extension is .CMD and the file is in your default directory, you need enter only the file name: @filename Using DATATRIEVE Command Files 10-3 10.3.1 Invocation Command Lines You need not eJ.1ter DATATRIEVE to invoke a command file. You can invoke a command file from the system level. For example, to invoke PRT.CMD in your operating system directory, type this in response to the system level prompt (> ): > DTR @PRT@ Invoking a command file in this way differs from invoking one in response to the DTR> prompt. DATATRIEVE executes all the commands and statements in the command file as though you had entered them interactively. However, it does not print the DTR> prompt on your terminal and after executing the last command or statement in the file, it automatically exits from DATATRIEVE. If the command file is in another user's directory, you invoke it by specifying all the necessary information in the following format: @device:[UIC]filename.extension For RSX systems, you can also specify a version number after the extension. 10.3.2 Invoking a Command File from a Procedure You can invoke a command file from a procedure you define with the DEFINE PROCEDURE command. For example, suppose you create a procedure PICKBOATS to form a collection of boats that cost more than $10,000. Invoke a command file SAMPLE.CMD containing report-generating statements within PICKBOATS to produce a report: DTR> DEFINE PROCEDURE PICKBoATSOO DFN> READY YACHTS@ DFN> FIND YACHTS WITH PRICE GT 10000 SORTED BY LoAt BEAMOO DFN> @SAMPLEOO SET ABORT !THIS REPORT REQUIRES AN ESTABLISHED COLLECTIONt !SORTED BY LOA AND BEAM. !HAVE YOU ESTABLISHED A COLLECTION? IF *.IIYES OR NOli CONTAINING IINII THEN ABORT IISORRYt NO COLLECTION. II REPORT ON *.IIOUTPUT DEI,IICE OR FILEII SET REPoRT_NAME=IISAMPLE REPORTII/IIFROM A PROCEDURE II SET LINES_PAGE=55t CoLUMNS_PAGE=60 PRINT BUILDER, MODEL, LOAt BEAMI PRICE AT BOTTOM OF LOA PR I NT SK I P I II AI,IERAGE PR I CE = II t AI,IERAGE (PR I CE) I SK I P AT BOTTOM OF REPORT PRINT COL 171 IINUMBER OF BOATS = II COL 40 I COUNT I SK I P I II AI,IERAGE PR I CE OF ALL BOATS = II I AI)ERAGE (PR I CE) END_REPORT DFN> END_PRoCEDUREOO DTR> :PICKBOATSOO Enter YES OR NO: YOO Enter OUTPUT DEVICE OR FILE: TI:OO DTR> (continued on next page) 10-4 Using DATATRIEVE Command Files SAMPLE REPORT FROM A PROCEDURE MANUFACTURER EASTWARD MODEL Ho 25-Aug-82 Page 1 LENGTH ot.IER ALL BEAM PRICE 2a 09 $15,900 AI.IERAGE PRICE IRWIN $15,900 25 25 12 AI.IERAGE PRICE AMERICAN GRAMPIAN WESTERLY TANZER ALBIN $10,950 $10,950 26-MS 26 CENTAUR 26 79 26 26 26 26 26 08 08 08 09 10 $18,895 $11,495 $15,245 $11,750 $17,900 DTR> You cannot invoke command files while you are in ADT or Guide Mode. You can invoke a command file in response to the RW> prompt of the Report Writer. The file must begin with valid report statements. If you complete the report specification in the file with an END_REPORT statement, you can follow the specification with other valid DATATRIEVE commands or statements. When you invoke a command file, DATATRIEVE prints each command or statement on your terminal and executes it as if you had entered it directly from your keyboard. If an error occurs, DATATRIEVE prints an error message and stops executing the command file. 10.4 Aborting Command Files To abort a command file that may contain an error, include an ABORT statement in the file. If the responses meet the abort conditions and SET ABORT is in effect, DATATRIEVE aborts the command file and prints the message specified for the ABORT command. If SET NO ABORT is in effect, DATATRIEVE aborts the command or statement that contains the ABORT but continues to execute the commands and statements that follow in the file. 10.5 Editing a Command File To edit a command file you must exit from DATATRIEVE and use a text editor. When you correct any error, return to DATATRIEVE, ready the necessary domains, establish any appropriate collections, and execute the command file again. Using DATATRIEVE Command Files 10-5 10.6 Sample Command File In contrast to the sample procedure, the sample command file prints each statement and command in the file as DATATRIEVE executes it. When DATATRIEVE encounters the statement with the *."YES OR NO" prompting value expression, it pauses to wait for your response to the question: HAVE YOU ESTABLISHED A COLLECTION? The Boolean expression CONTAINING checks your response to the question. If the response contains a letter N anywhere, the command file aborts. When DATATRIEVE encounters the *."OUTPUT DEVICE OR FILE" prompt, it pauses again for you to select the device or file for output of the report. Note that, except for the report name, the report the command file produces is the same as the one produced by the procedure YACHT_SUMMARY in Chapter 9. The file YSUM.CMD contains the following sequence of commands and statements: SET ABORT !THIS REPORT REQUIRES AN ESTABLISHED COLLECTION, !SORTED BY LOA AND BEAM. !HAVE YOU ESTABLISHED A COLLECTION? IF *.IIYES OR NOli CONTAINING liN II THEN ABORT IIS0RRY, NO COLLECTION. II REPORT ON *. II OUTPUT DEIJI CE OR FILE II SET REPORT_NAME=IISAMPLE REPORTlljllFROM A COMMAND FILEII SET LINES_PAGE=55, COLUMNS_PAGE=60 PRINT BUILDER, MODEL, LOA, BEAM, PRICE AT BOTTOM OF LOA PRINT SKIP, "AI)ERAGE PRICE =", AI.IERAGE (PR I CE), SK I P AT BOTTOM OF REPORT PRINT COL 13,IINUMBER OF BOATS = COL 33, COUNT, SK I p, II AI.IERAGE PR I CE OF ALL BOATS =", AI.IERAGE (PR I CE) END_REPORT II When you have readied the domain and established the appropriate collection, you invoke the command file with an at sign (@). You do not have to include the .CMD extension. DATATRIEVE prints each command and statement as it executes them: DTR> READY YACHTS(@) DTR> FIND FIRST 5 YAC"HTS WITH LOA BETWEEN 36 37 AND PRICE NE O(@) [5 records found] DTR> SORT BY LOA, BEAM(@) DTR> @YSUMffiill SET ABORT !THIS REPORT REQUIRES AN ESTABLISHED COLLECTION, !SORTED BY LOA AND BEAM. ! !HAVE YOU ESTABLISHED A COLLECTION? IF *.IIYES OR NOli CONTAINING liN II THEN ABORT IIS0RRY, NO En t e r YES OR NO: YES(@) REPORT ON *.1I0UTPUT DEVICE OR FILE" SET REPORT_NAME=IISAMPLE REPORTlljllFROM A COMMAND FILEII SET LINES_PAGE=55, COLUMNS_PAGE=60 COLLECTION. II (continued on next page) 10-6 Using DATATRIEVE Command Files PRINT BUILDER, MODEL, LOA, BEAM, PRICE AT BOTTOM OF LOA PRINT SKIP, IIAVERAGE PRICE =11, AI.IERAGE (PR ICE), SK I P AT BOTTOM OF REPORT PRINT COL 17,IINUMBER OF BOATS = II, COL 40, COUNT, SK I P, II A1.lERAGE PR I CE OF ALL BOATS = II, A1.lERAGE (PR I CE) END_REPORT Enter OUTPUT DE1.lICE OR FILE: TI:tBTI) 01-Apr-S7 Pa9'e 1 SAMPLE REPORT FROM A COMMAND FILE MODEL MANUFACTURER ISLANDER I. TRADER LENGTH OVER ALL BEAM PRICE 36 36 11 12 $31 ,730 $38,500 36 37 $35,615 AVERAGE PRICE IRWIN NORTHERN ALBERG 37 37 37 37 MARK II 37 37 MK I I $36,850 $50,000 $36,851 11 11 12 AVERAGE PRICE $41 ,300 NUMBER OF BOATS = AVERAGE PRICE OF ALL BOATS 10.7 = 5 $38,026 Nesting Command Files Within Command Files You can invoke both procedures and command files from within a command file. For example, the command file MSMOD creates a loop with a FOR statement and then invokes the command file MOD. MOD contains a BEGIN-END block of statements that allows you to modify prices interactively: DTR> @MSMODtBTI) READY YACHTS WRITE FOR YACHTS WITH RIG IIMS II @MOD BEGIN PRINT IF *.IIY TO MODIFY, N TO SKIp CONTAINING THEN MODIFY PRICE ELSE PRINT IINO CHANGEII IF *.IIY TO CONTINUE, N TO ABORT II CONTAINING IINII ABORT IIEND OF PRICE CHANGES II END ll MANUFACTURER MODEL RIG lIylI LENGTH OI.lER ALL WEIGHT BEAM AMERICAN - ~6-MS MS 26 Enter Y TO MODIFY, N TO SKIP: ytBTI) Enter PRICE: 18350tBTI) Enter Y TO CONTINUE, N TO ABORT: ytBTI) EASTWARD HO MS 24 PRICE 5,500 OS $lS,850 7,000 08 $15,800 (continued on next page) Using DATATRIEVE Command Files 10-7 Enter Y TO MODIFY, N TO SKIP: NOO NO CHANGE Enter Y TO CONTINUE, N TO ABORT: NOO ABORT: END OF PRICE CHANGES DTR> FIND YACHTS WITH RIG = IIMS II OO [5 records found] DTR> SELECTm DTR> PRINTCBill MANUFACTURER AMERICAN MODEL 28-MS RIG LENGTH OVER ALL WEIGHT BEAM MS 28 5,500 08 PRICE $18,350 DTR> When nesting command files, do not allow a command file to invoke itself, either directly or indirectly. If you do, you receive this message: COMMand file 10.8 nestin~ liMit exceeded Using a Command File in a FOR or REPEAT Statement You can invoke a command file in a loop you create with the FOR or REPEAT statements. As the following example shows,You must be sure to invoke the command file on a separate line, and you must include its statements within a BEGIN-END block: DTR> SET NO PROMPTOO DTR> READY YACHTS WRITEOO DTR> FIND YACHTS WITH RIG = IIKETCH II OO [13 records found] DTR> FOR CURRENT @MODOO Expected statefrlent, encounte red II@II. DTR> FOR CURRENTOO CON> @MODOO BEGIN PRINT IF *.IIY TO MODIFY, N TO SKIp CONTAINING THEN MODIFY PRICE ELSE PRINT liND CHANGE II IF *.IIY TO CONTINUE, N TO ABORT II CONTAINING IINII ABORT IIEND OF PRICE CHANGES II END lI MANUFACTURER MODEL RIG lIylI LENGTH OI.JER ALL WEIGHT BEAM PRICE 20,000 $38,851 ALBERG 37 MK II KETCH 37 Enter Y TO MODIFY, N TO SKIP: hZ Execution terMinated by operator DTR> 10-8 Using DATATRIEVE Command Files 12 10.9 Maintaining Command Files Your operating system directories, not the dictionary, store the command files. If you adopt the convention of using .CMD as the extension for command files, you can display the names of the command files on your terminal by requesting a directory listing of*.CMD at the command level. You can adopt any other convention you wish and use the wildcard in the same manner: READY >DIR *.CMD;lliIT) Nalrle .T}'p Size BLDllM.CMD 2 CLASSE.CMD 3 SAMPLE.CMD a Prot Date < GO> za-Sep-8Z < GO> za-Sep-8Z < GO> za-Sep-8Z SY: [ 1 t 37] You can display the contents of a command file with the TYPE command at the system level: >TYPE SAMPLE.CMD;lliIT) SET ABORT !THIS REPORT REQUIRES AN ESTABLISHED CoLLECTIoNt !SoRTED BY LOA AND BEAM. !HAVE YOU ESTABLISHED A COLLECTION? IF *."'(ES OR NO" CONTAINING "N" THEN ABORT "SoRRYt NO COLLECTION." REPORT ON *. "OUTPUT DE1nCE OR FILE" SET REPoRT_NAME="SAMPLE REPoRT"/"FRoM A COMMAND FILE" SET LINES_PAGE=55t CoLUMNS_PAGE=GO PRINT BUILDERt MODELt LOAt BEAMt PRICE AT BOTTOM OF LOA PRINT SKIP t "AI.JERAGE PRICE =" t AI.JERAGE (PR I CE) t SK I P AT BOTTOM OF REPORT PRINT COL 17t "NUMBER OF BOATS = "t COL ao t COUNT t SK I P t "AI.JERAGE PR I CE OF ALL BOATS =" t AVERAGE (PR I CE) END_REPORT You can delete a command file from your directory with the operating system command level DELETE command. >DELETE SAMPLE.CMD;lliIT) Using DATATRIEVE Command Files 10-9 Using DATATRIEVE Variables 11 A variable is a symbol whose value can change as you execute a program. You can use the letter A as a variable, for instance. The name of the variable stays the same, but its value can change during a DATATRIEVE session. You use variables in DATATRIEVE: • To assign values to fields in STORE and MODIFY statements • As counters in FOR, REPEAT, and WHILE loops • As conditional values in Boolean expressions 11.1 Declaring Variables You declare a variable with a statement in this form: DECLARE variable-name variable-definition The variable name is the name you give to the variable. The variable definition consists of field definition clauses. The following is an example of a DECLARE statement. Notice the similarity between the DECLARE statement and the definition of a field in a record: DTR> DECLARE X PIC 8(7)V88 EDIT_STRING IS $$t$$$t$$$.88. When you declare a variable, you can use any of the DATATRIEVE field definition clauses except OCCURS and REDEFINES. You must include at least one PIC, COMPUTED BY or USAGE clause. You can also use the QUERY_HEADER, QUERY_NAME, EDIT_STRING, VALID IF, and SIGN clauses. 11-1 11.2 Assigning Values to Variables DATATRIEVE assigns a starting value to, or initializes, variables at the time you create them. Numeric variables are initialized to the value o. Alphabetic or alphanumeric string variables are initialized to a blank field (spaces). You can assign an initial value of 0 to numeric fields or space to string fields, but it is not necessary to do this. Of course, you must always initialize a variable when you want the starting value to be other than the DATATRIEVE default. In most cases, you use the assignment statement (=) to give a value to a variable. The assignment statement takes the following form: variable-name = value-expression Variable name is the name you gave the variable in the DECLARE statement. Value expression can be anyone of the following: • A literal • A field name • Another variable • A prompting value expression • Values from a table • A statistical function • An arithmetic expression • A concatenated expression Remember, however, to assign a value that is consistent with the definition of the variable. If you assign a value that is larger or a different data type than you specified in the PIC or USAGE clauses, your results might not be what you intended. You can also use the assignment statement to change the value ofa variable at any time after initialization. The following example declares a variable, prints its initial value, then changes its value using two methods: DTR)- DECLARE}-{ PIC 999 EDIT_STRING ZZ9.(ffi) DTR)- PR I NT }{(ffi) I) DTR)- X 23; PRINT }{(ffi) 23 (continued on next page) 11-2 Using DATATRIEVE Variables DTR> )-{ = *. "1.IALUE FOR )-{"~ En t e r VALUE FOR ~-{: Ll5G~ DTR> PRINT ~-{ (-)~ Ll5G DTR> The minus sign (-) in the preceding example suppresses the/heading, in this case the name of the variable (X), in a PRINT statement. The following example illustrates another way of assigning values to a variable. In the example, the procedure NAME-LIST creates a variable (NEAT-N"AME). The values of the variable are supplied from the PERSONNEL domain and computed by two fields (FIRST_NAME and LAST-N"AME) in the record definition for that domain. The values for the variable change as the values for the COMPUTED BY fields change. The procedure uses the variable both to restrict the print display to the two name fields in the record and to improve the appearance of each name by eliminating extra spaces between the first and last names: DTR> SHOW NAME_LIST~ PROCEDURE NAME_LIST DECLARE NEAT_NAME COMPUTED BY FIRST_NAME::" ":LAST_NAME QUERY_HEADER IS "EMPLOYEE NAMES". READY PERSONNEL PRINT NEAT_NAME OF FIRST 2 PERSONNEL END_PROCEDURE DTR> :NAME_LIST~ EMPLOYEE NAMES CHARLOTTE SP I 1.1 A FRED HOWL DTR> 11.3 Local and Global Variables You can define two kinds of variables in DATATRIEVE: • Global • Local You use the DECLARE statement to define both local and global variables. A variable you define with a BEGIN-END block is a local variable, and you can use it only within that block. A variable you define at DATATRIEVE command level is a global variable. It remains in your workspace until you release it or exit from DATATRIEVE. Use the assignment statement (variable = value) to set the variable equal to a particular value. Using DATATRIEVE Variables 11-3 11.3.1 Global Variables You can use a global variable to change values in every record in a domain. Suppose you want to assign to each boat in YACHTS a new price that is two-thirds of the present price. By using a COMPUTED BY clause in a global variable, you can apply a single formula to every yacht, as in the example that follows: DTR> DTR> CON> DTR> DTR> READY YACHTS MODIFY(BTI) DECLARE SALE_PRICE COMPUTED BY PRICE/1.5(BTI) EDIT_STRING IS $Z8,888.88.(BTI) SALE_PRICE = O(BTI) FOR FIRST 5 YACHTS PRINT BOAT, SALE_PRICE(BTI) MANUFACTURER MODEL RIG LENGTH OVER WEIGHT BEAM ALL ALBERG ALBIN ALBIN ALBIN AMERICAN 37 MK I I 78 BALLAD I.JEGA 28 KETCH SLOOP SLOOP SLOOP SLOOP 37 28 30 27 28 20,000 4,200 7,278 5,070 4,000 12 10 10 08 08 PRICE SALE PRICE $38,851 $24,834.00 $17,800 $11 ,833.33 $27,500 $18,333.33 $18,800 $12,400.00 $8,885 $ 8,588.87 DTR> The variable SALE-PRICE declared at DATATRIEVE command level remains in the workspace throughout the session. It changes its value whenever the value of PRICE changes. The variable remains in your workspace until you release it with the RELEASE command or declare another variable with the same name. 11.3.2 Local Variables You define local variables with DECLARE statements entered in BEGIN-END blocks and THEN statements. The local variable has an effect only within the clause or statement in which you declare it. In the following example, the local variable declared in the inner statement supersedes one with the same name declared in an outer statement. Notice that the different value or different data type assigned to the inner variable has no effect on the value of the variable in the outer statement. Note also that neither local variable exists when DATATRIEVE finishes executing the compound statements containing them both: . DTR> SET NO PROMPT (BTI) DTR> BEGIN(BTI) CON> DECLARE ~< PIC }ODD<.(BTI) CON> }o{ = IITOPII(BTI) CON> PRINT H(BTI) CON> BEG I N(BTI) CON> DECLARE ~< PIC 8.88. (BTI) CON > ~< = 1. 23(BTI) CON> PR I NT ~<(BTI) CON> END(BTI) (continued on next page) 11-4 Using DATATRIEVE Variables CON> PR I NT CON> ENDlliIT) ~<lliIT) }.{ TOP V 1\ 1.23 TOP DTR> PR I NT Field "}-{" ~<lliIT) is undefined or used out of context DTR> If you declare a global variable and then use the same name for local variables, the value of the global variable is not affected by value assignments and changes made to its local counterpart(s). 11.4 Using Variables to Assign Values to Fields You can use variables to assign values to fields in the USING clauses of STORE and MODIFY statements. You cannot, however, use a variable to respond to a prompt for a field value, whether the prompt is the result of the syntax of the STORE or MODIFY statement or of a prompting value expression. In USING clauses of STORE and MODIFY statements, you can use value expressions on the right side of assignment statements to supply values for fields. In some circumstances, you can use variables in those assignments to control the uniformity of input data. In this example, WORK is a domain you want to contain uniform names. The data file is indexed on WHO and allows duplicates: DTR> SHOW WORK_REClliIT) RECORD WORK_REC USING 01 TOP. 03 JOB PIC X(15). 03 RESPONSIBLE_PERSON PIC x(a) QUERY_NAME WHO. DTR> Using DATATRIEVE Variables 11-5 NAME_TABLE translates the varying inputs into uniform values to store in the work domain: DTR> SHOW NAME_TABLEoo TABLE NAME_TABLE EDt ED t ED t EDt FRED t FRED t FREDt FRED t RICK t RICK t RICK t RICK t RICK t E ED EM M F FH FRED H L R RBL RICK RL ELSE II????II END_TABLE In the following STORE statement, the USING clause uses the variable PERSON with a prompting value expression for the responsible person. The table translates the value supplied to that prompt and stores the uniform results in the field WHO. DTR> SET NO PROMPToo DTR> DECLARE PERSON PIC }{(S) .00 DTR> READY WORK WRITEoo DTR> REPEAT 3 STORE WORK USINGoo CON> BEGINoo JOB = *.JOBOO CON> PERSON = *.WHOOO CON> WHO = PERSON I.' I A NAME_TABLEoo CON> CON> ENDoo Enter JOB: CLEANINGoo Enter WHO: Eoo Enter JOB: DRYINGoo Enter WHO: FRoo Enter JOB: SELLINGoo Enter WHO: ROO DTR> PRINT WORKoo JOB RESPONSIBLE PERSON CLEANING DRYING SELLING ED ???? RICK DTR> 11.5 Using Variables as Counters to Control Record Streams You can use a counter to keep track of how many times DATATRIEVE performs a task. When you use a counter to control a record stream, however, it can also limit the number of times DATATRIEVE executes FOR and WHILE statements. 11-6 Using DATATRIEVE Variables Suppose you want to keep a running count of the yachts you are repricing. You can use the following global variable: DTR) DECLARE A PIC 999.@W DTR) A = O@W DTR> PRINT A@W A 000 DTR> DTR> CON) CON> CON> CON> SET NO PROMPT@W FOR YACHTS@W BEGIN@W A = A + 1@W PRINT A, BOAT@W END A MANUFACTURER MODEL RIG LENGTH OVER ALL WEIGHT BEAM 001 002 003 004 005 006 007 ALBERG ALBIN ALBIN ALBIN AMERICAN AMERICAN BAYFIELD 37 MK I I 79 BALLAD VEGA 26 26-MS 30/32 KETCH SLOOP SLOOP SLOOP SLOOP MS SLOOP 37 26 30 27 26 26 32 20,000 4,200 7,276 5,070 4,000 5,500 9,500 12 10 10 08 08 08 10 $36,951 $17,900 $27,500 $18,600 $9,895 $18,895 $32,875 113 WRIGHT SEAWIND II SLOOP 32 14,900 00 $34,480 PRICE DTR) In this example, you use the variable as a counter. Each time DATATRIEVE prints the corresponding record, it increases A by one. When you use a global variable as a counter in FOR and WHILE statements, you must initialize the variable to ensure that DATATRIEVE executes the loop the number of times you intend. If you use the same variable to control two loops, you must reinitialize the variable before DATATRIEVE executes the second loop. If you do not, DATATRIEVE may execute the loop fewer times than you intend. It may not execute the loop at all if the value of the variable is greater than the value specified in the IF-THEN-ELSE statement in the second loop. Either at the beginning or the end of the loop, you can use an IF-THEN-ELSE statement to evaluate the variable against a set of conditions. Depending on the evaluation, DATATRIEVE will continue the looping or execute an ABORT statement to end the loop. This example shows the use of a global variable to control a FOR statement and force an end to the loop: DTR> DTR) DTR> DTR) SET NO PROMPT@W READY YACHTS@W DECLARE B PIC 9.@W B = 000 (continued on next page) Using DATATRIEVE Variables 11-7 DTR> FOR YACHTSOO) CON> BEGINOO) CON> B = B + 1(0) CON> PRINT Bt BOATOO) CON> IF B = 7 THEN ABORT "END OF LOOPIlOO) CON> ENDOO) B MANUFACTURER MODEL RIG ALBERG 37 MK I I KETCH ALBIN 79 SLOOP ALBIN BALLAD SLOOP a ALBIN VEGA SLOOP 5 AMERICAN 28 SLOOP 8 AMERICAN 28-MS MS 30/32 7 BAYFIELD SLOOP ABORT: END OF LOOP Execution te rlrlinated b }' "ABORT" DTR) 2 3 LENGTH OI.'ER ALL WEIGHT BEAM 37 28 30 27 28 28 32 20tOOO at200 7t278 5,070 a,ooo 5,500 9,500 12 10 10 08 08 08 10 PRICE $38t951 $17t900 $27t500 $18t800 $9t895 $18t895 $32,875 5 tat elrlen t You can also assign a value greater than zero to the variable and use it as a decremental counter, as in this example: DTR> DECLARE A PIC 9. DTR> A=8 DTR> PRINT AOO) A 8 DTR> DTR> CON> CON> CON> CON> CON> SET NO PROMPTOO) FOR YACHTSOO) BEGINlBTI) PRINT At BOATOO) A = A - 1(0) IF A = 0 THEN ABORT "END OF LOOPIlOO) ENDCBTI) A MANUFACTURER MODEL RIG LENGTH OI)ER ALL WEIGHT BEAM 20,000 ALBERG 37 MK I I KETCH 37 79 ALBIN SLOOP 28 at200 7,278 ALBIN BALLAD SLOOP 30 I)EGA 5,070 ALBIN SLOOP 27 a,ooo a AMERICAN 28 SLOOP 28 5,500 3 AMERICAN MS 28-MS 28 30/32 9,500 BAYFIELD 2 SLOOP 32 18,500 1 BLOCK I • ao SLOOP 39 ABORT: END OF LOOP Execution t e rlrl ina ted b }' "ABORT" statelrlent DTR> 8 7 8 5 11-8 Using DATATRIEVE Variables 12 10 10 08 08 08 10 12 PRICE $38t951 $21 1859 $27t500 $18,800 $9,895 $18t895 $32,875 $29t050 The WHILE statement causes DATATRIEVE to repeat a statement as long as the condition specified in the Boolean expression is "true." The command file (WH.CMD) in this example uses a variable in a WHILE statement. DTR) @WH(@) DECLARE A USAGE INTEGER. A = 0 PRINT A A o FOR YACHTS WHILE A < 5 BEGIN A = A + 1 PRINT At BOAT END MANUFACTURER A 2 3 a 5 ALBERG ALBERG ALBERG ALBERG ALBERG 37 37 37 37 37 MODEL RIG LENGTH Ot.IER ALL WEIGHT BEAM MK MK MK MK MK KETCH KETCH KETCH KETCH KETCH 37 37 37 37 37 II II II II II 20tOOO 20tOOO 20tOOO 20tOOO 20tOOO 12 12 12 12 12 PRICE $38t951 $38t951 $38t951 $38t951 $38t951 DTR) The variable in the next example changes with the value expression PRICE/LOA and stops the FOR loop when the value expression meets the condition specified in the IF-THEN-ELSE statement: DTR> SET NO PROMPT@] DTR) FIND FIRST 15 YACHTS(@) [15 records found] DTR> DECLARE ~{ PIC 9999 EDIT_STRING IS $$ t$$$.99.(@) DTR) ~{ = O@] DTR) FOR CURRENT@0 CON) BEGIN@] CON) ){ = PRIC E / LOA@] PRINT TYPE t ~{ (IIPRICEII/IIPER FOOTII)(@) CON) IF }-( GE 1000 THEN ABORT TOO SHORT FOR THE MONEY II(@) CON) CON) END(@) 11 MANUFACTURER MODEL PRICE PER FOOT ALBERG ALBIN ALBIN ALBIN AMERICAN AMERICAN BAYFIELD 37 MK I I 79 BALLAD t.IEGA 28 28-MS $998.00 $888.00 $918.00 $888.00 $380.00 $728.00 $1 t027. 00 30/32 ABORT: TOO SHORT FOR THE MONEY Execution terlTlinated b}' IIABORT II statelrlent DTR) Using DATATRIEVE Variables 11-9 Using DATATRIEVE Tables 12 Tables save space. They save space in record definitions and data files. They also save space when you type in commands and statements. With a DATATRIEVE table, you can associate codes with corresponding translations - for example, area codes with states and products with price codes. One advantage to such code and translation pairs is that you can substitute a short field for a long one. For instance, you can have a list of codes for job titles such that you can put E01 into the definition and have a table that translates the code into Tax Assessor First Class. A dictionary table looks like the sample in Figure 12-1. DICTIONARY TABLE Code Translation C "Customer Services" E Engineering Figure 12-1: Code and Translation Pairs in a Dictionary Table 12.1 A Sample Dictionary Table Suppose, for example, that you are a manufacturer who needs to order various items from clerks around the country. With the help of a DATATRIEVE table, you can use one command to find out which products have reached zero inventory, which clerks are responsible for the parts, and the phone numbers for those clerks. 12-1 You can use a dictionary table, in this case a table called ORDER_TABLE, to pair clerks and phone numbers with the products you need to track. You can define a procedure to determine which items are out of stock, then invoke a table producing a list of clerks responsible for those parts. The following example uses the domain PRODUCTS and a procedure TAB, which finds the items no longer in stock and uses ORDER_TABLE to list the clerks you need to call: DTR> READY PRODUCTSffiITl DTR> PRINT ALL PRODUCTSffiITl I.IENDOR PARTS PART IN NUMBER STOCK ITEM ACME ASPHALT &: SHINGLE ACME ASPHALT &: SHINGLE ACME ASPHALT &: SHINGLE PURGE SYSTEMS PURGE SYSTEMS PURGE SYSTEMS PURGE SYSTEMS QUERY ENTERPRISES QUERY ENTERPRISES ASPHALT SHINGLES CUBE WALLS ERASER-CHALK ERASER-PENCIL WHITE-OUT MAGNETS-20 oz. LISTINGS REPORTS 1001 1002 1003 3001 3002 3003 300a 2001 2002 3 0 8888 3 1 86a5 0 a 0 DTR> SHOW ORDER_TABLEffiITl TABLE ORDER_TABLE ilL. LANDF I LL ACME ASPHALT &: SH I NGLE (888) 555-123a liT. ABMOW (111) 555-a321" t "QUERY ENTERPRISES" liT. SKWAIRDEE "PURGE SYSTEMS (123) 555-8876" t ELSE "S0METHING ELSE" END_TABLE DTR> SHOW TABffiITl PROCEDURE TAB FIND PRODUCTS WITH STOCK = 0 SORTED BY PART FOR CURRENT PRINT ITEM, PART, VENDOR 1)1 A ORDER_TABLE (" CALL ") US I NG }-{ (30) END_PROCEDURE DTR> : TABffiITl II II II II ITEM SHINGLES REPORTS MAGNETS-20 oz. DTR> 12-2 Using DATATRIEVE Tables PART NUMBER CALL 1002 2002 300a L. LANDFILL (888) 555-123a . T. ABMOW (111) 555-a321 T. SKWAIRDEE (123) 555-8876 , 12.2 Creating Dictionary Tables To create a dictionary table, enter the DEFINE TABLE command: DEFINE TABLE table-name Then enter the pairs of codes and their translations on separate lines, separating them by a colon (:). Make sure to place a comma after each pair at the end of the line. If the code or the translation contains more than one word, enclose it in quotation marks. For example, the translation "New Hampshire" must be placed in quotation marks so DATATRIEVE will recognize the two words as one translation entry. You must also use quotation marks to preserve lowercase letters in a code or translation. If you use quotation marks, the rules for character string literals apply. That is, neither the code nor the translation can exceed 132 characters, and neither can contain a RETURN, line feed, space, or control character. After the last code and translation pair, you can enter an optional ELSE clause. DATATRIEVE substitutes the translation in the ELSE clause for any values not found in the table. If your dictionary table does not contain an ELSE clause, DATATRIEVE prints an error message when it cannot find a value in the table. Translations included in an ELSE clause are also enclosed in quotation marks. Apply the same rules as with character string literals, except do not place a comma after an ELSE clause. To end a dictionary table definition, enter the keyword END_TABLE. The END_TABLE statement must follow the ELSE clause, if specified, or the last code and translation pair if there is no ELSE clause. If you omit the ELSE clause, do not put a comma after the last code and translation pair. After you enter the END_TABLE statement, DATATRIEVE stores the definition in your current dictionary and creates an access control list for the dictionary table. When you first refer to a table, DATATRIEVE searches the current data dictionary for the table and loads it into your DATATRIEVE workspace. DATATRIEVE evaluates the value expression in your statement and compares the value with the codes in the table. The comparison is case sensitive and proceeds characterby-character. Thus, a value expression of 5 does not match a code of 05, and a value expression of Rig does not match a code of RIG. As you define a dictionary table, DATATRIEVE checks for syntax errors. For example, if you use a semicolon in place of the required colon, DATATRIEVE prints an error message and aborts the DEFINE TABLE command. DATATRIEVE does not store anything in the dictionary until you complete the table definition without a syntax error. You can use the DATATRIEVE Editor to change a table once it is in the dictionary. Using DATATRIEVE Tables 12-3 If you want to edit the table as you create it, you can: • Enter one co4e and translation pair, finish the definition with END_TABLE, then use the DATATRIEVE Editor to extend the table to include additional code and tranlation pairs . • Leave DATATRIEVE and use the editor you usually use on your operating system to define the table in a command file. Then enter DATATRIEVE again and invoke the command file at the DTR> prompt. DATATRIEVE checks the syntax, and if the definition contains an error you can leave DATATRIEVE again and edit the command file. See Chapter 10 for more information about command files. 12.3 Sample Dictionary Tables This section show ways you can define and use dictionary tables. For example, suppose you are a sales manager with a list of names and phone numbers of potential customers, and you want to know where they live. You can enter telephone area codes and their corresponding state names in a dictionary table, then refer to the table in a PRINT statement. You can define a dictionary table as follows: TABLE 207 603 802 617 AREA_CODE_TABLE MAINEt "NEW HAMPSHIRE" t 1.IERMoNT t "EASTERN MASSACHUSETTS" t a13 "WESTERN MASSACHUSETTS" t a01 "RHODE ISLAND" t 203 CoNNECTICUTt ELSE "NOT A I.IAL I 0 AREA CODE" END_TABLE Then you can prompt for an area code and print the corresponding state in a single statement: DTR> PR I NT *." AREA CODE" In A AREA_CoDE_ TABLE US I NG }{ (21 ) ffiIT) Enter AREA CODE: 203ffiIT) CONNECTICUT DTR> Suppose you also want to create a table of abbreviations for RIG, KETCH, SLOOP, and MS from the YACHTS domain. You can create the following dictionary table, RIG_TABLE, and store it in the data dictionary for YACHTS: DTR> DFN> DFN> DFN> DFN> DFN> DFN> DTR> 12-4 DEFINE TABLE RIG_TABLEffiIT) "SLOOP" "ONE-MAST" tffiIT) "KETCH" : "TWO MASTS t BIG ONE IN FRONT" tffiIT) "YAWL" : "SIMILAR TO KETCH" tffiIT) "MS" : "SAILS AND BIG MOTOR" tffiIT) ELSE "SOMETHING ELSE"ffiIT) END_TABLEffiIT) Using DATATRIEVE Tables 12.4 Using the IN Relational Operator with DATATRIEVE Tables You can use tables with the relational operators IN and NOT IN to set conditions in IF-THEN-ELSE statements and to validate data. The following is the general format for using IN and NOT IN with a DATATRIEVE table: field-name *.prompt variable-name 12.4.1 [NOn IN table-name Using a Table in a Record Selection Expression In a record selection expression, you can use a Boolean expression that refers to a dictionary table: DTR> FDR YACHTS WITH RIG NOT IN RIG_TABLE PRINT BOAT®) MANUFACTURER AMERICAN EASTWARD FJORD LINDSEY ROGGER FD MODEL 26-MS HO MS 33 39 MIS RIG MS MS MS MS MS LENGTH OI.JER ALL WEIGHT BEAM 26 2a 33 39 35 5t500 7tOOO latOOO lat500 17t600 08 09 11 12 11 PRICE $18t895 $15t900 $35t900 DTR> FIND YACHTS WITH RIG IN RIG_TABLE®) [108 records found] DTR> 12.4.1.1 Using a Table to Set Conditions in an IF-THEN-ELSE Statement - You can combine IN with a table reference to set the conditions of an IF-THEN-ELSE statement: DTR> SET NO PROMPT®) DTR> FOR YACHTS WITH LOA = 26®) CON> BEGIN®) CON> PRINT®) CON> IF RIG NOT IN RIG_TABLE®) CON> THEN ABORT "Does not frleet reqUirefrlents"®) CON> END®) MANUFACTURER MODEL RIG LENGTH OI.JER ALL WEIGHT BEAM 79 SLOOP 26 at200 ALBIN 26 SLOOP 26 atOOO AMERICAN AMERICAN MS 26 5t500 26-MS ABORT: Doe~ not Meet reqUireMents Execution terfrlinated b}' "ABORT" statefrlent DTR> 10 08 08 PRICE $17t900 $9t895 $18t895 Using DATATRIEVE Tables 12-5 Using a VALID IF Clause with a Table to Validate Data - By referring to a dictionary table in a VALID IF clause, you can validate data in a field before storing the data. The VALID IF clause must be part of the record definition. The following definition of PHONE_REC illustrates this method of automatic data validation: 12.4.1.2 DTR> DEFINE RECORD PHONE_REC USINGoo DFN> 01 PHONE.oo DFN> 02 NAME PIC }-{ (20) .00 DFN> 02 NUMBER PIC 9(7) EDIT_STRING IS }on-{-}oon<.oo DFN> 02 LOCATION PIC }-{(9).(@l DFN> 02 DE PARTMENT PIC }o< I.JAL I D I Foo DFN> DEPARTMENT IN DEPT_TABLE.ffiITl DFN> ;00 DTR> The table DEPT_TABLE looks like this: DTR> SHOW DEPT_TABLEoo TABLE DEPT_TABLE IIT3 11 IITYPESETTING II , IID5 11 IIFINANCE II , IIR9 11 : IIHOUSEKEEPING II , 1I}-{711 : IIGROUNDSKEEPING II , IIR711 : IIBEEKEEPING II , ELSE IINOT A DEPARTMENT HEREII END_TABLE DTR> If you try to enter a department number that is not in the table, DATATRIEVE rejects the entry and prompts you for a correct one: DTR> READY PHONE WRITEffiITl DTR> STORE PHONEoo Enter NAME: IIBENJAMIN PAUL"ffi(!) Enter NUMBER: 75aS769ffiITl Enter LOCATION: POLE_SffiITl Enter DEPARTMENT: TaffiITl Validation error for DEPARTMENT Re-enter DEPARTMENT: T3ffiITl DTR> 12.4.2 Using the Keyword VIA with DATATRIEVE Tables To refer to tables in value expressions, combine the table name with the keyword VIA. DATATRIEVE compares the codes in the table with the value you supply. If the value matches one of the codes, DATATRIEVE uses the corresponding translation in the table. Use the following format to refer to a dictionary table in a value expression: field-name * .prompt variable-name 12-6 VIA table-name Using DATATRIEVE Tables You can refer to an entry in the dictionary table RIG_TABLE by using a prompting value expression, as shown in the following PRINT statement: DTR> PRINT *."TYPE OF BOAT" I,IIA RIG_TABLE USING ){<30)ffiTI) Enter TYPE OF BOAT: KETCHffiTI) TWO MASTS, BIG ONE IN FRONT If you refer to a dictionary table in a PRINT statement, include an"edit string to specify the number of characters to be printed. If you omit the edit string, DATATRIEVE uses an edit string that is 10 characters long. 12.5 DATATRIEVE Tables and Workspace Once you have referred to a table, it remains in your DATATRIEVE workspace until you either relinquish it with the RELEASE command or end your DATATRIEVE session. If you are redefining a table, you must release the old version before the new table takes effect. Note that DATATRIEVE does not release tables when you switch data dictionaries. You cannot have two tables with the same name in your workspace at the same time. Use the SHOW READY command to display the names of tables in your DATATRIEVE workspace. It is helpful for optimization to see the tables in your workspace so you can release tables you do not need. For a complete discussion ofDATATRIEVE workspace, see Chapter 17 in this manual. 12.6 Displaying Table Information You can use the SHOW TABLES command to list the names of all dictionary tables in your default dictionary. DTR> SHOW TABLESffiTI) Tables: DEPT_TABLE JOB_TITLE NAME_TABLE RIG_TABLE DTR> 12.6.1 Displaying Tables To display a dictionary table on your terminal, use the SHOW command and specify the name of the table. Use the following format to display a table: SHOW table-name [(pa~;Wd)] Using DATATRIEVE Tables 12-7 Here is an example: DTR> SHOW AREA_CODE_TABLEID TABLE AREA_CODE_TABLE 207 MAINE, 603 "NEW HAMPSHIRE", 802 I.IERMONT, 617 "EASTERN MASSACHUSETTS 413 "WESTERN MASSACHUSETTS 401 RHODE I SLAND 203 CONNECTICUT, ELSE NOT A I.IAL I D AREA CODE END_TABLE DTR> II II , II , , II 12.6.2 II II Editing Tables You can modify a table in the current data dictionary with the DATATRIEVE Editor. Type EDIT and the table name, then use the Editor to make the desired changes. Remember to end a new table entry with a comma. When you EXIT from the Editor, DATATRIEVE places the modified table in your workspace. See Chapter 16 for more information on the DATATRIEVE Editor. The following example illustrates how to use the Editor to add a new entry to an existing table: DTR> SHOW NUM_LISTID TABLE NUM_LIST 1: "ONE" , 2: "TWO" , 3: I THREE", ELSE "NUMBER OUT OF TABLE RANGE" END_TABLE DTR> EDIT NUM_LISTID OED> IELSE"ffiD) ELSE "NUMBER OUT OF TABLE RANGE" OED> lID IN> 4: "FOUR" ,ID IN> ,. z OED> WHID 1: "DNE" , 2: "TWO" , 3: "THREE" , 4: "FOUR ELSE "NUMBER OUT OF TABLE RANGE" END_TABLE OED> '·z DTR> II 12-8 Using DATATRIEVE Tables , 12.6.3 Deleting Tables You can delete a table from your current data dictionary with the DELETE command. Use the following format: DELETE table-name [(pa~~Wd)] The following example deletes AREA_CODE_TABLE from the default data dictionary: DTR> SHOW TABLES@] Tables: AREA_CODE_TABLE JOB_TITLE DTR> DELETE AREA_CODE_TABLEj@] DTR> SHOW TABLES@] NAME_TABLE Tables: JOB_TITLE NAME_TABLE DTR> 12.7 Protecting Dictionary Tables When you create a dictionary table, DATATRIEVE stores its definition in the current data dictionary and creates an access control list (ACL) for it. DATATRIEVE automatically stores one project-programmer number (PPN) or user identification code (UIC) in the ACL with full access privileges. An account number is called a PPN under RSTS/E systems and a UIC under other operating systems. Your individual installation determines the actual PPN/UIC that is stored in the ACL. Any user logged in under that PPN/UIC and the creator of the table have R (Read), W (Write), E (Execute), M (Modify), and C (Control) access to the dictionary table. Depending on the PPN/UIC in the ACL, other users in the installation may be able to delete, modify, or print the dictionary table. If you want to grant additional privileges to other users or further restrict the use of the dictionary table, you must modify its ACL. For more information on protecting dictionary tables and on modifying access control lists, refer to Chapter 19. To guard against accidental deletion of your dictionary table, you can maintain a backup copy of it by using the DATATRIEVE EXTRACT command to copy your table to a disk file or tape file. For example: DTR > E~{TRACT ON NAMTAB BK P NAME_TABLE@] t DTR> Using DATATRIEVE Tables 12-9 Defining and Using Views 13 A view is a special type of domain that lets you select some or all fields in some (or all) records from one or more domains. Using a view, you can refer to fields and field values in different domains without duplicating their records and data. You can use views to do the following: • Work with subsets of records • Refer to subsets of fields in records • Change the apparent order of the fields in records • Combine subsets of records from more than one domain • Modify the values in the fields you select A view does not actually change the way fields are organized in records or the way records are combined into data files. A view only changes how existing data appears to you. You can modify values in the fields selected by the view, but you cannot store or erase any records accessed by the view. A view is like a window in a house. Just as a window might let you look into more than one room, a view can let you look into more than one domain. A window might give you a complete look at everything in one or more rooms, restrict what you can see to a few items of furniture, or only let you see the back of one chair. Similarly, a view can let you look at all records, a few records, or parts of records. Each window in a house gives you a different picture of what is inside, but the actual locations of the items you see are the same no matter how you look at them. In the same way, when you define a view, you do not affect the way information is actually stored. 13-1 13.1 Defining Views You define a view by creating a domain definition in your data dictionary with the DEFINE DOMAIN command: DEFINE DOMAIN view-name OF domain-name [, ... ] USING level-number-1 field-na'me-1 OCCURS FOR rse-1 . level-number-2 field-name-2 {OCCURS FOR rse-2 } FROM domain-name-2 After the keyword OF, you must list each domain that the view uses. The domains you list cannot be views themselves. You may specify the domains in any order, separating them with commas. You must end each field definition with a period and ena the view definition with a semicolon. You can use two clauses to define the fields in a view: • OCCURS FOR • FROM The top-level field must be defined with an OCCURS FOR clause. The record selection expression in the first OCCURS FOR clause determines the number of records in the view. Each subsequent OCCURS FOR clause creates a list within the view. Consequently, a view that contains more than one OCCURS FOR clause is always a hierarchy. (The first OCCURS FOR clause does not make the view a hierarchy. It only establishes the source record stream for the view.) See Chapter 14 for more information about hierarchies. You establish the fields of data for the view with the FROM clause. It specifies the name of the field and the domain from which it derives. The domain must be the same domain named in the preceding OCCURS FOR clause. The field name must be either a field name or a query name from that domain. If two or more fields have the same name, you might have to qualify those field names to avoid ambiguity. See Appendix A for more information about qualified field names. 13-2 Defining and Using Views 13.1.1 Views Using Subsets of Records A view lets you work with a specific subset of records from another domain. For instance, you may want to work with the records for ketches only and no other rig type. The following example shows a view definition that allows you to work with four fields of the yachts that are ketches: DTR DFN DFN DFN DFN DFN DFN DTR DTR DEFINE DOMAIN KETCHES@] OF YACHTS USING@] 01 KETCH OCCURS FOR YACHTS WITH RIG EQ "KETCH".@] 03 TYPE FROM YACHTS.@] 03 LOA FROM YACHTS.@] 03 PRICE FROM YACHTS.@] ;@] READY KETCHES@] PRINT FIRST 4 KETCHES@] LENGTH OI.JER ALL MANUFACTURER MODEL ALBERG CHALLENGER FISHER FISHER 37 MK I I 37 41 41 30 37 30 37 PRICE $36t951 $51 t228 DTR> The view domain KETCHES, which is based on the single domain YACHTS, is not hierarchical because there is only one OCCURS FOR clause. You cannot store or erase records in a view. Otherwise, you can use a view just as you would any other domain. 13.1.2 Views Using Subsets of Fields Another type of view lets you refer to a subset of fields from the records of another domain. For example, the record definition for YACHTS contains seven elementary fields and three group fields: DTR> READY YACHTS@] DTR> SHOW FIELDS@] YACHTS BOAT TYPE [Indexed field] MANUFACTURER (BUILDER) [Character stringt indexed Key] MODEL [Character stringt indexed Key] SPECIFICATIONS (SPECS) RIG [Character string] LENGTH_OVER_ALL (LOA) [Character string] DISPLACEMENT (DISP) [NuMber] BEAM [NuMber] PR I CE [NUfrlb e r] Defining and Using Views 13-3 If you want to work with only a few fields of the record, you can create a record definition for those fields and then create a domain and a data file containing one record for each record in YACHTS. The result is a data file that duplicates some field values in an existing data file (YACHT.DAT). Maintaining these two files so that they always contain the same field values would be difficult. You can define a view, however, that lets you look at just the fields in YACHTS that you need without duplicating field values. You also avoid the additional time and overhead of creating another record definition and creating and updating two data files: DTR> DEFINE DOMAIN MAKERS(@) DFN> OF YACHTS USING(@) DFN> 01 BOAT OCCURS FOR YACHTS.(@) DFN> 03 TYPE FROM YACHTS.(@) DFN> 03 RIG FROM YACHTS.(@) DFN> DTR> READY MAKERS(@) DTR> PRINT FIRST 6 MAKERS(@) MANUFACTURER MODEL RIG ALBERG ALBIN ALBIN ALBIN AMERICAN AMERICAN 37 MK I I 79 BALLAD VEGA 26 26-MS KETCH SLOOP SLOOP SLOOP SLOOP MS 13.1.3 Views Using More Than One Domain The preceding sections showed how to use view domains to define a subset of records or fields from a single domain. You can also use field values from more than one domain. The domain OWNERS, for example, contains records of yacht owners. Each record contains the owner's name and the name, builder, and model of the owner's yacht: DTR> SHOW OWNER_RECORD(@) RECORD OWNER_RECORD ALLOCATION IS LEFT_RIGHT 01 OWNER. 03 NAME PIC }-{ ( 10) QUERY _HEADER I S OWNER NAME EDIT_STRING IS X(5). 03 BOAT _NAME PIC }-{ ( 17) QUERY _HEADER I S BOAT NAME 03 TYPE. 06 BUILDER PIC X(10). 06 MODEL PIC X(10). II II / II DTR> READY OWNERS(@) DTR> PRINT FIRST 1 OWNERS(@) OWNER NAME BOAT -NAME BUILDER SHERM MILLENNIUM FALCON ALBERG DTR> 13-4 Defining and Using Views MODEL 35 II II II • If you define a view that refers to both the OWNERS domain and the YACHTS domain, you can use any combination of fields and records in those domains. For example, you can include the name and yacht fields from the OWNERS domain and the price field from the YACHTS domain. The view SAILBOATS in the following example uses every field and every record in the YACHTS domain to match owners with the boats they own. It uses records from the OWNERS domain and matches those records by boat type with records in the YACHTS domain. It requests only the NAME field from those records. After the first OCCURS FOR clause, each OCCURS FOR creates a list within the view. A domain that contains a list is a hierarchy. The view SAILBOATS, therefore, is a hierarchical view: DTR> SHOW SAILBOATS(@) DOMAIN SAILBOATS OF YACHTSt OWNERS USING 01 SAILBOAT OCCURS FOR YACHTS. 03 BOAT FROM YACHTS. 03 SKIPPERS OCCURS FOR OWNERS WITH TYPE EO BOAT.TYPE. 05 NAME FROM OWNERS. DTR> The field SKIPPERS is a list of owner names. Each record in SAILBOATS can contain a NAME field for each of several owners. This view allows you to combine all the information on each yacht with the names of all its skippers. DTR> READY SAILBOATS(@) DTR> PRINT FIRST" 2 SAILBOATS WITH ANY SKIPPERS(@) MANUFACTURER MODEL RIG LENGTH OI.IER ALL WEIGHT ALBIN I.IEGA KETCH 35 17tOOO 12 CB:C CORVETTE SLOOP 31 BtG50 01 BEAM PRICE $33tOOO OWNER NAME STEI.IE HUGH JIM ANN DTR> Printing the values of list fields is illustrated later in this chapter. Hierarchies are discussed in greater detail in Chapter 14. In general, if you define a view that uses only one domain, use an OCCURS FOR clause to define the top-level field and then use FROM clauses to specify which fields the view contains. If you define a view using more than one domain, group the field definitions by the domain they refer to, putting the field definition with an OCCURS FOR clause first in each group. Defining and Using Views 13-5 13.2 Using a View Domain You use a view as you do any other domain. To ready a view" you must have R (Read) access privilege to the view, and you must also have the same access privilege to each domain the view uses. You must have E (Execute) access privilege to the record definition associated with each domain. You cannot store or erase records in a view, but you can modify values of fields. For example, here is how to modify a field in the view KETCHES: OTR> READY KETCHESCffi) OTR> SHOW KETCHESCffi) OOMAIN KETCHES OF YACHTS USING 01 KETCH OCCURS FOR YACHTS WITH RIG EO "KETCH". 03 TYPE FROM YACHTS. 03 LOA FROM YACHTS. 03 PRICE FROM YACHTS. OTR> READY KETCHES MODIFYCffi) OTR> FIND KETCHES WITH PRICE EO OCffi) [a records found] OTR> PRINT ALLCffi) MANUFACTURER FISHER FISHER PEARSON PEARSON MOOEL 30 37 385 alB LENGTH OI.IER ALL PRICE 30 37 38 az OTR> FOR CURRENT PRINT THEN MOOIFY PRICECffi) MANUFACTURER MODEL FISHER Enter PRICE: FISHER Enter PRICE: PEARSON Enter PRICE: PEARSON Enter PRICE: 30 30000Cffi) 37 a5000Cffi) 385 3Z000Cffi) alB 5aOOOCffi) LENGTH OI.IER ALL PRICE 30 37 38 az OTR> PRINT ALL MANUFACTURER FISHER FISHER PEARSON PEARSON MOOEL 30 37 385 alB OTR> 13-6 Defining and Using Views LENGTH OI.JER ALL 30 37 38 az PRICE $30tOOO $a5tOOO $3ZtOOO $5atOOO 13.2.1 Using a View That Contains a List To refer to field values contained in a list, use one of the methods described in Chapter 14. For example: DTR> SHOW SAILBOATSOO DOMAIN SAILBOATS OF YACHTSt OWNERS USING 01 SAILBOAT OCCURS FOR YACHTS. 03 BOAT FROM YACHTS. 03 SKIPPERS OCCURS FOR OWNERS WITH TYPE EQ BOAT.TYPE. 05 NAME FROM OWNERS. DTR> READY SAILBOATS WRITEOO DTR> FIND OWNED IN SAILBOATS WITH ANY SKIPPERSOO [6 records found] DTR> PRINT ALLOO MANUFACTURER MODEL RIG LENGTH OI.lER WEIGHT BEAM ALL ALBIN I.IEGA SLOOP 27 5t070 08 C~:C CORI.IETTE SLOOP 31 8t650 08 ISLANDER BAHAMA SLOOP 2a at200 08 PEARSON PEARSON RHODES 10M 26 SWIFTSURE SLOOP SLOOP SLOOP 33 26 33 12taa1 11 08 10 5taOO 1atOOO PRICE OWNER NAME $18t600 STEI.IE HUGH JIM ANN $6t500 JIM ANN STEI.IE HARI.IE TOM DICK JOHN DTR> SELECT 300 DTR> FIND SKIPPERSOO [a records found] DTR> PRINT ALLOO OWNER NAME JIM ANN STEI.IE HARI.lE DTR> SELECT 200 DTR> MODIFY NAMEOO Enter NAME: ANNEOO DTR> PRINT BOATt ALL SKIPPERS SORTED BY NAME OF OWNEDOO (continued on next page) Defining and Using Views 13-7 MANUFACTURER MODEL ALBIN t.IEGA SLOOP 27 5,070 08 C&:C CORt.IETTE SLOOP 31 8,650 08 ISLANDER BAHAMA SLOOP 24 4,200 08 PEARSON PEARSON RHODES 10M 26 SWIFTSURE SLOOP SLOOP SLOOP 33 26 33 12,441 5,400 14,000 08 10 DTR> 13-8 RIG LENGTH OVER ALL WEIGHT BEAM Defining and Using Views 11 PRICE OWNER NAME $18,600 HUGH STEt.IE ANN JIM $6,500 ANNE HARt.IE JIM STEt.IE TOM DICK JOHN Using Hierarchies 14 In DATATRIEVE, the term hierarchy refers to a one-to-many relationship between record sources. With hierarchies, you can nest record streams to see a single record from one record source displayed with a combination of records from another record source. This nesting established a parent-child relationship between the two record streams. For each record in the outer, parent record stream, you see all records in the inner, child record stream. Parent records are displayed even if there are no corresponding child records in the inner record stream. Some examples of how this can be useful are: o One team with several players • One project with several workers • One employee with several previous jobs • One library with many books • One computer with several users Hierarchies let you define records with fields that are lists. Items in a list can contain more than one field, and the list itself may contain more than one item. Therefore, a list lets you store more than one value for a field or group of fields in one record. Lists are also called repeating fields. When you retrieve a value from a record containing a repeating field, you cannot always apply the same statements you do for other records. The following 14-1 sequence of statements shows what can happen when you try to print the repeating field KIDS from the hierarchical record FAMILIES: DTR> READY FAMILIESm DTR> SHOW FAMILY_RECm RECORD FAMILY_REC 01 FAMILY. 03 PARENTS. 08 FATHER PIC X(10). 08 MOTHER PIC X(10). 03 NUMBER_KIDS PIC 88 EDIT_STRING IS Z8. 03 KIDS OCCURS 0 TO 10 TIMES DEPENDING ON NUMBER_KIDS. 08 EACH_KID. 08 KID_NAME PIC X(10) QUERY_NAME IS KID. 08 AGE PIC 88 EDIT_STRING IS Z8. DTR> PRINT FATHER OF FAMILIESm FATHER JIM JIM DTR> PRINT MOTHER OF FAMILIESm MOTHER ANN LOUISE DTR> PRINT KIDS OF FAMILIESm Expected end of staterrlent t encounte red 1I0F II DTR> You can print the names of fathers and mothers, but you get an error message when you try to print the list field KIDS. If you form a collection, you can again print information on fathers and mothers but not kids: DTR> FIND FAMILIESm [13 records found] DTR> PRINT ALL FATHERm FATHER JIM JIM (continued on next page) 14-2 Using Hierarchies DTR> PRINT ALL MOTHER@) MOTHER ANN LOUISE DTR> PRINT ALL EACH_KID@) Field "EACH_KID" is undefined or used out of context DTR> PRINT ALL KIDS@) Field "KIDS" is undefined or used out of context DTR> PRINT ALL KIDS OF FAMILIES@) Expected end of statelTlent t encountered "OF" In the first two examples, you get a message stating that the field name is undefined or used out of context. The third example results in the same message you got in the previous example. To retrieve the information, you can apply one of the following methods to set up a DATATRIEVE context: • Use a FIND statement to establish a context for the list. Then use a SELECT statement to identify one record in the collection. • Use nested FOR RSE loops. The outer FOR loop forms a target stream of hierarchical records and the inner FOR loop forms a stream of list items within a hierarchical record. • Use inner print lists (ALL print-list OF rse) to form a stream of list items within a record stream. The following sections describe these methods for retrieving items from lists. For more information about DATATRIEVE context, see Appendix A in this manual. 14.1 Retrieving Repeating Field Values with FIND and SELECT Statements You use the FIND statement to find all the records in the file that meet your specifications. Then you can use the SELECT statement to request anyone of these records: DTR> READY FAMILIES@) DTR> FIND FAMILIES@) [1a records found] DTR> SELECT 3; PRINT@) FATHER JOHN MOTHER JULIE NUMBER KIDS 2 KID NAME ANN JEAN AGE 29 26 Using Hierarchies 14-3 When you have selected a record that contains a list, you can treat the list as though it were a source of records like a domain or collection. You can continue as follows: DTR> PRINT KIDS(@) KID NAME ANN JEAN DTR> AGE 29 26 You can also combine the FIND and SELECT statements to single out one list item. Then the context of the selected list item allows you to use the list item name by itself in a PRINT statement. Continue the previous example by forming a collection of the KIDS list field and selecting a list item from the collection: DTR> FIND KIDS(@) [2 records found] DTR> SELECT 2; PRINT(@) KID NAME JEAN AGE 26 DTR> PRINT AGE(@) AGE 26 DTR> 14.2 Retrieving Repeating Field Values with Nested FOR Loops To retrieve values from list items by nesting FOR loops, start from the top of the hierarchy and work toward the list items you want to retrieve. In the following example, the source for the RSE in the first or outer FOR loop is the hierarchical domain FAMILIES. The source in the second loop is the list item KIDS: DTR> FOR FAMILIES(@) [LooKin~ for statement] CON> FOR KIDS WITH AGE < 10(@) [LooKin~ for statement] CON> PRINT KID_NAME(@) (continued on next page) 14-4 Using Hierarchies KID NAME URSULA RALPH CHRISTOPHR SCOTT BRIAN DAVID PATRICK SUZIE DTR> The FOR statement preceding the PRINT statement in the following example loops through all the records in FAMILIES. For each of those records, the RSE in the PRINT statement retrieves only the first kid whose ag~ is less than 10: DTR> FOR FAMILIESlBTI) [Looking for stateMent] CON> PRINT KID_NAME OF FIRST 1 KIDS WITH AGE <: 10lBTI) KID NAME URSULA CHRISTOPHR SCOTT DAt.JID PATRICK DTR> The OF rse clause in the PRINT statement serves the same purpose as a nested FOR RSE statement. The inner RSE (FIRST 1 KIDS WITH AGE < 10) identifies items from the list field KIDS that are included with a FAMILIES record identified by the outer FOR RSE statement. You get the same results using the following nested FOR rse statements: DTR) FOR FAMILIES FOR FIRST 1 KIDS WITH AGE <: 10 PRINT KID_NAME 14.3 Retrieving Repeating Field Values with Inner Print Lists The simplest way to print a repeating field is to print the entire record containing the repeating field: DTR) READY FAMILIESlBTI) DTR> PRINT FIRST 1 FAMILIESlBTI) FATHER JIM MOTHER ANN 2 NUMBER KIDS URSULA RALPH KID NAME AGE 7 3 DTR> Using Hierarchies 14-5 To print selected fields from the record, you must specify a print list in the PRINT statement. (Print lists consist offield names or other value expressions and modifiers.) To specify a list item in a print list, you must use an inner print list, which has the format: ALL print-list OF rse In the print list clause of the inner print list, include the list items you want to display. The OF rse of the inner print list creates a context for the item in the hierarchical list. You can nest an inner print list in a PRINT statement using any of the following formats. The arrows under each format show where the inner print list begins and ends. A sample PRINT statement for the FAMILIES domain illustrates each format: 1. PRINT ALL ALL print-list OF rse OF rse t t DTR> PRINT ALL ALL KID_NAME OF KIDS OF FIRST 1 FAMILIES(8ffi KID NAME URSULA RALPH DTR> 2. PRINT [ALL] value-exp, ALL print-list OF rse OF rse t t DTR> PRINT ALL MOTHER, FATHER, ALL KID_NAME OF(8ffi CON> FIRST KIDS OF FIRST 1 FAMILIES(8ffi MOTHER ANN FATHER KID NAME URSULA JIM DTR> 3. PRINT ALL ALL print-list OF rse, value-exp OF rse t t DTR> PRINT ALL ALL KID_NAME OF FIRST 1 KIDS, FATHER OF(8ffi CON> FIRST FAMILIES(8ffi KID NAME URSULA DTR> 14-6 Using Hierarchies FATHER JIM There are two important points to remember when working with inner print lists: • To DATATRIEVE, an inner print list is just another print list element in the outer print list . • An inner print list establishes context for items in a list. See Appendix A for more information about context. While inner print lists can complicate statements, they allow you to control completely how DATATRIEVE displays repeating fields. By using the repeating field as the source for an RSE in an inner print list, you can specify which occurrences of the repeating field DATATRIEVE displays. As a rule of thumb, you can think of embedding an inner print list in a PRINT statement the same way you think of nesting parentheses in an arithmetic expression. Just as you put a matching left parenthesis for every right parenthesis in an arithmetic expression, there must be a matching ALL for every RSE in a PRINT statement. In the second format the first ALL is optional, but it is easier to remember the rule of thumb than to remember when ALL is optional. The remainder of this section presents more examples to help you use inner print lists effectively. By limiting the RSEs in a PRINT statement, you can tailor a record stream to suit your needs. These next three examples show the results of limiting one or both of the RSEs in a PRINT statement that includes an inner print list using the second format: DTR> PRINT ALL MOTHER t ALL EACH_KID OF KIDS OF FIRST 1 FAMILIES(BTI) MOTHER ANN KID NAME AGE URSULA RALPH 7 3 DTR> PRINT ALL MOTHERt ALL EACH_KID OF FIRST 1 KIDS OF FAMILIES(BTI) MOTHER ANN LOUISE JULIE ELLEN ANNE SARAH ANNE MERIDETH 0101 RUTH BETTY LOIS SARAH TRINITA KID NAME AGE URSULA 7 ANNE 31 ANN 29 CHRISTOPHR 0 SCOTT 2 (I DAI.! 10 4 PATRICK BEAU 28 ERIC MARTHA JEFF CHARLIE ERIC 32 30 23 31 16 (continued on next page) Using Hierarchies 14-7 DTR> PRINT ALL MOTHERt ALL EACH_KID OF(ill) CON> FIRST 1 KIDS OF FIRST 1 FAMILIES(ill) KID NAME AGE URSULA 7 MOTHER ANN DTR> If you want to display only items from the list field, you must precede the inner print list with two ALL keywords, one for each RSE you define. In the following examples, the first ALL matches the RSE, FIRST 1 FAMILIES WITH NUMBER_KIDS = 3. The second ALL matches the RSE, KIDS: DTR> PRINT ALL ALL EACH_KID OF KIDS OF(ill) [Loo~~ing for IIFIRST t dOfrlain nafrlet or collection nafrle] CON> FIRST 1 FAMILIES WITH NUMBER_KIDS = 3(ill) ll KID NAME JEFF FRED LAURA AGE 23 26 21 DTR> PRINT ALL ALL KID_NAME OF KIDS WITH(ill) [LooKing for Boolean expression] CON> AGE GT 25 OF FAMILIES(ill) KID NAME ANNE JIM ELLEN ANN JEAN BEAU BROOKS ERIC MARTHA TOM FRED CHARLIE HAROLD SARAH DTR> The last display contains blank lines that you would probably want to eliminate. Eliminating empty print lines is discussed in the next section. 14-8 Using Hierarchies Note that when you include a list field in a print list, you should specify the list field as the last item. The following example shows what happens when you specify some other field after the list. The display of that field begins on the same line as the last item in the list: DTR> PRINT ALL ALL EACH_KID OF KIDS, MOTHER OF FIRST 2 FAMILIES(@) KID NAME URSULA RALPH ANNE JIM ELLEN DA1.JID ROBERT AGE 7 3 31 29 26 MOTHER ANN 2L1 16 LOUISE DTR> 14.4 Retrieving List Items with Nested RSEs - Eliminating Empty Print Lines You can use Boolean expressions in the outer RSE to eliminate empty print lines. Empty print lines occur when the outer RSE includes records that do not satisfy the inner RSE. When DATATRIEVE processes a record that does not contain information needed by the inner RSE, it generates a carriage return and line feed. The following example illustrates empty print lines that result from an outer RSE (FAMILIES) that forces DATATRIEVE to include records that do not match inner RSE requirements: DTR> PRINT ALL ALL EACH_KID OF KIDS WITH(@) [LooKin~ for Boolean expression] CON> AGE GT 25 OF FAt1 I LIES(@) KID NAME AGE ANNE JIM ELLEN ANN JEAN 31 29 26 29 26 BEAU BROOKS 28 26 ERIC MARTHA TOM FRED CHARLIE HAROLD SARAH 32 30 27 26 31 35 27 DTR> Using Hierarchies 14-9 In the following statement, the clause WITH ANY KIDS eliminates the blank line caused by the record of the family without children: DTR> PRINT ALL ALL EACH_KID OF KIDS WITH(BIf) [LooKing for Boolean expression] CON> AGE GT 25 OF FAMILIES WITH ANY KIDS(BIf) KID NAME AGE ANNE JIM ELLEN ANN JEAN 31 29 26 29 26 BEAU BROOKS ERIC MARTHA TOM FRED CHARLIE HAROLD SARAH 28 26 32 30 27 26 31 35 27 DTR> The four blank lines in the preceding print display represent the records offamilies who have kids, but whose kids have ages less than or equal to 25. The following statement excludes those records from the record stream and therefore eliminates the blank lines: DTR> PRINT ALL ALL EACH_KID OF KIDS WITH(BIf) [LooKing for Boolean expression] CON> AGE GT 25 OF FAMILIES WITH ANY KIDS WITH(BIf) [LooKing for Boolean expression] CON> AGE GT 25(BIf) KID NAME AGE ANNE JIM ELLEN ANN JEAN BEAU BROOKS ERIC MARTHA TOM FRED CHARLIE HAROLD SARAH 31 29 26 29 26 28 26 32 30 27 26 31 35 27 DTR> 14-10 Using Hierarchies You do not have to use an extra ALL before inner print lists if you put the PRINT statement in a FOR statement: DTR> FOR FAMILIES PRINT ALL EACH_KID OF KIDS WITH(ill) [Looking for Boolean expression] CON> KID_NAME CaNT "Y"(ill) KID NAME JAY CISSY NANCY AGE 22 2a 22 DTR> 14.5 Retrieving Values from Sublists You can use collections, nested FOR loops, or inner print lists to retrieve values from sublists (lists within lists). When you work with sublists, you must remember to create a context for each level of the hierarchy. The outermost context establishes the target record or target record stream (source = FAMILIES); the second establishes the context for the list (source = KIDS); and the third establishes the context for the sublist (source = PET); and so on. This series of FIND and SELECT statements uses collections to retrieve one list item from PET: DTR> READY PETS(ill) DTR> FIND PETS(ill) [3 records found] DTR> SELECT; FIND KIDS@] [2 records found] DTR> SELECT; FIND PET(ill) [2 records found] DTR> SELECT; PRINT PET_NAMEt PET_AGE(ill) PET NAME POP PET AGE 03 DTR> Using Hierarchies 14-11 You can also use nested FOR loops for dealing with a sublist: DTR> FOR PETS WITH ANY KIDS(§] [LooKing for stateMent] CON> FOR KIDS WITH ANY PET(§] [LooKing for stateMent] CON> FOR PET WITH PET_AGE GT O(§] [LooKing for stateMent] CON> PRINT PET_NAMEt PET_AGE(§] PET NAME POP SODA MOUSE SHORTY SQUEEKY FRANK FRANK PET AGE 03 oa 03 08 03 07 la DTR> You can also use inner print lists to get at all three levels of the hierarchy: DTR> PRINT ALL ALL ALL PET_NAME OF PET OF(§] [Loo~\ing for IIFIRST II t dOlrlain nalrle t or collection nalrle] CON> KIDS WITH ANY PET WITH PET_AGE NE 0 OF(§] [Loo~\ing for IIFIRST II t dOlrlain nalrle t or collection nalrle] CON> PETS WITH ANY KIDS WITH ANY PET t~ I TH PET _AGE NE O(§] PET NAME POP SODA MOUSE SHORTY SQUEEKY FRANK FRANK DTR> 14-12 Using Hierarchies Restructuring Domains 15 This chapter describes how to create new domains with data from existing ones. You might do this to: • Add new fields to the record definition associated with the domain • Change field definitions to affect the values stored in the data file • Create a copy of a domain for testing • Change the file organization • Change the index structure (key fields) • Create a domain that contains a subset of records contained in another domain How you create the new domain depends on whether you want to keep the old domain. If you want to keep the old domain, follow these steps when creating the new domain: 1. Define a new domain, its record, and its data file. 2. Ready the new domain for WRITE or EXTEND access and the old domain for READ access. 3. Use a statement with the following format to transfer field values from the old data file to the new one: FOR rse-FROM-old-domain-name STORE new-domain-name USING new-record-name = old-record-name 15-1 If you want to use old procedures on the new domain, you must edit them if they refer to fields not included in the new domain. See Chapter 9 for information about editing procedures. If the old procedures refer only to fields included in the new domain, you need not change the procedures. You can ready the new domain with the old domain name as an alias (READY NEW AS OLD) and execute the old procedures. If you do not want to keep the old domain, you can still use the old procedures if you follow these steps: 1. Define the new domain (NEW), record (NEW_REC), and file (NEW.DAT). 2. Use a statement with the following format to transfer the data from the old domain (OLD) to the new one (NEW): FOR rse-FROM-ald-damain-name STORE new-domain-name USING new-record-name = old-record-name 3. Use the REDEFINE command, which deletes the old domain and creates a new domain with the same name as the old domain. The new domain uses the old domain name (OLD), the new record definition (NEWREC), and the new data file (NEW.DAT): DTR> REDEFINE DOMAIN OLD USING NEJ..JREC ON NEJ...l.DATj(ffi) DTR> 4. Check the old procedures for any references to field names not included in the new record definition and edit where necessary. The following sections provide examples to help you restructure your own domains. 15.1 A Sample Domain PROJECTS is a sample domain you can create to practice restructuring: DTR> SHOW PROJECTS, PRoJECTS_REC(ffi) DOMAIN PROJECTS USING PRoJECTS_REC ON PRoJEC.DATj RECORD PRoJECTS_REC USING 01 PROJECT. 03 PRoJ_CoDE PIC 9(3) QUERY_NAME IS CODE. PIC X(10) QUERY_NAME IS NAME. 03 PRoJ_NAME 03 MANAGER_NUM PIC 9(5) QUERY_NAME IS NUM. DTR> 15-2 Restructuring Domains The data file PROJEC.DAT is a sequential file and contains these records: DTR> PRINT PROJECTS~ PROJ CODE PROJ NAME MANAGER NUM 002 005 008 018 037 073 GROUNDS BUILDING 2 SHED RESEARCH PUB REL MATERIALS 00006 00003 00002 00006 00008 00002 DTR> 15.2 Changing Record and File Definitions and Using New Names This section shows you how to change record and file definitions using new names for the record and data file. To create a new domain with two fields added to PROJECTS_REC, follow these steps: 1. Define a new domain: DTR> DEF I NE DOMA I N NEI-L PROJECTS@) DFN> USING NEI-LPROJECTS_REC ON NWPROJ. DAT;~ DTR> 2. Use the EXTRACT command to copy the old record definition to a command file: DTR> EHTRACT ON TEMP DTR> PROJECTS_REC~ 3. Exit DATATRIEVE and edit the command file TEMP.CMD. Remove the DELETE command from the first line of the file, change the name of the record, add the new fields, and include any other changes you want. 4. Enter DATATRIEVE again and invoke the modified command file to enter the new record definition in the data dictionary: DTR> @TEMP~ DEFINE RECORD NEW_PROJECTS_REC USING 01 NEW_PROJECT. 03 PROJ_CODE PIC 9(3) QUERY_NAME IS CODE. 03 PROJ_NAME PIC H(10) QUERY_NAME IS NAME. 03 PROJ_COST PIC 9(6)V99 EDIT_STRING IS $$$t$$9.99. 03 MANAGER_NUM PIC 9(5). PIC X( 15). 03 MANAGER_NAME ; [Record NEW_PROJECTS_REC is al bytes long] DTR) Restructuring Domains 15-3 5. Define a data file for NEW_PROJECTS. This example creates an indexed file to replace the sequential file associated with PROJECTS: DTR> DEFINE FILE FOR NEW_PROJECTS KEY=CODE(illj DTR> You are now ready to transfer the data from the old domain to the new one. 15.2.1 Storing Data from All the Records in the Old Domain This section tells you how to transfer data from all the records in the old domain. The next section explains how to transfer data from a subset of the records in the old domain. You must first ready both domains. Ready the new domain for WRITE or EXTEND access and ready the old domain for READ access. Use the STORE statement in a FOR loop to transfer the data: DTR> READY NEW_PROJECTS WRITE(illj DTR> READY PROJECTSffiIj) DTR> FOR PROJECTSffiIj) [LooKing for stateMent] CON> STORE NEW_PROJECTS USING(illj [LooKing for assignMent stateMent(s)] CON> NEW_PROJECTS_REC = PROJECTS_REC(illj DTR> For each field name in NEWJ>ROJECTS-REC that matches a field name in PROJECTS_REC, the STORE statement transfers field values from the record in PROJECTS to a record in NEW_PROJECTS. If a field in NEW_PROJECTS_REC does not match a field in PROJECTS_REC, DATATRIEVE initializes the field according to its data type and field definition (zero for numeric fields; spaces for alphabetic and alphanumeric ones). The data file associated with NEW_PROJECTS now has records in it. When you display its contents on the terminal, you can see the values transferred from the PROJECTS domain, as well as initial values for the two new fields, PROJ_COST and MANAGER_NAME: DTR> PRINT NEW_PROJECTS(illj PROJ CODE PROJ NAME 002 005 008 018 037 073 GROUNDS BUILDING 2 SHED RESEARCH PUB REL MATERIALS DTR> 15-4 Restructuring Domains PROJ COST $0.00 $0.00 $0.00 $0.00 $0.00 $0.00 MANAGER NUM 00006 00003 00002 00006 00008 00002 MANAGER NAME 15.2.2 Storing Data from a Subset of the Records in the Old Domain You can create the new domain from a subset of the old domain records. You specify the limiting conditions in the RSE following the FOR statement. For example, you could have limited NEW_PROJECTS to the projects of only two managers: DTR> FOR PROJECTS WITH MANAGER_NUM EQ 2t 6ffiDj [LooKing for stateMent] CON> STORE NEW_PROJECTS USINGffiDj [LooKing for aSSignMent stateMent(s)] CON> NEW_PROJECTS_REC = PROJECTS_RECffiDj DTR> PRINT NEW_PROJECTSffiDj PROJ CODE PROJ NAME 002 008 (118 073 GROUNDS SHED RESEARCH MATERIALS PROJ COST $0.00 $0.00 $(1.00 $0.00 MANAGER NUM MANAGER NAME 00006 00002 00006 00002 DTR> 15.2.3 Deleting References to the Old Domain After you store records from the old domain in your new one, you can delete the old data file from your directory. You can continue to use your old procedures with the new record definition and data file, however, by using the REDEFINE command. As described earlier in this chapter, the REDEFINE command deletes the old domain and creates a new domain with the same name as the old domain. The domain is now defined with the new record definition and data file: DTR> REDEFINE DOMAIN PROJECTS USINGffiDj DFN> NEW_PROJECTS_REC ON NWPROJ. DAT H~ DTR> 15.3 Changing Record and File Definitions and Using Old Names This section explains how to restructure domains when you do not want to access old data, but you want to keep the domain, record, and file names you created for the old domain. The sample statements use the domain PROJECTS. Using an alias is the easiest way to change data structures without changing the names you use for them. ----------------------- Note ----------------------- Notice that the changes made to the PROJECTS record and file definitions are not associated with the names you want until you use the FINISH command and ready the PROJECTS domain again. Restructuring Domains 15-5 The following list explains how to restructure domains. Steps preceded by (RSTS/E only) are necessary only if you are working on a RSTS/E system: 1. (RSTS/E only) At the system command level, rename the data file associated with the domain you are restructuring. The examples in the following steps assume that PROJEC.DAT has been renamed OLDPRO.DAT. 2. At the DATATRIEVE command level, use the EXTRACT command to copy the old record definition to a command file: DTR> E}-{TRACT ON TEM P PRoJECTS_REC(@) DTR> 3. At the system command level, edit the command file TEMP.CMD to add the desired field definitions. Do not remove the DELETE command from the first line of the file. 4. (RSTS/E only) At the DATATRIEVE command level, redefine the domain specifying the renamed data file: DTR> REDEFINE DOMAIN PROJECTS USING(@) DFN> PRO,JECTS_REC ON oLDPRo. DAT;(@) DTR> 5. At the DATATRIEVE command level, ready the domain as an alias: DTR> READY PROJECTS AS OLD_PROJECTS(@) DTR> SHOW READY(@) Read}' dOlrlains: OLD_PROJECTS: RMS SEQUENTIAL, PROTECTED READ DTR> 6. Invoke the modified command file to enter the revised record definition in the data dictionary: DTR> @TEMP(@) DELETE PRoJECTS_REC; DEFINE RECORD PRoJECTS_REC USING 01 PROJECT. 03 PRoJ_CoDE PIC 8(3) QUERY_NAME IS CODE. 03 PRoJ_NAME PIC X(10) QUERY_NAME IS NAME. 03 PRoJ_CoST PIC 8(G)V88 EDIT_STRING IS $$$,$$8.88. 03 MANAGER_NUM PIC 8(5). PIC }-«(15). 03 MANAGER_NAME [Record PRoJECTS_REC is 41 bytes long] DTR> 7. (RSTS/E only) Redefine the domain PROJECTS using your original name for the data file: DTR> REDEFINE DOMAIN PROJECTS USING(@) DFN> PRoJECTS_REC ON PRoJEC.DAT;(@) DTR> 15-6 Restructuring Domains 8. Define a new data file for the domain. When you ready a domain' with an alias, as in Step 5, defining a new file does not interfere with the link between that readied domain and the file containing the old data. Do not use the SUPERSEDE option of the DEFINE FILE command. The following example changes the file organization from sequential to indexed: DTR> DEFINE FILE FOR PROJECTS KEY DTR> = NUM(@) 9. Ready the domain as a different alias and specify WRITE access mode. This READY command uses the new record definition and opens the new data file created by the DEFINE FILE command: DTR> READY PROJECTS AS NEW_PROJECTS WRITE(@) DTR> SHOW READY(@) Read}' dOITlains: NEW_PROJECTS: RMS INDEXED, PROTECTED WRITE OLD_PROJECTS: RMS SEQUENTIAL, PROTECTED READ DTR> 10. Use the STORE statement in a FOR loop to move the data from the original domain to the new one. If you plan to use all the records in the domain, you simply specify the alias of the old domain in the FOR statement: DTR> FOR OLD_PROJECTS(@) [Looking for stateMent] CON> STORE NEW_PROJECTS USING(@) [Looking for assignMent stateMent(s)] CON> PROJECTS_REC DTR> = PROJECTS_REC(@) If you plan to use a subset of the records in the old domain, specify a more restrictive RSE including the alias of the old domain. The following example limits the record stream to the projects of two managers: DTR> FOR OLD_PROJECTS WITH MANAGER_NUM EQ 2, G(@) [Looking for stateMent] CON> STORE NEW_PROJECTS USING(@) [Looking for assignMent stateMent(s)] CON> PROJECTS_REC = PROJECTS_REC(@) DTR> Restructuring Domains 15-7 11. When you type FINISH and ready the domain again, you can access data as you restructured it. DATATRIEVE no longer recognizes either alias. The following example assumes that the RSE specified in the FOR loop included all the records from the domain: DTR> FINISHOO DTR> READY PROJECTSOO DTR> SHOW READYOO Read}' dOlllains: PROJECTS: RMS INDEXED, PROTECTED READ DTR> PRINT PROJECTSOO PROJ CODE PROJ NAME 002 005 008 018 037 073 GROUNDS BUILDING 2 SHED RESEARCH PUB REL MATERIALS PROJ COST MANAGER NUM $0.00 $0.00 $0.00 $0.00 $0.00 $0.00 MANAGER NAME 00006 00003 00002 00006 00008 00002 DTR> 12. (RSTS/E only) At the system command level, delete the data file associated with your domain before you changed the file organization. Using the PROJECTS domain as an example, you would delete the file OLDPRO.DAT. 15.4 Changing the Organization of a Data File You can also use an alias with the READY command to change only the organization of a data file associated with a domain. The following steps make the indexed file created for PROJECTS a sequential file again: 1. (RSTS/E only) At the system command level, rename the data file associated with PROJECTS. The examples in the following steps assume that PROJEC.DAT has been renamed IDXPRJ.DAT. 2. (RSTS/E only) At the DATATRIEVE command level, redefine the PROJECTS domain specifying the renamed data file: DTR> REDEFINE DOMAIN PROJECTS USINGillli) DFN> PROJECTS_REC ON ID}-(PRJ.DAT;illli) DTR> 3. Ready the domain using an alias: DTR:> READY PROJECT S AS I m-(_ PROJECTSillli) DTR > SHm~ READYillli) Read}' dOlllains: lOX_PROJECTS: RMS INDEXED, PROTECTED READ DTR> 15-8 Restructuring Domains 4. (RSTS/E only) Redefine PROJECTS again, using the original name of the data file: DTR> REDEFINE DOMAIN PROJECTS USING(ffi) DFN> PROJECTS_REC ON PROJEC.DATi(ffi) DTR> 5. Define for the domain a data file that has the organization you want. The following example defines a sequential file: DTR> DEFINE FILE FOR PROJECTS(ffi) DTR> 6. Ready the domain for WRITE access using another alias: DTR> READY PROJECTS AS SEQ_PROJECTS WRITE(ffi) DTR> 7. Using a STORE statement in a FOR loop, transfer records from the old domain to the new on~: DT R> FO RID >~ _PRO JE CTS(ffi) [Lookin~ for stateMent] CON> STORE SEQ_PROJECTS USING(ffi) [Lookin~ for assi~nMent stateMent(s)] CON> PROJECTS_REC = PROJECTS_REC(ffi) DTR> 8. Type FINISH. When you ready the domain again, access records in the reorganized file: DTR> FINISH(ffi) DTR> READY PROJECTS(ffi) DTR> SHOW READY(ffi) Readied dOMains: PROJECTS: RMS SEQUENTIALt PROTECTED READ DTR> 9. (RSTS/E only) You may want to print some records to ensure that records were successfully copied to your reorganized file. Then, at the system command level, delete the data file with the organization you no longer want. Using the PROJECTS domain as an example, you would delete IDXPRJ.DAT from your directory. Restructuring Domains 15-9 Using the DATATRIEVE Editor 16 U sing a command file is probably the easiest way to make changes to your DATATRIEVE work. You can edit a command file using the editor you already know from your own operating system, rather than learning a new editor. Chapter 10 explains how to use command files. The rest of this chapter explains how to use the DATATRIEVE Editor. You can use the DATATRIEVE Editor only to modify dictionary objects that are defined in your current data dictionary. You can edit commands and statements only when they are stored as a procedure. Edit with caution, especially when changing record definitions. The DATATRIEVE Editor does not check for syntax errors as you edit dictionary objects. Any errors show up only when you use the modified dictionary object. The changes you make with the DATATRIEVE Editor do not affect domains that you currently have readied in your workspace. For example, if you ready the domain PERSONNEL and then edit its record definition, you are not changing the record definition currently being used by the PERSONNEL domain. For the new record definition to take effect, you must finish the PERSONNEL domain and ready it again. Similarly, edits do not change a dictionary table loaded into your DATATRIEVE workspace until you release the table and refer to it again. 16.1 Invoking the Editor You invoke the DATATRIEVE Editor at the DATATRIEVE command level with the following command: EDIT object-name [(pa~;Wd) ] [ADVANCED] 16-1 Arguments object-name Is the name of the dictionary object in the current data dictionary you want to edit. (passwd) Is an asterisk enclosed in parentheses (*) or the password necessary to gain C (control) access to the dictionary object. If you specify a password, you must enclose it in parentheses. If you specify (*), DATATRIEVE prompts you for the password but does not print the response on your terminal. If you omit this argument, DATATRIEVE uses your login UIC/PPN to verify that you have C (control) access privilege to the dictionary object you want to edit. (*) ADVANCED Must be included in the EDIT command if you want to edit a domain definition or a record definition. When you invoke the DATATRIEVE Editor, it responds with the QED> prompt. 16.2 Editor Modes When you first invoke the Editor, you are at the Editor's command level in edit mode. In this mode, the Editor interprets all your input as commands, and you can display and alter the text of the dictionary object. The QED> prompt indicates that you are in edit mode. The second Editor mode, insert mode, allows you to enter text directly into the dictionary object. You enter insert mode with the INSERT and REPLACE commands and leave it by pressing CTRL/Z. The Editor uses the IN> prompt to indicate that you are in insert mode. In this mode, the Editor interprets all your input as new text to be entered into the dictionary object. 16.3 Line Pointer Some commands move you through the text from one line to another. Other commands display or alter lines at various places in the text but leave the current line unchanged. The Editor uses a line pointer to keep track of the current line. The line pointer points to the entire current line, not to any part of the line. You can display the current line by typing a period (.) and pressing RETURN in response to the QED> prompt. The maximum line size you can edit is 132 characters. The line pointer can also point to the end of the text buffer, where you can add text to the end of the dictionary object. The symbol [EOB] marks the end of the text buffer. 16-2 Using the DATATRIEVE Editor 16.4 Range Specification The Editor commands for deleting, inserting, replacing, and typing lines,' and for substituting strings all contain an optional argument that specifies the range of lines on which the command operates. The range may be a single line, a series of consecutive lines, or a group of nonsequential lines. For a complete listing of all the range specifiers you can use with the DATATRIEVE Editor, refer to the section on the EDIT command in the DATATRIEVE-ll Reference Manual. Table 16-1 shows several examples of these ranges using the TYPE command. TYPE displays specified lines on your terminal, and it searches for specified strings. If you want to display the rest of a dictionary object, the following commands all work: TYPE REST TYPE R REST T R %R Note the percent sign before the R in the last example. The Editor assumes R by itself is the abbreviated form of the REPLACE command. Entering R without the percent sign in response to the QED> prompt does not display the rest of the dictionary object; it deletes the current line and puts you in insert mode. Table 16-1: Examples of Range Specifiers You Type: Editor Displays: TY PE ALL II BEAM" All lines containing the string BEAM. TY PE BEG I N AND END The first line of the dictionary object and the end-of-buffer marker ([EOB]). TYPE BEGIN t "BEAM" The first line of the dictionary object and the first line containing the string "BEAM". If the current line is the first line of the dictionary object and contains the string "BEAM", this command displays the current line twice. TYPE BEFORE All lines before the current line and the current line. TYPE BEGIN The first line of the dictionary object. TYPE END The end-of-buffer marker ([EOB]). TYPE. FOR 5 The current line and the four lines following it. TYPE REST The current line and all remaining lines in the dictionary object. TYPE "BEAM" The next line containing the string "BEAM". If the current line contains "BEAM", the Editor displays the current line. (continued on next page) Using the DATATRIEVE Editor 16-3 Table 16-1: Examples of Range Specifiers (Cont.) You Type: 16.5 Editor Displays: TYPE WH All lines in the dictionary object. TYPE BE+5 The sixth line of the dictionary object. TYPE IIBEAMII+B The sixth line following the next line containing the string "BEAM". If the current line contains the string "BEAM", the Editor displays the sixth line following the current line. TYPE The current line. t Editor Commands Table 16-2 summarizes the DATATRIEVE Editor commands in alphabetical order. The following section contains a sample editing session illustrating some common uses of these commands. Table 16-2: Summary of DATATRIEVE Editor Commands Format Command Function CTRL/Z CTRUZ In edit mode, works like the EXIT command. In insert mode, returns control to edit mode. DELETE D[ELETE] [range] Deletes the specified range or the current line if you omit the range. After deletion, the current line is the line following the last line deleted. EXIT EX[IT] Returns you to DATATRIEVE command level. The edited dictionary object replaces the previous version in the data dictionary. INSERT I[NSERT] [range] Enters insert mode. The Editor inserts lines before the line specified by range or before the current line if you omit the range. CTRLlZ ends insert mode and returns you to the Editor command level. If you omit the range, the current line does not change when you leave insert mode; if you specify a range, the line specified by the range becomes the current line. Do not use ALL, AND, a comma (,), BEFORE, FOR, a semicolon (;), REST, or WHOLE when specifying the range in this command. QUIT QUIT Returns you to DATATRIEVE command level and leaves the dictionary object unchanged by the editing session. REPLACE R[EPLACE] [range] Deletes the specified range or the current line if you omit the range and puts you in insert mode. CTRLlZ ends insert mode and returns you to the Editor command level. The current line is the line following the last line deleted. None of the restrictions on specifying ranges in the INSERT command apply to REPLACE. (continued on next page) 16-4 Using the DATATRIEVE Editor Table 16-2: Summary of DATATRIEVE Editor Commands (Cont.) Command Format Function SUBSTITUTE S/str-1/[str-2][/[range]] Substitutes string 2 for all occurrences of string 1 in the specified range or in the current line if you omit the range. The line in which the last substitution occurred becomes the current line. If you omit the range, you can also omit the third delimiter. If you omit string 2, the Editor deletes the specified string from the range you specify or from the current line if you omit the range. The search for the first occurrence of string 1 starts with the current line and proceeds toward the end of the text buffer. Do not use END to specify the range in this command. TYPE [T[YPE]] [range] Displays the specified range oflines or the line following the current line if you omit the range. The first line displayed becomes the current line, with one exception: if E[ND] plays any part in the range of this command, the line pointer points at the end-of-buffer marker ([EOB]). 16.5.1 DELETE Command Function Deletes one or more lines from the dictionary object. Format O[ELETE] [range] Argument range Specifies the range of lines to be deleted. If you omit the range, only the current line is deleted. Position of Line Pointer Current line is the line following the last line deleted. Examples Delete the current line only: QED> DffiIT) Delete all lines containing the string PHD: QED> D ALL "PHD "ffiIT) Using the DATATRIEVE Editor 16-5 Delete all lines containing the string "PHD" from the current line and the seven lines following it: QED> D PHD II II FOR 7ffiIT) Delete all lines from the beginning of the dictionary object up to and including the current line: QED> D BEFOREffiIT) 16.5.2 EXIT Command Function Ends an editing session, and returns you to DATATRIEVE command level. The edited dictionary object replaces the previous version in the data dictionary. Format EX[IT] CTRUZ Argument None. Position of the Line Pointer Not applicable. Examples End the current editing session with the EXIT command: QED> E}<ffiIT) DTR> End the current editing session with CTRL/Z: QED> DTR> .'. Z 16.5.3 INSERT Command Function Enters insert mode, which allows you to enter text directly into the dictionary object. The inserted lines are added before the line specified in the range or before the current line if you omit the range. Format I[NSERT] [range] 16-6 Using the DATATRIEVE Editor Argument range Is the line or group of lines that will follow the inserted lines. If you omit the range, DATATRIEVE adds the inserted lines before the current line. Position of the Line Pointer If you omit the range, the current line does not change when you leave insert mode. If you specify a range, the line that the range specifies becomes the current line. Notes • When you issue the INSERT command, the Editor prompts with IN> to show that you are in insert mode. • Remember to press RETURN after each line you want to insert. If you enter CTRL/Z after a line, that line is not entered into the procedure or table. In the following example, only the words READY YACHTS are inserted in the dictionary object: QED> I NSERTffiIT) IN> READY YACHTSffiIT) IN> FIND TINIES IN YACHTS WITH LOA < 25 AZ QED> • Do not use the following range specifiers in the INSERT command: - [%]ALL - [%]AND (,) [%]BEFORE - [%]FOR (;) - [%]R[EST] - [%]WH[OLE] • To leave insert mode and return to edit mode, enter CTRL/Z. Examples Insert lines before the current line: QED> IffiIT) IN> READY YACHTSffiIT) IN> IN> QED> PRINT ALL TINIESffiIT) .'. Z Using the DATATRIEVE Editor 16-7 Insert lines before the first line of the dictionary object: OED> I BEGINffiD) IN> READY YACHTSffiD) Insert lines after the last line of the dictionary object: OED> I ENDffiIT) [EOBJ IN> PRINT ALL TINIESffiD) Insert lines before the next line containing the string "BEAM": OED> I IN> BEAM 'ffiD) PRINT ALL TINIES SORTED BY BEAMffiD) I Insert lines between the fourth and fifth lines from the current line: OED> I IN> .+5ffiIT) PRINT BUILDER OF TINIESffiD) 16.5.4 QUIT Command Function Returns you to the DATATRIEVE command level and leaves the dictionary object unchanged by the editing session. Format QUIT Argument None. Position of the Line Pointer Not applicable. Notes· • QUIT aborts an editing session. Any changes made during the session do not affect the dictionary object . • You cannot abbreviate the QUIT command. Example Abort the current editing session: OED> OUITffiD) DTR> 16-8 Using the DATATRIEVE Editor 16.5.5 REPLACE Command Function Deletes the specified range of lines in a dictionary object or deletes the current line if you omit the range and enters insert mode, which allows you to enter text directly into the dictionary object. Format R[EPLACE] [range] Argument range Specifies the range of lines to be deleted. If you omit the range, DATATRIEVE deletes only the current line. Position of the Line Pointer After you leave insert mode, the current line is the line following the last line deleted. If you have inserted lines, the current line is the line after the inserted lines. Notes • W:hen you issue the REPLACE command, the Editor deletes the lines you specify in the range and then prompts with IN> to show that you are in insert mode. • To leave insert mode and return to edit mode, enter CTRL/Z . • The restrictions on specifying ranges in the INSERT command do not apply to REPLACE. Examples Replace the current line with a single line: OED> FIND YACHTS WITH LOA BETWEEN 36 AND 37(BID OED> R(BID IN> FIND YACHTS WITH LOA > 38ffiTI) IN> .'. Z OED> .(BID REPORT CURRENT SORTED BY BEAMt LOAt RIG ON .WHERE Delete the first line of a dictionary object and enter insert mode: OED> R BE(BID IN> Delete all lines containing the string "PRICE" and enter insert mode at the line following the last line deleted: OED> R ALL "PRICE"(BID IN> Using the DATATRIEVE Editor 16-9 Delete all lines in the dictionary object and enter insert mode: QED> R WHOLECBTI) IN> 16.5.6 SUBSTITUTE Command Function Substitutes a character string for all instances of another character string in the specified range or in the current line if you omit the range. Format S[UBSTITUTE] /string-1 /[string-2][/[range]] Arguments string-1 Is the string of characters to be replaced. / Is the delimiter that separates string 1, string 2, and the range. The delimiter can be any printing character not in string 1 or string 2. In any given SUBSTITUTE command, you must use the same character as a delimiter. You need only specify the first two delimiters if you omit the range. string-2 Is the string of characters to replace string 1. If you omit string 2, then string 1 is deleted from the specified line. range Specifies the range of lines within' which DATATRIEVE will make the substitution. If you specify a range, DATATRIEVE replaces all occurrences of string 1 in that range with string 2. If you omit the range, DATATRIEVE replaces only the first occurrence of string 1. That first occurrence of string 1 need not be in the current line. Position of the Line Pointer If a substitution takes place, the current line is the last line in which the substitution occurred. If there is no match for string 1 within the range, or if there is no match for it in the current line or any line from that point to the end of the dictionary object, no substitution takes place. The current line remains unchanged. Notes • The Editor prints each line in which a substitution occurs. • Do not use END to specify the range in this command. • The search for the first occurrence of string 1 starts with the current line and moves toward the end of the text buffer. 16-10 Using the DATATRIEVE Editor Examples Substitute the string YACHT for the first occurrence of the string YAHCT in the current line only: QED> S IYAHCT/YACHTI .ffiTI) Substitute the string YACHT for every occurrence ofYAHCT in the entire dictionaryobject: QED>S *YAHCT*YACHT* WHffiTI) This WHOLE range is in effect regardless of the current line's position in the text buffer. Substitute the string YACHT for the next occurrence ofYAHCT: QED> S IYAHCT/YACHT If there is no occurrence of string 1 between the current line and the end of the text buffer, then DATATRIEVE does not change the current line. Substitute the string YACHT for every occurrence ofYAHCT from the current line to the end of the dictionary object: QED> S "YAHCT" YACHT" RESTffiTI) 16.5.7 TYPE Command Function Displays the specified range of lines or the line following the current line if you omit the range. Format [T[YPE]] [range] Argument range Specifies the range of lines to be displayed. If you omit the range, the Editor displays only the line following the current line. Position of the Line Pointer The first line displayed becomes the current line, with one exception. If the range of this command contains E[ND], the line pointer points to the end-of-buffer marker ([EOB]). Using the DATATRIEVE Editor 16-11 Notes • Both the command name and range are optional. If you press the RETURN key, the Editor prints the line following the current line, which then becomes the current line. You can also enter the range specifiers without the command name . • The TYPE command performs the searches in the DATATRIEVE Editor. You can search for text strings in dictionary objects by enclosing the string you seek in pairs of single or double quotation marks. Examples The following commands all work as alternative ways of displaying lines during an editing session~ Commands for displaying the current line only: QED> TYPE QED> .ffiD) .ffiD) Commands for displaying the next line (the line following the current line): QED> TYPE QED> .+1lliIT) .+1ffiD) QED> Tru QED> ru Commands for displaying the entire dictionary object: QED> T WHlliIT) QED> WHlliIT) Commands for displaying the first and last lines of the dictionary object: QED> T BEGIN tENDlliIT) QED> BEGIN tENDru QED> BE AND ElliIT) Commands for displaying all lines from the current line to the end of the dictionaryobject: QED> T RESTru QED> RESTffiD) QED> I..Rru 16-12 Using the DATATRIEVE Editor 16.6 Sample Editing Session DTR> ED I T CTRLffiIT) OED> WHffiIT) READY YACHTS FIND YACHTS WITH LOA BETWEEN 36 AND 37 REPORT CURRENT SORTED BY BEAM, LOA, RIG ON .WHERE SET REPORT-NAME = "YACHTS WITH LENGTH-OI.IER-ALL"1 "OF 36 AND 37 FEET" AT TOP OF BEAM PRINT COL 1, "BEAM = ", COL 7, BEAM AT TOP OF LOA PRINT COL 12, "LENGTH = ", COL 20, LOA, SKIP PRINT BUILDER, RIG, DISP AT BOTTOM OF RIG PRINT SKIP, COL 4, "NUMBER OF ", COL 14, LOA (" "), COL 1 7 t "FOOT ", COL 22, RIG t COL 28, "W I TH BEAM OF ", COL 40 t BEAM, COL 43, " = ", COL 46, COUNT USING ZSt SKIP AT BOTTOM OF REPORT PRINT SKIP, "LIGHTEST = ", MIN (DISP), SKIP, "HEA1.lIEST = ", MA}{ (DISP), SKIP t "AI.IERAGE WEIGHT OF ALL BOATS = ", AI.IERAGE (DISP) SET DATE = "DD-MMM-YY" SET COLUMNS-PAGE = 60 END-REPORT OED> .ffiIT) READY YACHTS OED> ffiIT) FIND YACHTS WITH LOA BETWEEN 36 AND 37 OED> RffiIT) FIND YACHTS WITH LOA > 38ffiIT) IN> .'."7 i... IN> OED> .ffiIT) REPORT CURRENT SORTED BY BEAM, LOA, RIG ON .WHERE OED> S/ON • WHERE/ffiIT) REPORT CURRENT SORTED BY BEAM, LOA, RIG OED> ffiIT) SET REPORT-NAME = "YACHTS WITH LENGTH-OI.IER-ALL"1 OED> ffiIT) "OF 36 AND 37 FEET" OED> RffiIT) IN> "GREATER THAN 38 FEET "ffiIT) IN> .'. Z OED> .ffiIT) AT TOP OF BEAM PRINT COL 1, "BEAM = ", COL 7 t BEAM OED> ALL "AT BOTTOM"ffiIT) AT BOTTOM OF RIG PRINT SKIP, COL 4, "NUMBER OF ", COL 14 t AT BOTTOM OF REPORT PRINT SKIP, "LIGHTEST =" MIN (DISP), OED> .ffiIT) AT BOTTOM OF RIG PRINT SKIP t COL 4, "NUMBER OF ", COL 14, OED> "BOTTOM "ffiIT) AT BOTTOM OF RIG PR I NT SK I p, COL 4, "NUMBER OF ", COL 1 4 t OED> ffiIT) LOA (" "), COL 1 7 t "FOOT ", COL 22, RIG t COL 28, OED> "BOTTOM" ffiIT) AT BOTTOM OF REPORT PRINT SKIPt "LIGHTEST MIN (DISP) t OED> • ;3ffiIT) AT BOTTOM OF REPORT PRINT SKIP, "LIGHTEST ,MIN (DISP), SKIP t "HEA1.lIEST = ", MA}-( (DISP), SKIP, "AI.IERAGE WE I GHT OF ALL BOATS = ", A1.lERAGE (D I SP) OED> .ffiIT) AT BOTTOM OF REPORT PRINT SKIP, "LIGHTEST = "t MIN (DISP) t OED> D • ;3ffiIT) OED> .ffiIT) SET DATE "DD-MMM-YY" (continued on next page) Using the DATATRIEVE Editor 16-13 OED> Iru IN> SET MA}-( - PAGES = LlOru IN> .'. Z OED> .ru SET DATE = IIDD-MMM-yylI OED> ru SET COLUMNS-PAGE = GO OED> ru END-REPORT OED> ru [EOBJ OED> BEru READY YACHTS OED> S/RIG/PRICE/WHru REPORT CURRENT SORTED BY BEAM. LOA. PRICE PRINT BUILDER. PRICE. DISP AT BOTTOM OF PRICE PRINT SKIP. COL Ll. IINUMBER OF II. COL 1Ll. LOA (II II). COL 17. II FOOT II. COL 22. PR I CE. COL 28. OED> WHru READY YACHTS FIND YACHTS WITH LOA > 38 REPORT CURRENT SORTED BY BEAM. LOA. PRICE SET REPORT_NAME = II YACHTS WITH LENGTH_OI.1ER_ALL II I IIGREATER THAN 38 FEETII AT TOP OF BEAM PRINT COL 1. "BEAM = ". COL 7. BEAM AT TOP OF LOA PRINT COL 12. "LENGTH = ". COL 20. LOA. SKIP PRINT BUILDER. PRICE. DISP AT BOTTOM OF PRICE PRINT SKIP. COL Ll. "NUMBER OF ". COL 1Ll. LOA (" "). COL 1 7. "FOOT ". COL 22. PR I CE. COL 28. "WITH BEAM OF ". COL LlO. BEAM. COL Ll3. " = ". COL LlG. COUNT USING Z9. SKIP SET MAX_PAGES = LlO SET DATE = "DD-MMM-YY" SET COLUMNS_PAGE = GO END_REPORT OED > E>~ru DTR> 16-14 Using the DATATRIEVE Editor Optimizing Workspace and Response Time 17 This chapter explains the concept ofDATATRIEVE workspace. It shows you how to use memory space efficiently during a DATATRIEVE session and suggests ways to optimize DATATRIEVE performance. 17.1 Using Workspace Your DATATRIEVE workspace is the area in physical memory that is available to you during your DATATRIEVE session. Sometimes referred to as "pool space," the workspace is not the same as disk space. Workspace refers instead to the size of the current DATATRIEVE task you are performing. The maximum workspace allowed for each DATATRIEVE session is 32K words. If the task you perform requires DATATRIEVE to use more than 32K words of memory, you receive an error message, such as "Compiler storage pool exhausted," and are unable to complete your task. 17.2 Effect of READY and FINISH on Workspace Before you ready any domains, the workspace looks like that in Figure 17-1. All the workspace is available, some of it for carrying out tasks related to Record Management Services (RMS), some for tasks related to DATATRIEVE domains, and some for sorting the records as you issue DATATRIEVE commands and statements. 17-1 RMS WORKSPACE ----------------------------------------------------SORT WORKSPACE ----------------------------------------------------SMALL BLOCK WORKSPACE Figure 17-1: Empty DATATRIEVE Workspace The dashed lines indicate temporary boundaries. DATATRIEVE takes space from the sort workspace and allocates it to the RMS workspace and the small block workspace when they need more space. A readied domain uses space in both the RMS workspace and the small block workspace. Collections, variables, and tables all use space in the small block workspace. If you use the SHOWSPACE command, you see that the proportions of space used are comparable to those in the diagram. The numbers you see for your system will not be identical with those in the following example: DTR> SHOW SPACEffiD) RMS pool Slrlall blod, pool Sort pool Total ***Current MelrlO f)' Usage*** Allocated Used F re e 4148 4384 236 312 312 0 0 14024 14024 4460 14260 18720 "* of Frag'rlents 3 0 0 3 When using the SHOW SPACE command, pay particular attention to the total used space and the total free space. As you take up more workspace, the used space increases and free space decreases. When you ready a domain, you begin to use up the available workspace, as shown in Figure 17-2. 17-2 Optimizing Workspace and Response Time YACHTS BUFFERS ----------------------------------------------------FREE SORT WORKSPACE ~---------------------------------------------------YACHTS BLOCKS Figure 17-2: Workspace with One Readied Domain If you type SHOW SPACE, you can see how the values change for current use of memory: DTR> READY YACHTSffiIT) DTR> SHOW S PACE(8li) ***Current MeMOry Usa~e*** Allocated Used Free RMS pool SITlall blod~ pool Sort pool Total 4384 2300 12038 18720 4282 1588 0 5880 220 712 12038 12840 :1:1: of Fra~ITlents 1 15 o 18 If you ready a second domain, you use additional space as shown in Figure 17-3. YACHTS BUFFERS ~---------------------------------------------------PERSONNEL BUFFERS ~---------------------------------------------------FREE SORT WORKSPACE ~---------------------------------------------------PERSONNEL BLOCKS ~---------------------------------------------------YACHTS BLOCKS Figure 17-3: Workspace with Two Readied Domains Type SHOW SPACE to see values for current memory use after readying two domains: DTR> READY PERSONNELffiIT) DTR> SHOW SPACE(8li) Optimizing Workspace and Response Time 17-3 RMS pool Sill a 11 b 1 od, pool So rt pool Total ***Current Meillo f)' Usage*** Allocated Used F re e a8aa a388 220 2656 3a16 760 10360 0 10360 18720 70aa 11676 # of Fragillents 5 21 0 26 If you finish a domain, you free the workspace that the domain was occupying. The sort workspace recovers free space only if the free space is adjacent to the sort workspace. If you free space in the interior of the RMS workspace or small block workspace, then it remains in that workspace as a fragment, as shown in Figure 17-4. FREE RMS WORKSPACE ~---------------------------------------------------PERSONNEL BUFFERS ~---------------------------------------------------FREE SORT WORKSPACE ~---------------------------------------------------PERSONNEL BLOCKS ----------------------------------------------------FREE SMALL BLOCK WORKSPACE Figure 17-4: Workspace When You Finish First Readied Domain The following SHOW SPACE command illustrates that releasing the first readied domain does not increase the amount of free sort workspace: DTR> FINISH YACHTSCffi) DTR> SHOW SPACECffi) ***Current MeMOry Usage*** Allocated Used Free RMS pool a8aa azaa 700 Sill a 1 1 blod, pool 3a16 1380 2036 Sort pool 10360 0 10360 Total 18720 562a 13086 DTR> # of Fragillents 5 12 o 17 You use the sort workspace each time you specify the order of a record stream with the SORTED BY clause in an RSE or a collection with the SORT statement. DATATRIEVE immediately seizes space from the sort workspace and releases it when it finishes the sort. DATATRIEVE sorts slowly when it has little space to work with, so keeping the sort workspace as large as possible saves computing time. If the sort workspace is too small, DATATRIEVE returns the message: Sort worKspace exhausted Execution failed 17-4 Optimizing Workspace and Response Time 17.3 Techniques to Optimize Workspace The following techniques for readying and finishing domains can help you optimize your workspace: • Try to reduce the number of files you have open at a time. If you no longer need a domain, FINISH it. • Pay attention to the order in which you open the files. As the illustrations show, when you finish a domain you do not always free a complete, contiguous block of workspace. If you finish the first domain before you finish the second, your workspace looks like that in Figure 17-4. It is best, therefore, first to ready the domains you plan to use the longest and then ready and finish those you need for only a short time. You can save space in the way you define your records too. Each time you define a field, you add overhead cost in addition to the size of the item being stored. EDIT-STRINGS, QUERY-HEADERS, and QUERY-NAMES also add to the storage space your record requires. Use the following guidelines when defining your record: • Keep record definition clauses short, in particular EDIT-STRINGS, QUERYHEADERS, and QUERY-NAMES. Do not use any of these clauses unnecessarily. • Use short names and eliminate unnecessary fields. Unnecessary group fields are a particular waste of space. • When you use FILLER, try to combine two or more elementary fields into one FILLER field. There are also other techniques you can use to save space: • Release collections, tables, and variables that you do not need. • Avoid using long BEGIN-END blocks, and the THEN connector to form compound statements. DATATRIEVE compiles the complete statement all at once, at the cost of workspace. • Use a small file bucket size. The file bucket size determines the size of the RMS buffers needed. A bucket size of 8 would use approximately half of DATATRIEVE workspace and would cause you to run out of space repeatedly. A bucket size of 1 or 2 reduces the requirements for DATATRIEVE workspace. • For the REPORT statement, first use the FIND statement to form a collection and the SORT statement to sort and then report on the sorted collection. Avoid including the SORTED BY clause in the REPORT statement. The REPORT and SORT statements both require large amounts of workspace. Optimizing Workspace and Response Time 17-5 17.4 Techniques to Optimize Response Time As mentioned earlier, DATATRIEVE performs best when it has adequate space to work with. Therefore, when you keep the sort pool in your workspace as large as possible, you improve response time. The following sections suggest other ways you can improve DATATRIEVE performance. 17.4.1 Using the ALLOCATION Option of the DEFINE FILE Command If you know approximately how many blocks of storage your data file will require and you want to enter records quickly, you can use the ALLOCATION option in the DEFINE FILE command to reserve contiguous storage space for the file. This option is particularly useful if you know your data file will be large. The format for the ALLOCATION option is ALLOCATION = n, where n is the number of blocks you want as the initial allocation for the file. 17.4.2 Using Keyed Access Efficiently DATATRIEVE allows you to define indexed or sequential files for your data. Sequential files require less storage, but DATATRIEVE must search records one by one according to their physical order in the file. This organization may be optimal in certain cases. For example, a domain's records may contain a field for the current date, so you may want records physically arranged in the order in which you stored them. For instance, you are likely to want to have sequential access to banking transactions. If you access groups of records in chronological order, you might find sequential organization efficient. In other cases, your access needs may not be suited to sequential organization. You may need to access a group of records that are distributed throughout the file. If you have stored the records in a sequential file, DATATRIEVE may have to read all the records to find the one or two that you request. In this case, indexed file organization is probably a better choice. Although indexed files require more storage, DATATRIEVE can search indexed files quickly to find the records you want, if you base the search on a key field. When defining data, try to decide which field of the record you are likely to name most often in queries. Make that field the primary key if its value is likely to be unique for each record. For example, if you are setting up a personnel domain, you might predict that most users seek information based on employee ID. In that case, make the ID field the primary key. By default, primary key values are unique. That is, the primary key value by itself is enough to identify a record. It is legal in DATATRIEVE to specify that primary keys can have duplicate values. However, allowing duplicate primary key values is not recommended; having too many duplicate key values slows DATATRIEVE searches based on key fields. 17-6 Optimizing Workspace and Response Time If the leading candidate for the primary key does not uniquely identify the record, find another field such that the two fields combined can uniquely identify the record. You can then designate a group field, encompassing the two fields, as the primary key. For example, in the YACHTS domain, the group field TYPE (consisting of BUILDER and MODEL) is the primary key, uniquely determining records in YACHTS. After organizing your indexed file and storing records in the file, you should structure DATATRIEVE queries to take advantage of keyed access. A query is a request for DATATRIEVE to identify all the records that satisfy a specified condition. Not all the DATATRIEVE queries you can formulate use keyed access to indexed files. The following sections tell you how to produce queries that give you the fastest response time. Avoid using a field defined as USAGE IS DATE as a key field. The value stored in a date field is larger than the maximum value allowed for a key by RMS. Therefore, specifying a date field as a key provides no response time advantage when you base a query on a comparison of the field value and the range of values (for example, LT, GT, LE, GE, and BETWEEN). If you base your query of an indexed data field on an equality comparison, DATATRIEVE uses the index and performs faster than ifit did a sequential search of the records. 17.4.2.1 Using EQUAL Rather Than CONTAINING - A Boolean expression that tests records with the EQUAL (=) relational operator is more efficient than a Boolean with CONTAINING (CaNT) when the expression refers to a key field. For example, compare these two queries: DTR> PRINT YACHTS WITH BUILDER = IPEARSON"CBTIl DTR> PRINT YACHTS WITH BUILDER CONT IPEARSON"CBTIl Although both queries yield the same results, the first query is twice as fast as the second one. To resolve the first query, DATATRIEVE conducts a fast search through the index to retrieve the desired records. In the second case, DATATRIEVE must search through the values of BUILDER looking for matches with the string following CaNT. DATATRIEVE must check all substrings of each BUILDER value that are equal in length to the string specified in the Boolean. To take advantage of the increased efficiency of EQUAL (=), you must specify a value that matches the field value exactly. EQUAL (=) is case sensitive but CaNT is not. In the last example, if a record had the value "Pearson" for BUILDER, only the second query would find the record. To get around the problem of case sensitivity, you might consider using only uppercase letters when entering data. Otherwise, to use the EQUAL operator, you must remember the case of each character of a field value. Optimizing Workspace and Response Time 17-7 17.4.2.2 Choosing Domains or Collections as Record Sources - When you form a collection, DATATRIEVE can no longer use key-based access for retrieving records. In most cases, you get the best performance on key-based queries when you specify a domain rather than a collection in the RSE. Furthermore, if you form a query that relates to more than one record source, all but the last source specified is an implied collection. Therefore, you cannot have key-based access for any but the last record source in a relational query. When you use nested FOR loops and specify domains and key fields in each loop, for example, DATATRIEVE can use a key-based index only for evaluating the RSE in the last FOR loop. If all other conditions are equal, it is better to use a domain name than a collection name in the last position of a key-based relational query. But there is one more factor to consider. Collections are efficient to use if you need to refer back to the same group of records in the same DATATRIEVE session. This is especially true if the collection is much smaller than the data file from which it is formed. In such a case, you may get better performance by forming and naming a collection so that DATATRIEVE does not have to retrieve the same group of records over and over again. To summarize, you gain efficiency with a domain when you can use keyed access. You gain efficiency with a collection if you reduce the number of times DATATRIEVE must isolate the same small group of records from a large body of records. 17.4.2.3 Ordering the Domains in Nested FOR Loops - If one FOR loop must process many more records than the others and all have the same key field, include the larger record stream in the last (inner) FOR loop. Similarly, if only one FOR loop can use keyed access, make sure that FOR loop is the last, or innermost, loop you specify. 17.4.2.4 Restoring Indexed Files That Are Often Modified - If you add, erase, or change many records in an indexed file, that file can degrade DATATRIEVE performance. When you have erased many records from an indexed file, records in the file can occupy many noncontiguous areas of the disk. This slows down record access. When you add records to a file or change many values in key fields, the index for the file can be split over many noncontiguous areas of the disk. This also slows down record access. The more keys you define for each file, the more quickly DATATRIEVE response time degrades when you make many changes to the file. If you have a DATATRIEVE performance problem and you have made many modifications to your indexed file, restructuring your domain might improve DATATRIEVE response time. When you restructure a domain, you are recreating the data file. When the new file is created, the records and index are stored as much as possible on contiguous areas of the disk. 17-8 Optimizing Workspace and Response Time Follow the same steps given in Chapter 15 for reorganizing a data file. In this case, however, specify the same organization for your new file rather than a different one. If you have defined many different keys for your file, you might want to eliminate any keys that you seldom use in queries. If you define as keys only those fields that you often use in queries, modifying your file has less effect on DATATRIEVE response time. You can also restructure files and indexes using the RMS-11 utilities CONVERT and IFL. These utilities are explained in the RMS-11 manuals in your operating system documentation set. The DATATRIEVE-11 utility program QCPRS, explained in Chapter 20 of this manual, can be used to restructure files and indexes. 17.4.3 Avoiding Nested FOR Loops Followed by a Conditional Statement Try to avoid using nested FOR loops to control the execution of a conditional statement. The following example is extremely inefficient: DTR> FOR A IN OWNERSru CON> FOR YACHTSru CON> IF TYPE = A.TYPEffiIT) CON> THEN PRINT BOAT, A.NAMEru Wherever possible, include conditional tests as Boolean expressions within one of the RSEs. This effectively limits the number of records that DATATRIEVE has to process. The following example works much more efficiently than the pre~ ceding one: DTR> FOR A IN OWNERSru CON> FOR YACHTS WITH TYPE CON> PRINT BOAT, A.NAMEffiIT) A.TYPEffiIT) Optimizing Workspace and Response Time 17-9 Controlling Output 18 When you invoke DATATRIEVE, several characteristics are set that control your display of input and output: • The number of columns in an output display (COLUMNS_PAGE) o The way DATATRIEVE responds to an ABORT statement ([NO] ABORT) o The presence or absence of Looking for ... prompts ([NO] PROMPT) You can change these characteristics at any time during a DATATRIEVE session by using the forms of the SET command discussed in the following sections. 18.1 Changing the Columns-Page Setting The default for the columns-page setting is 80 characters, the width of most video display screens. You can change this setting to fit your application and terminal characteristics. 18.1.1 Increasing the Columns-Page Setting You may want to increase the columns-page setting on your video diplay terminal or hardcopy terminal if you want to display detail lines more than 80 characters long. If you have a VT100-family or VT200-family terminal and your command language is DCL, do the following: 1. Use the DCL SET TERMINAL command to tell your system to increase the width of lines it can send you: $ SET TERMINAL/WIDTH=132@] 18-1 Use the SET COLUMNS_PAGE command to increase the length of the line DATATRIEVE can display on your terminal. The maximum limit on the columns-page setting is 255. DTR> SET CDLUMNS_PAGE = 132ru Whatever the column setting on your terminal, you can continue a long input line by using a hyphen (-) continuation character at the end of the line. When you use a hyphen, DATATRIEVE does not check the syntax of your input until you press RETURN after a line that does not end in a hyphen. If the line you want to extend ends with a complete word, separate the hyphen from the word by entering a space. Otherwise, DATATRIEVE considers the characters at the beginning of the next line to be part of the same character string. 18.1.2 Decreasing the COlumns-Page Setting To decrease the number of columns displayed, enter a SET COLUMNS_PAGE command: DTR> SET COLUMNS_PAGE = GOru DTR> Decreasing the columns-page setting may cause problems when you display your output, however. If one of the elements in a print line is longer than the columnspage setting, DATATRIEVE displays an error message: DTR> SET COLUMNS_PAGE = lSru DTR> PRINT "123aSG7S80123aSG"ru Print object too large for line width DTR> Notice that the columns-page setting does not affect the length of your input lines or the messages you receive from DATATRIEVE. Reducing the columns-page setting can also distort the display of a record as in the following example: DTR> READY YACHTSru DTR> PRINT FIRST 1 YACHTSru MANUFACTURER ALBERG MODEL RIG LENGTH OI.IER ALL WEIGHT BEAM 37 MK I I KETCH 37 PRICE 20,000 $3G,8S1 12 DTR> SET COLUMNS-PAGE 12ru DTR> PRINT FIRST 1 YACHTSru (continued on next page) 18-2 Controlling Output MANUFACTURER ALBERG 37 MK II KETCH 37 20,000 $36,951 12 DTR> 18.1.3 Determining the Number of Columns You Need for a Print Line Several considerations determine the number of spaces, or columns, needed for each print object in the output line: • The actual length of the character string literal or numeric literal, or the length of the field or variable as specified by the record definition or the DECLARE command • The length of the field name, query name, query header, or longest segment of the query header • The length of the edit string The longest of these determines how many columns you need. To prevent crowding, DATATRIEVE also adds one space to the length of all fields except the last one on a line. To print a record from the YACHTS domain requires a minimum of 57 columns: • MANUFACTURER takes 13 columns; the query-header is 12 characters long. • MODEL takes 11 columns; the field is defined as 10 characters long: PIC X(10). • RIG takes 7 columns; the field is defined as 6 characters long: PIC X(6). • LENGTH_OVER-ALL takes 7 columns; the longest segment of the query header (LENGTH) is 6 characters long . •. DISPLACEMENT takes 7 columns; both the query header (WEIGHT) and the edit string (ZZ,ZZ9) are 6 characters long. • BEAM takes 5 columns; the query header (BEAM) is 4 characters long. • PRICE takes 7 columns; the edit string ($$$,$$$) is 7 characters long, but no column is added because PRICE is the last field in the detail line. Controlling Output 18-3 If you set the columns to 56, the PRICE field no longer fits on one line. DATATRIEVE displays the price on the following line and omits the PRICE header: OTR> SET COLUMNS_PAGE = 56Cffi) OTR> PRINT FIRST 1 YACHTSCffi) MANUFACTURER ALBERG $36,851 MOOEL RIG LENGTH OI.IER ALL WEIGHT BEAM 37 MK II KETCH 37 20,000 12 OTR> 18.2 Using the SET ABORT Statement When DATATRIEVE executes an ABORT statement in a command file or procedure while SET NO ABORT is in effect, it affects only the compound statement containing the ABORT statement. If SET ABORT is in effect, DATATRIEVE terminates the remainder of the command file or procedure. The same rules apply if you enter CTRL/Z in response to a prompt. IfDATATRIEVE encounters a syntax or logical error in a command file or procedure, it returns you to the DTR> prompt whether or not you have used SET ABORT. SET NO ABORT is the default setting when you invoke DATATRIEVE. See Chapters 9 and 10 for a discussion of using ABORT and NO ABORT in controlling procedures and command files. 18.3 Using the SET PROMPT Statement When you invoke DATATRIEVE, SET PROMPT is in effect. If you press RETURN before finishing a command or statement, DATATRIEVE prompts you for the remaining required elements of that command or statement. The following sequence of commands and statements shows how DATATRIEVE responds when SET PROMPT is in effect. After the line of text indicates the next required element, DATATRIEVE displays the CON> (continuation) prompt. As long as the syntax of a command or statement is incomplete, DATATRIEVE uses CON> to tell you it is ready for further input. OTR> REAOYlliITl [LooKin~ for Oictionary EleMent] CON> YACHTSlliITl OTR> FINOm II , dOfrlain nafrle, or collection nafrle] [Loo~\in~ for IIFIRST CON> FIRSTm [LooKin~ for a value expression] CON> 1m [Loo~\in~ for col.lection or dOfrlain nafrle] CON> YACHTSm [1 Record found] OTR> 18-4 Controlling Output ) Notice that DATATRIEVE stops prompting as soon as you enter elements that comprise a syntactically complete command or statement. For example, READY YACHTS is complete, and DATATRIEVE does not prompt for any further element. Similarly, when you enter FIND FIRST 1 YACHTS, DATATRIEVE does not prompt you for a Boolean expression or a SORTED BY clause. When SET NO PROMPT is in effect, DATATRIEVE does not display the text about the next required element. It does, however, use the CON> prompt when the syntax is incomplete. The following example is identical to the previous one but has SET NO PROMPT in effect: DTR> SET NO PROMPTOO DTR> FINDOO CON> FIRSTOO CON> 100 CON> YACHTSOO [1 Record found] DTR> Note that SET NO PROMPT does not suppress the messages DATATRIEVE displays about the results of commands and statements. Controlling Output 18-5 ) Controlling Access to Dictionary Objects 19 To supplement your operating system protection, DATATRIEVE uses access controllists (ACLs) to protect your data and dictionary definitions. An ACL, stored in the data dictionary, regulates user access to an object in the data dictionary. Every dictionary object (domain, record, procedure, and table) has an associated ACL. This chapter describes the contents of an ACL and the commands you use to maintain the ACL. It also shows a strategy to help ensure the integrity of your data. Carefully maintained ACLs can be effective against unauthorized browsing through files and accidental corruption of the dictionary or data. Use them to augment the overall security system for your installation. 19.1 Contents of an Access Control List An ACL consists of one or more entries. Each entry contains the following information: • A sequence number • A lock type • A key • One or more access privileges Figure 19-1 shows a sample ACL containing three entries that illustrate the parts and options in an ACL. The table within Figure 19-1 identifies the parts of each entry. 19-1 DTR> SHOWP SAMPLECBTI) 1 ,UIC, [25a ,203], "RWEMC" 2 ,PW, "SWORDFISH", "RM" 3 ,UIC, [* ,*], "RE" Lad, Ke}' Privileges UIC [25a,203] RWEMC 2 PW SWORDFISH RM 3 UIC [* ,*] RE Se9uence NUITlbe r Figure 19-1: Sample Access Control List 19.1.1 Sequence Numbers Sequence numbers are sequential integers beginning with 1 that DATATRIEVE assigns to identify ACL entries. Use sequence numbers to identify entries you are adding to or deleting from the ACL. 19.1.2 Lock Types Each entry in the ACL has a lock type that indicates whether you access the associated dictionary object by specifying a password or by using a UIC/PPN. There are two lock types: PW, for password, and UIC, for UIC/PPN. (A UIC/PPN represents an operating system account number.) 19.1.3 Keys DATATRIEVE uses keys to identify you when you request access to dictionary objects. When you attempt to access a dictionary object, you must provide the correct password for a PW lock or own the correct UIC/PPN for a UIC lock. If the lock type is PW, the key is a 1- to 10-character password. You can use any character from the ASCII character set except the dollar sign ($). Examples of legal passwords include: FISH-FRY, SWORDFISH, 1234, and PASSWD-9. 19.1.3.1 Password Keys - To execute a command or statement that requires access privileges protected by a password, you include the password directly in the command or statement. For example, the domain YACHTS might contain only one ACL entry: PW SWORDFISH RWEMC To delete the YACHTS domain definition from the dictionary, you can specify the password enclosed in parentheses in the DELETE command: DTR> DELETE YACHTS (SWORDFISH);CBTI) 19-2 Controlling Access to Dictionary Objects ) For security reasons, you can also suppress the display of the password on your terminal. To do this, type an asterisk enclosed in parentheses ((*» instead of the password. DATATRIEVE then prompts for the password but does not display the password when you enter it: DTR> DELETE YACHTS (*);ffiill Enter password for YACHTS: This technique for specifying a password is especially useful if you have a hardcopy terminal. 19.1.3.2 UIC Keys - If the lock type is UIe (for UIC/PPN), the key is an account number known to the operating system. Under RSTS/E systems, an account number is called a project-programmer number, or PPN. Under other operating systems, the account number is called the user identification code, or UIC. The UIC/PPN consists of a 3-digit octal group number followed by a 3-digit octal user number. The numbers are separated by a comma and enclosed in brackets, for example [253,201]. A UIC/PPN lock can include specific numbers, asterisks, or a combination of an asterisk and a number. Asterisks allow all users or only users in a specified group to access a dictionary object. The following are valid ACL lock entries: o [253,201], allowing only the user with the account number [253,201] to have access • [253,*], allowing any user with group number 253 to have access • [*,*], allowing any user to have access For the UIC lock type, you do not include a UIC or PPN in a command or statement. Rather, DATATRIEVE verifies that you have access by checking the UIC/PPN you used to log in. For example, if the ACL for the procedure BIGYACHTS contains just the following entry, then you must log in under [253,201] in order to access the procedure: UIC [253,201] RWEMC If the ACL contains the following entry, you can access the procedure regardless of your UIC/PPN: UIC RWEMC Because you cannot use a password when invoking a procedure, you may want to use the UIC/PPN lock type to protect procedures. ----------------------- Note ------------------------ On RSX and VAX-II RSX systems, a VIC must be in the range of [0,0] to [377,377]. On RSTS systems, a UIC must be in the range of [0,0] to [256,256]. Controlling Access to Dictionary Objects 19-3 19.1.4 Access Privileges An access privilege determines the access you have to the associated dictionary object. You designate an access privilege by a single letter, a string of letters, or a space. Table 19-1 contains a list of access privileges and their description. Table 19-1: Access Privileges Description Access Privilege R READ. The user can SHOW or EXTRACT the associated dictionary object. For a domain, the user can ready the domain for READ access only. W WRITE. The user can ready the domain for READ, EXTEND, MODIFY, or WRITE access to retrieve, modify, store, or erase records. E EXTEND or EXECUTE. For a domain, the user can ready the domain for EXTEND access only to store records. For a procedure, the user can execute the procedure. For a table, the user can refer to the table (using VIA or IN clauses). The user must have E access to a record to ready the associated domain. M MODIFY. The user can ready the domain for READ or MODIFY access to read or change records in the domain but not to add or delete. C CONTROL. The user can issue the commands DEFINEP, DELETE, REDEFINE, DELETEP, EDIT, and SHOWP. Space(s) No access. The user cannot access the dictionary object. Each entry in an ACL can include from one to five access privileges or designate no access. A space indicates that no access is permitted to a user with the corresponding key. For example, the single letter R specifies that a user with the corresponding key has read access only. The letters RW specify that the user has both read and write access. Full access, designated by RWEMC, allows a user complete access to the dictionary object. If you specify a space, the user has no access to the dictionary object. Each access privilege allows you to issue certain commands and statements. For example, with R privilege, you can issue an EXTRACT command or ready a domain for read access. If you ready a domain to READ, you can then use commands and statements that display and manipulate the domain database. With only R privilege, you cannot ready a domain to WRITE, MODIFY, or EXTEND. Therefore, you cannot add to, delete, or modify data. Table 19-2 contains a list of commands that you can issue if you are granted the corresponding access privilege. The table also shows the statements you can use after issuing the command. 19-4 Controlling Access to Dictionary Objects Table 19-2: Commands/Statements by Privilege ) Privilege for Domain R Commands Permitted Query Statements Permitted EXTRACT READY. .. READ FIND PRINT SELECT SORT SUM SHOW E READY. .. EXTEND STORE M READY... READ FIND PRINT SELECT SORT SUM READY... EXTEND STORE READY. .. MODIFY FIND MODIFY PRINT SELECT SORT SUM READY... READ FIND PRINT SELECT SORT SUM READY. .. EXTEND STORE READY... MODIFY FIND MODIFY PRINT SELECT SORT SUM READY. .. WRITE ERASE FIND MODIFY PRINT SELECT SORT STORE SUM W (continued on next page) Controlling Access to Dictionary Objects 19-5 Table 19-2: Commands/Statements by Privilege (Cont.) Privilege for Domain C Commands Permitted Query Statements Permitted DEFINEP - DELETE - REDEFINE - DELETEP - EDIT - SHOWP - ----------------------- Note ----------------------- You must have E access to the associated record definition to ready a domain. The meaning ofE privilege differs depending on the dictionary object to which an ACL corresponds. In an ACL for a domain, E means extend privilege; that is, the user can store records in a file or extend it. In an ACL for a table, procedure, or record definition, E means execute privilege. The user can use a table or procedure, or ready the domain associated with the record definition. Only users with C (control) access to a dictionary object can directly access its associated ACL or edit or delete the dictionary object. However, any user with a group (or project) code of 1 (that is, a UIC/PPN in the form [1,n]) is automatically granted C (control) access to all ACLs. 19.2 Creating Access Control Lists When you define a dictionary object, DATATRIEVE automatically creates an ACL for that object. The ACL initially contains only one entry, a UIC/PPN that is granted full access privileges to the dictionary object. The specific UIC/PPN stored in the ACL is installation-dependent and is determined when the DATATRIEVE software is installed. The entry can be in one of the following formats: [m,n] Full access privileges are granted to any user with the same UIC/PPN as the creator of the dictionary definition. For example, if you log in under [253,201] and create a procedure definition, then an entry for [253,201] is stored in the access control list for the procedure. Only users with a UIC/PPN of [253,201J can access the procedure. 19-6 Controlling Access to Dictionary Objects [m,*] Full access privileges are granted to any user with the same group (or project) code (m) as the creator of the definition. For example, if you log in under [253,201] and create a procedure definition, then an entry for [253, *] is stored in the access control list for the procedure. Any user with a group (or project) code of253 (such as [253,222]) also has full access privileges to the procedure. [*,*] All DATATRIEVE users, regardless of their UIC/PPN, are granted full access to the dictionary object. Regardless of the default UIC/PPN stored in the ACL, the creator of the definition always has full access privileges (RWEMC) to the dictionary object at the time he or she creates the definition. If you have C access to a dictionary object, you can grant privileges to additional users or further restrict the use of the dictionary object by changing its ACL. The commands you use to change the table are summarized later in this chapter and described fully in Chapter 5 oftheDATATRIEVE-ll Reference Manual. 19.3 Processing Access Control Lists in DATATRIEVE DATATRIEVE checks the appropriate access control list to verify that you have access privilege whenever you use a table, invoke a procedure, or issue one of the following commands: • DEFINEP • DELETE • DELETEP • EDIT • EXTRACT • READY • REDEFINE • SHOW • SHOWP Controlling Access to Dictionary Objects 19-7 To verify that you have the correct access privilege, DATATRIEVE searches the ACL, checking each entry until it finds a match between the ACL key and your UIC/PPN or between the password you supply and one in the ACL. DATATRIEVE searches the table in the following sequence: 1. DATATRIEVE stores your UIC/PPN and determines if you are a privileged user. A privileged user is one with a group (or project) code of 1 (that is, a UIC/PPN in the form [1,n]). At a minimum, DATATRIEVE grants a privileged user C (control) access. It may grant additional privileges, depending on the results of the following steps. 2. DATATRIEVE checks the first entry in the access control list. If the lock type is PW, DATATRIEVE checks to see if you specified a password in the command. If you did and the password matches the entry's key, DATATRIEVE stops searching the access control list and grants you the privilege or privileges listed in the entry. If the password does not match or you did not specify a password, DATATRIEVE performs the next step. If the lock type is UIC, DATATRIEVE checks to see if your UIC/PPN matches the key. If it does, DATATRIEVE stops searching the list and grants you the privileges listed in the entry. If the UICs do not match, DATATRIEVE performs the next step. 3. DATATRIEVE checks the next entry in the list, following the same procedure as in the previous step. When there are no more entries, DATATRIEVE denies access to the dictionary object and rejects your command or statement. The following examples show how DATATRIEVE handles some user requests. The examples use the following ACL for the domain YACHTS: DTR> SHOWP YACHTS(ffij l,UIC, [253,201], 2 ,UIC, [214,217], "CW" 3 ,PW, "FISH-FRY", "M" 4,UIC, [*.*] t "R" A user with UIC/PPN [253,201] enters a SHOW command to look at the definition of the YACHTS domain. DATATRIEVE checks the user's UIC/PPN and finds it as the first entry. Because no access privilege is granted, access to the domain is denied to the user. DTR> SHOW YACHTS Access denied to dictionar}' DTR> resource "YACHTS" A user with UIC/PPN [214,217] readies YACHTS for write access. The first match in the ACL (at entry 2) grants the user write (and control) privilege. The READY command executes: DTR> READY YACHTS WRITE(ffij DTR> 19-8 Controlling Access to Dictionary Objects A user with UIC/PPN [253,201] tries to ready YACHTS for modify access by including a password in the READY command. Because the entry in the ACL that contains the password FISH-FRY appears after the entry denying all privileges to the user, modify access to YACHTS is denied: DTR> READY YACHTS MODIFY (FISH-FRY)(ffi) Access denied to dictionar}' resource "YACHTS" DTR> A user with UIC/PPN [234,231] issues the same command as in the previous example. Because the user does not have the UIC/PPN that is denied all access and has included the correct password key for modify access, the READY command executes: DTR> READY YACHTS MODIFY (FISH-FRY)(ffi) DTR> 19.4 Maintaining an Access Control List To maintain an ACL that implements your security strategy, you must have C (control) access to the dictionary object associated with the ACL. Control access allows you to display an ACL and add or delete ACL entries. 19.4.1 Guidelines for Ordering Entries When you add entries to an ACL, the order of entries in the ACL controls the access to the dictionary object. Place the most restrictive entries first in an ACL and the least restrictive entries last. The most restrictive entries completely deny access to a specific UIC/PPN, while the least restrictive entries allow access by any UIC/PPN. The following rules apply when adding entries to the ACL: • Place entries that deny all privileges first. Use a lock type UIC (instead ofPW) for these entries. • Place restrictive entries that limit access to a specific UIC/PPN next. • Place the less restrictive entries (such as those requiring a password) next. • If access is allowed for any UIC/PPN (that is, if the key is [*,*]), place its entry last in the list. Controlling Access to Dictionary Objects 19-9 19.4.2 Assigning Privileges If you know which commands or statements you want to permit a user to issue, use Table 19-3 to find the privileges you must assign to that user. Table 19-3: Privilege Requirements by Command/Statement Command/Statement Privilege Required DEFINEP C privilege for the dictionary object DELETE C privilege for the dictionary object DELETEP C privilege for the dictionary object EDIT C privilege for the procedure or table EDIT ADVANCED C privilege for the domain or record ERASE W privilege for the domain and E privilege for the associated record EXTRACT R privilege for the dictionary object READY ... READ R, W, or M privilege for the domain and E privilege for the associated record ... WRITE W privilege for the domain and E privilege for the associated record ... MODIFY M or W privilege for the domain and E privilege for the associated record ... EXTEND E, W, or M privilege for the domain and E privilege for the associated record SHOW domain -name record-name proc-name table-name R privilege for the dictionary object SHOWP C privilege for the dictionary object associated with the ACL Use care when assigning the W privilege, particularly if a more restrictive privilege (such as R or M) would suffice. The W privilege allows the user to perform the same functions as the R, M, and E privileges but also allows the user to issue the ERASE command to delete records. 19.4.3 Displaying an Access Control List Use the SHOWP command to display an ACL: . [ (passwd) ] SHOWP object-name (*) 19-10 Controlling Access to Dictionary Objects 19.4.4 Adding Entries to an Access Control List Use the DEFINEP command to add an entry to an ACL: DEFINEP . [ (passwd) ] object-name (*) sequence-no, { PW, new-passwd } UIC, [m,n] , priv Before adding any entry to an ACL, display the ACL using SHOWP. The following example illustrates adding one entry to an ACL: DTR> SHOWP YACHTS 1 ,PW, (FISH-FRY)(ill) "FISH-FRY", DTR> DEFINEP YACHTS DTR> SHOWP YACHTS "RWEMC" (FISH-FRY) 2, UIC, [201 ,213J, R(ill) (FISH-FRY)(ill) 1 ,PW, "FISH-FRY", 2 ,UIC, [201 ,213J, IIRWEMC" IIR" DTR> When you add an entry to an ACL, DATATRIEVE renumbers the entries that follow it so that their numbers occur in proper sequence. 19.4.5 Deleting Entries from an Access Control List The DELETEP command deletes one entry from an ACL: DELETEP object-name [(pa~~Wd) ] sequence-number Use the SHOWP command before deleting an entry to verify that you are deleting the correct entry. For example: DTR> SHOWP YACHTS (FISH-FRY)(ill) 1 ,PW, IIFISH-FRylI, 2 ,UIC, [201 ,213J, IIRWEMC II "RII DTR> DELETEP YACHTS (FISH-FRY) 2(ill) DTR> SHOWP YACHTS (FISH-FRY)(ill) 1 ,PW, "FISH-FRY", "RWEMC" DTR> After you delete an entry, DATATRIEVE renumbers the entries so that they are sequential, beginning with 1. An ACL must have at least one entry. DATATRIEVE does not allow you to delete an entry wh~n that entry is the only one in the ACL. If you delete all entries that have C (control) privilege, there is only one way to change the ACL. Log in using a privileged UIC/PPN, invoke DATATRIEVE, and use the DEFINEP command to create an entry that gives one or more users the C privilege. Controlling Access to Dictionary Objects 19-11 Maintaining Data Dictionaries 20 A data dictionary holds domain, record, procedure, and table definitions. The items that you define in a data dictionary are called dictionary objects. DATATRIEVE supplies you with a default dictionary called QUERY.DIC. When you invoke DATATRIEVE, your current dictionary is QUERY.DIC. You can keep all your data definitions in QUERY.DIC, but it is orderly and efficient to store related definitions in separate dictionaries. You can create other data dictionaries with the CREATE DICTIONARY command. You can change from one dictionary to another, and you can display general and specific information about your current dictionary. You can also display information about readied domains, established collections, tables currently in memory, and selected records. You can transfer definitions stored in one dictionary to another dictionary by copying the definitions you want to a command file. You then set the destination dictionary as the current dictionary and execute the command file to store the definitions. You can also edit dictionary definitions. If you need to make only a few changes to an existing procedure or table, use the DATATRIEVE Editor, as described in Chapter 16. If you need to make extensive modifications to a procedure or table or want to edit a domain or record definition, you can copy the definition to a command file, exit from DATATRIEVE, edit the command file with the editor of your choice, and return to DATATRIEVE to execute the command file and store the new definition. The following sections discuss dictionary maintenance in detail. 20-1 20.1 Displaying Dictionary Objects You can list the names of all domains, records, procedures, and tables defined in the current data dictionary with the SHOW ALL command. SHOW ALL also lists the names of any established collections and readied domains: OrR> SHOW ALLCffi) DOfrlains: COMPANIES DDMF_TEST FAMILIES OLD_FAMILIES OWNERS PROJECTS YACHTS_SEQUENTIAL Records: COMPANIES_REC FAMILY_REC OWNER_RECORD Procedures: LOA_REPORT PRICE_PER_POUND TMP Tables: The current dictionary is SY:[ZtlJQUERY.DIC No established collections No read}' dOlrlains FOOYAC YACHTS PROJECTS_REC tylER I FY You can print the definition of any dictionary object to which you have read access: DTR> SHOW FAMILIESCffi) DOMAIN FAMILIES USING FAMILY_REC ON FAMILY.DAT; DTR> The kind of access you have to a dictionary object depends on the access control list (ACL) associated with that object. The ACL specifies whether you have R (read), W (write), M (modify), E (execute), C (control) or no privilege for a dictionary object. You can only display the ACL for a dictionary object if you have C (control) privileges. The following example prints the ACL for the domains FAMILIES and PROJECTS: DTR> SHOWP FAMILIESCffi) 1 tUIC t [* t*J t "RWMEC" DTR> SHOWP PROJECTSCffi) 1 tUIC t [23 ta5] t "RWMEC" ZtPWt "SESAME"t "RE" DTR> See Chapter 19 for further information on controlling access to dictionary objects. 20.2 Modifying Dictionary Objects To modify the definition of a dictionary object, you must have M (modify) access to the dictionary object. You can modify dictionary objects in the following ways: • You can use the DATATRIEVE Editor to modify definitions of procedures and tables. You cannot modify domains or records with the DATATRIEVE Editor, however. 20-2 Maintaining Data Dictionaries • You can use the REDEFINE command to create a new definition. DATATRIEVE deletes the previous version of the object and allows you to define it a different way. The domain FAMILIES, for example, can be redefined as follows: DTR> SHOW FAMILIESOO DOMAIN FAMILIES USING FAMILY_REC ON FAMILY.DAT; DTR> REDEFINE FAMILIES USINGOO DFN> NEW_FAMILY_REC ON NEW_FAMILY.DAT;OO DTR> SHOW FAMILIESOO DOMAIN FAMILIES USING NEW_FAMILY_REC ON NEW_FAMILY.DAT; DTR> ----------------------- Note ------------------------ The previous definition of an element will be permanently lost after a REDEFINE command is entered. If you make a mistake while entering the definition, you must enter it again from the beginning. • The easiest way to modify a dictionary element is probably to copy the definition to a command file using the EXTRACT command: DTR> E)-(TRACT ON TEM P. CMD PERSON_RECOO DTR> Exit DATATRIEVE and edit the command file using the text editor of your choice. After making the needed changes, return to DATATRIEVE and execute the command file. The EXTRACT command adds both a DELETE command and a DEFINE command to the beginning of the indirect command file. When you execute the command file, the DELETE command removes the old definition of the dictionary object from the current data dictionary, and the DEFINE command stores ~ the new definition in that dictionary. ----------------------- Note ----------------------- Use extreme caution when changing record definitions. If you change the record definition so that the record it describes no longer matches the record stored in your file, you can no longer access your data. Chapter 15 explains the relationship between your record definition and data access. The REDEFINE and EXTRACT commands do not copy the ACL associated with your record definition. When you redefine your record with the command file, DATATRIEVE also defines a new ACL for the record. This new ACL specifies the default privileges that have been set up for your system. Maintaining Data Dictionaries 20-3 The QXTR utility, discussed later in this chapter, enables you to copy the ACL associated with your record to a command file. 20.3 Deleting Dictionary Objects To remove the definition of a dictionary object from the current data dictionary, you must have C (control) access to the dictionary object. To remove a dictionary definition, use the DELETE command: DTR> SHOW DOMAINS(ffij DOfTlains: DDMF_TEST OWNERS DTR> DELETE FOOYAC;(ffij DTR> SHOW DOMAINS(ffij OLD_FAMILIES YACHTS_SEQUENTIAL FAMILIES PROJECTS FOOYAC YACHTS FAMILIES YACHTS OLD_FAMILIES OWNERS YACHTS_SEQUENTIAL DOITlains: DDMF_TEST PROJECTS DTR> Remember to terminate the DELETE command with a semicolon. DELETE removes from the dictionary both the definition of the dictionary object and its associated ACL. This command does not delete the data file associated with a domain. The data file still resides in the directory where it was stored. Therefore, you can delete a domain definition and redefine it to access the same data file. 20.4 Optimizing Disk Storage of Data Dictionaries with QCPRS The data dictionary is an indexed file stored on a disk. When you add and delete definitions from a dictionary, that file accumulates unused areas of disk space. To reclaim this wasted disk space, run the utility program QCPRS. QCPRS compresses the contents of the dictionary, eliminating unused disk space. Compressing your dictionary can also improve DATATRIEVE performance. To compress a data dictionary, you should first determine how many blocks of storage your dictionary occupies. The following example determines the size of the dictionary KELLER.DIC that resides in directory [100,120] on the system disk. The example uses the DCL DIRECTORY command: $ DIRECTORY/FULL SY:[100t120JKELLER.DIC(ffij The resulting display tells you the size (in blocks) of the dictionary. Later on, QCPRS prompts you for the number of blocks it should allocate for the compressed file. The number you supply should equal or exceed the number of blocks the dictionary currently uses. On a RSTS/E system, you should rename the dictionary before invoking the QCPRS utility. The easiest way to do this is to change the file extension: $ RENAME KELLER.DIC KELLER.5AK(ffij $ 20-4 Maintaining Data Dictionaries Then you invoke QCPRS in response to the operating system prompt. The following example assumes that you are using DCL to invoke QCPRS, which prints an identification message and requests a command with the following prompt: $ RUN $QCPRS QUERY FILE COPY-COMPRESS UTILITY CPR> Use the following format to compress the dictionary: new-file = old-file New-file is the file specification for the compressed copy of the dictionary. Old-file is the file specification of the dictionary to be compressed. If you omit a field in either file specification, QCPRS uses the following defaults: Field Default dev: SY: (the system device) UIC/PPN Your default UIC/PPN file name QUERY extension DIC Under all operating systems but RSTS/E, the file specifications for new-file and old-file can be the same. QCPRS merely creates a new copy of the file using the next higher version number. Under RSTS/E, the file specifications for new-file and old-file must be different. Use the renamed dictionary from a previous example: QCP>KELLER.DIC = KELLER.BAKffiD) After you have entered the file specifications, QCPRS asks you to specify a number of disk blocks as an allocation for the new version of the dictionary: ENTER ALLOCATION FOR AREA 0: Enter the number of disk blocks you want to allocate for the compressed dictionary. If the number is too low, QCPRS automatically extends the file to hold the contents of the original file. If the number is too high, the extra blocks remain in the file and give room for contiguous expansion of the dictionary. A number that is higher than what the file currently needs can help maintain DATATRIEVE performance for a longer period of time; however, the higher number wastes disk space over the short run. QCPRS then prompts again with CPR>, and you can compress another dictionary file or terminate QCPRS with CTRL/Z. Maintaining Data Dictionaries 20-5 Because QCPRS does not alter the contents of the original file, you can save the file as a backup, or you can delete it. You can use QCPRS to compress an indexed data file associated with a DATATRIEVE domain as well as to compress a dictionary. If you have added many records to the indexed data file since the time you created it, compressing the file can help reduce DATATRIEVE response time to queries that access the file. Simply follow the steps you use to compress a dictionary, but specify the name and extension of the indexed file. 20.5 Extracting Dictionary Content with the QXTR Utility You might want to transfer dictionary objects from one data dictionary to another or transport your dictionary objects to VAX DATATRIEVE. You can use the QXTR utility to create a command file containing all the definitions extracted from a DATATRIEVE-ll data dictionary. Like QCPRS, QXTR is a dictionary maintenance program supplied with the DATATRIEVE-ll installation kit. Running the QXTR program is equivalent to specifying all the objects in your dictionary in an EXTRACT command. However, the QXTR program also allows you to preserve the access control lists (ACLs) associated with each dictionary object. You must invoke QXTR from the system command level. The following example uses the DCL RUN command: $ RUN $Q>nROO) Extract Utility for DTR Dictionaries V02.00 QXTR then prompts you for the following information: • The file specification of the dictionary to be processed. • Whether you want to extract the access control list for each dictionary object. • If you respond with Y to the question on access control lists, whether you want those lists to use VAX DATATRIEVE syntax. • The name of the output command file to contain the extracted definitions. (The default is QXTR.CMD in your default directory.) When QXTR finishes processing your dictionary, it returns you to system command level. The file QXTR creates an RMS sequential file you can invoke as an indirect command file for DATATRIEVE. 20-6 Maintaining Data Dictionaries The following example processes the dictionary KELLER.DIC and copies the dictionary object definitions to LESLIE.CMD. The ACLs are extracted along with the objects. The ACLs remain in DATATRIEVE-ll syntax: o i c t ion a r}' F i 1 e s p e c toE x t r act fro ITI? KELL ER • 0 I C(Bill Should Protection Tables be Extracted (Y or N)? Y(Bill Ext r act in t.J A}-( - 11 0 ATAT R I Et.J E S}' n t a x ? N(Bill Filespec to Extract elements to? LESLIE.CMD(Bill $ Like the EXTRACT command in DATATRIEVE, the QXTR utility precedes each dictionary object definition with a DELETE command. It also adds an ALLOCATION LEFT-RIGHT clause ifno ALLOCATION clause is specified for record definitions. QXTR checks that you have R (read) privilege for the objects in the dictionary before extracting them. If you do not, it prints a message that the objects were not extracted, and the program continues. If you are logged in under a privileged account (with a UIC/PPN [l,x]), you can extract everything regardless of the access control list. If the access control list allows only password access and not UIC/PPN access, you must run QXTR from a privileged account to extract the element. The program checks your current UIC against the access control list. QXTR aborts if it encounters a corrupt dictionary object. In this case, the command file contains definitions extracted before QXTR encountered the corrupt object. It does not contain the definition of the corrupt object or the definitions that would follow. DATATRIEVE extracts definitions in the following order: domains, procedures, records, and tables. Definitions of specific objects within these four types are extracted in alphabetical order according to the name of the object. Examine the incomplete command file to determine which dictionary object is corrupt. You must delete the corrupt object from the dictionary before running QXTR again. Maintaining Data Dictionaries 20-7 Name Recognition and Single Record Context A When you use a field name as a value expression and when you display, modify, or erase one or more records, DATATRIEVE determines exactly which record or records are the targets of the action you propose. For each of these actions, DATATRIEVE must first determine the context within which the action occurs. The context is the set of conditions that govern the way DATATRIEVE recognizes field names and determines which records are the targets ofDATATRIEVE statements. Understanding the way DATATRIEVE manages context is especially important when you begin nesting DATATRIEVE statements. A.1 Establishing the Context for Name Recognition DATATRIEVE does not require that every field name be unique. You can use the same name in several record definitions. You can even use the same name several times in the same record definition, as long as the fields with the identical name do not have the same level number in one group field. Both the YACHTS and OWNERS domains, for example, have group fields named TYPE, and both group fields contain elementary fields you can refer to with the names BUILDER and MODEL. (In YACHTS, DATATRIEVE recognizes the query name BUILDER as equivalent to MANUFACTURER. Other query names for YACHTS are SPECS, LOA, and DISP.) Figure A-I shows the fields in both record definitions and points out the duplicate names. When you work with several record streams from the same domain, the field names in all record streams are identical. Whether you form collections or record streams of records from the YACHTS domain, DATATRIEVE has a mechanism for identifying which record to act on when you want to retrieve or change data from only one field of one record. A-1 +--------+ +--------+ : OWNERS : : YACHTS : +--------+ +--------+ OWNER NAME BOAT_NAME TYPE BUILDER MODEL ~ ~ ~ BOAT TYPE MANUFACTURER (BUILDER) MODEL SPECIFICATIONS (SPECS) RIG LENGTH_OVER_ALL (LOA) DISPLACEMENT (DISP) BEAM PRICE Figure A-1: Duplicate Field Names in YACHTS and OWNERS When you understand the way DATATRIEVE establishes the context for recognizing names, you can use the names of domains, fields, collections, and variables to form both simple and complex relationships among fields. One of the keys to mastering the use of context is understanding the two DATATRIEVE context stacks. A.1.1 The Right Context Stack When you issue a statement, DATATRIEVE builds a context stack, a linked list that controls the DATATRIEVE search for names to match the ones you use in statements. The context stack consists of context blocks, or lists of names. These context blocks are linked together by pointers that control the sequence of search by DATATRIEVE for values to associate with the names you use in statements. DATATRIEVE searches the right context stack for values to associate with names you use in print lists, Boolean expressions, and the right side of assignment statements such as x = y. The left context stack is discussed later in this appendix. The Content of a Context Block - When you use a record selection expression, DATATRIEVE creates a context block to establish a context for name recognition. That context block contains, among other things, a list of names. A.1.1.1 At the top of the list is a slot for the name of a context variable (see the section on context variables later in this appendix). Next is the name of the domain referred to in the record selection expression. The rest of the list contains the names of fields in the record associated with that domain. Those field names are arranged according to the field tree associated with the source. The field tree contains the names of all the group fields, elementary fields, COMPUTED BY fields, REDEFINES fields, and lists in the record and preserves the hierarchical relationships among them. A-2 Name Recognition and Single Record Context When DATATRIEVE searches for a name in the context stack, it is looking for a value to associate with that name. The search ends, and DATATRIEVE takes the associated value when it finds the first name that matches the one in your statement. A DATATRIEVE name can consist of several names joined together. They resemble dictionary path names in form and function. To be recognized, these compound or qualified names must represent a valid path through the hierarchy of a context block and the field tree it contains. When DATATRIEVE encounters a name, it begins its search in the context block on top of the stack. DATATRIEVE first looks at the slot in the context block reserved for the name of a context variable. For unnamed CURRENT collections, this slot contains the name CURRENT. For named CURRENT collections, the name CURRENT and the collection name are equivalent. Named collections that are not the CURRENT collection have the collection name in this slot. If the top block on the context stack refers to a record stream, this slot is empty unless you use a context variable in the RSE that forms the record stream. The context variable gives a record stream a temporary name; this name fills the first slot in the context block for these "named" record streams. If DATATRIEVE finds that the first segment of a qualified name matches the name in the collection name/context variable slot, it continues its search in that block for a match for the rest of the name. If the name in your statement does not match the name in the collection name/context variable slot, or if that slot is empty, DATATRIEVE continues to look through the first context block to find a match. Next in the context block is the name of the source of the records referred to by that block. For collections and record streams, that source can be the name of a domain, collection, or list for hierarchical records. The source can also be the name of a collection if you use the collection as the basis for a record stream in a FOR statement and you use a context variable. If the source name does not match the name in your statement, DATATRIEVE next looks for the name in the slot reserved for names. Next DATATRIEVE looks at the name of the top-level (the 01 level) field name. Ifno match occurs, DATATRIEVE looks at each succeeding field name in the order they are displayed when you enter a SHOW FIELDS command. That order can take you through the entire hierarchy of the field tree, traversing first the left branch then the right, wherever there is a branching point in the hierarchy. IfDATATRIEVE finds no match in the first block on the context stack, it goes to the next context block on the stack and begins its search there. DATATRIEVE stops its search as soon as it finds an exact match for the name in your statement. Then it associates the value assigned to the name on the context stack with the name of the field in your statement. Name Recognition and Single Record Context A-3 IfDATATRIEVE finds no match for the name in any of the context blocks, it displays a message on your terminal that the field name is either undefined or used out of context. The only remedies are to change the context so that the name in your statement resolves properly or to remove any ambiguity by qualifying the name further with group field names or context variables. For the sake of clarity, the following description of the various types of context blocks starts with the bottom of the context stack, that is, with the context block that DATATRIEVE checks last. A.1.1.2 Global Variables - The bottom context block contains the names of any global variables you have established and have not released. This block is different from the others on the stack because its content is not determined by a record selection expression. Nevertheless, DATATRIEVE treats the name ofa global variable as though it were the name of a field in a simple record. Just as DATATRIEVE associates the value of a field with the field name, DATATRIEVE associates the value of a global variable with its name. DATATRIEVE looks at the global variables last when trying to find a name to match one in your statement. No two global variables can have the same name. When you issue a DECLARE statement at command level (indicated by the DTR> prompt), DATATRIEVE checks the names of the global variables you have declared. If it finds one with the same name, it releases the old variable and its value and replaces it with the new one. DATATRIEVE initializes the new variable with a default value, a zero, or a space depending on the clauses you include in the DECLARE statement. Collections - The next higher set of blocks in the context stack refers to existing collections. Each collection with a block on the context stack must have one record singled out as a selected record. Although a collection can have a number of records in it, only one of those records can be used in the search for the context ofa name. DATATRIEVE can assign only one value to the name. Consequently, that one value can come from only one of the records in the collection. A.1.1.3 Remember, the reason for resolving the context of a name you use in a statement is to assign a value to the name that can be used in the statement. For an existing collection, you can designate one record at a time as the selected record for that collection. The SELECT statement lets you designate the selected record in a collection by relative reference (FIRST, NEXT, and LAST) or by absolute reference to the position number of the record in the collection. A collection has a block on the context stack only ifit has a selected record. If you have more than one existing collection with a selected record, the block immediately above the one for global variables refers to a named collection with a selected record. That collection is the one you formed with a FIND statement before you formed any of the other collections that have selected records. The rest of the context blocks for the collections with selected records are ordered according to the sequence in which you formed them, not the order in which you entered the SELECT statement to establish the selected records. A-4 Name Recognition and Single Record,Context If the CURRENT collection has a selected record, the context stack contains a block referring to the CURRENT collection. That block is above the blocks of all other collections. DATATRIEVE searches for names in the context block of the CURRENT collection before it searches the context block of any other collection. The key to understanding the way DATATRIEVE recognizes names is that except for the global variables, the context stack is ordered on a last-in, first-out basis. The most recently formed context block is the one DATATRIEVE searches first. You do not have to rely on your meIl].ory to recall the order in which you formed your existing collections. You need only issue a SHOW COLLECTIONS command. DATATRIEVE displays the most recently formed collection (always the CURRENT collection, whether it has a name or not) at the top of the list and the "oldest" one at the bottom. The SHOW COLLECTIONS command, however, lists all the existing collections whether or not they contain selected records. Remember, only the collections with selected records are represented on the context stack. With the SHOW collection-name command, you can inspect each existing collection to see how many records are in the collection, whether it has a selected record, and, if it does, what the position number of the selected record is in the collection. IfDATATRIEVE searches the context stack and does not find a match for the name in your statement, it displays an error message that may seem puzzling unless you understand the way DATATRIEVE forms the context stack: Field IInalTlell is undefined or used out of context You may know the name has been defined, and that it is the name ofa field in a record associated with one or more existing collections. If, however, none of the collections containing that field has selected records, DATATRIEVE cannot tell if the field is defined or not. If a collection containing the named field has no selected record, that collection has no block on the context stack. Consequently, DATATRIEVE neither finds a match for the field name nor has a way of discovering from the search of the context stack if the field name is defined at all. The order of context blocks at the higher levels of the context stack depends on the order in which DATATRIEVE encounters the elements containing names associated with values. The order of the following sections does not imply any relative position on the stack. Only the order DATATRIEVE encounters those elements determines their order on the stack. A.1.1.4 Record Streams - Before DATATRIEVE looks at the context block of the most recently formed collection with a selected record, it first looks at the context blocks created explicitly in the statement. One type of context block created by a statement refers to the field names of a record stream formed by a statement. Name Recognition and Single Record Context A-5 Context blocks of record streams act differently from those of collections. The context block for a collection stays on the stack as long as the collection has a selected record. The context block of a collection is removed from the stack only if you release the collection or remove its selected record with a DROP statement. The context block for a record stream, however, stays on the stack only as long as the statement containing it is being executed. When DATATRIEVE finishes processing the statement, the block is removed from the context stack and is not available when DATATRIEVE rebuilds the stack after it encounters the next statement. Only three statements and one command make lasting changes to the context stack: • FIND The FIND statement can remove the CURRENT collection from the context stack by forming a new CURRENT collection. The new CURRENT collection releases the old collection but does not put a block on the context stack because a newly formed collection has no selected record. • SELECT The SELECT statement puts a collection on the context stack by establishing a selected record. SELECT cannot change the relative order of collections on the stack. That order is determined by the relative order in which you formed the collections with the FIND statement. • DROP The DROP statement removes a collection from the context stack by dropping the selected record from the collection. The SHOW collection-name command still notes the position number of the previously selected record, but the record has been removed from the collection and you cannot retrieve it unless you form a new collection that contains it. • RELEASE The RELEASE command also removes a collection from the context stack. The released collection no longer exists, thus freeing the space it occupied. Records and domains associated with a collection named in the RELEASE command are not affected. These three statements, however, share a restriction that separates them from all other statements: you cannot use FIND, SELECT, or DROP statements in compound statements. They must be entered at command level by themselves. Furthermore, these statements do not form temporary record streams; they affect only collections. A-6 Name Recognition and Single Record Context You can, however, have several context blocks for record streams on the context stack at one time. The block for a record stream stays on the context stack until DATATRIEVE finishes the statement. Because you can nest statements in FOR loops, BEGIN-END blocks, IF-THEN-ELSE statements, THEN, and WHILE statements, the inner statements can form record streams before DATATRIEVE finishes the outermost statement. DATATRIEVE has to keep the context of outer statements separate from that of inner ones. It keeps them separate by putting a block on the context stack when it encounters an element that requires one. DATATRIEVE begins processing compound statements with the outermost statement and works progressively toward the innermost one. The context blocks it forms for elements in the innermost statement are at the top of the stack when the innermost statement is being processed. When DATATRIEVE finishes processing the innermost statement, it removes the blocks created by that statement. DATATRIEVE works its way back out toward the outermost statement, removing blocks created by statements as soon as it finishes processing the statement. For example, in the case of nested FOR loops, the context block for the innermost FOR loop is higher in the stack than the blocks for the outer loops. When DATATRIEVE completes the execution of the innermost loop, it removes the context block of that FOR statement, leaving the blocks of the outer FOR statement on the stack. As DATATRIEVE completes each loop, the context block for that loop is removed from the stack. This same pattern applies to statements in BEGIN-END blocks. When a statement that forms a record stream is followed by a second statement that is not contained in the first, DATATRIEVE removes the context block created for the first statement from the stack and puts a context block for the second statement in its place. For example, in a BEGIN-END block, one PRINT statement containing an OF rse clause follows another. The context block of the first statement is in effect only during the execution of that first statement. That block is replaced by the one for the second PRINT statement when DATATRIEVE begins processing the second statement. DATATRIEVE handles the context block ofa FOR loop the same as it handles statements containing an OF rse clause. DATATRIEVE creates four other types of context blocks that affect the order of the context stack: those for local variables, VERIFY clauses, VALID IF clauses, and context variables. Local Variables - Local variables are variables defined in compound statements. A local variable and its effect on the context stack last only from the DECLARE statement that defines it until DATATRIEVE completes the execution of the statement containing the DECLARE statement. A.1.1.S Name Recognition and Single Record Context A-7 VERIFY Clause in the STORE Statement - Like the context for local variables, the context for resolving field names in a VERIFY clause of the STORE statement is short-lived. The STORE statement does not access or change any existing record. Consequently, for each STORE statement, DATATRIEVE creates a context block to associate the field names with the values in the new record. DATATRIEVE executes the VERIFY clause after you have assigned values to all the fields prescribed by the syntax of the statement but before DATATRIEVE stores the record in the data file. A.1.1.6 A.1.1.7 VALID IF Clause in a Record Definition - When you assign a value to a field name in either a STORE or MODIFY statement, DATATRIEVE looks in the appropriate record definition for a VALID IF clause. If the value is unacceptable according to the conditions specified in the VALID IF clause, DATATRIEVE displays a message on your terminal and reprompts you for an acceptable value. It uses the same context to associate the field name with your response to the reprompt. The context for resolving field names in the VALID IF clause is established by the context block set up for either: • The STORE statement • The MODIFY statement In either case, the value associated with the field name is the one just assigned to it by your response to a prompt or by an assignment statement in the USING clause of the STORE or MODIFY statement. DATATRIEVE executes the VERIFY clause only after the values you assign meet the conditions of VALID IF clauses in the record definition. As a result, there can be no conflict between the context established for these two clauses. The context for the VALID IF clause no longer exists when DATATRIEVE executes the VERIFY clause. A.1.2 Using Context Variables and Qualified Field Names The ways of establishing context discussed to this point deal with resolving the connections between names and values by finding the first instance of a valid field name or variable name. When several context blocks on the stack contain fields with the same names, you need a way to skip over some instances of the name to get to the field that contains the value you want to retrieve. DATATRIEVE gives you two methods of forcing name recognition: context variables and qualified field names. Although they require different actions from you, these two methods have an underlying similarity. A.1.2.1 Context Variables as Field Name Qualifiers - A context variable is a dummy variable specified in a record selection expression for the purpose of name recognition. When DATATRIEVE encounters a context variable, it puts a new block on the context stack. That new block connects the name of the context variable with the field names and values of the records identified by the record selection expression. A-8 Name Recognition and Single Record Context The context established by the context variable lasts until DATATRIEVE completes the execution of the statement containing the record selection expression in which the context variable occurs. However, that context does not affect any outer loops or nesting statements that contain the statement in which you use the context variable. A context variable, however, does affect all inner statements nested in the statement that contains the record selection expression in which the context variable occurs. You can use the context variable as a prefix for each field name of the records identified by the record selection expression. Citing a field name with a context variable prefix can make a field name unique, even when the domains and field trees of a record in a record stream are identical. Putting a prefix on a field name produces a qualified field name. The context variable must be the first prefix added to a field name. Using other qualifiers as prefixes to field names is the second method of overriding the DATATRIEVE default mechanism of name recognition. A.1.2.2 Other Field Name Qualifiers - Each fully qualified field name must be unique. The fully qualified field name consists of the record name, the top-level group field name, the names of any group field to which the elementary field belongs, and the elementary field name. You must separate each element of the fully qualified name from the next with a period. For example, In the domain YACHTS, the fully qualified field name of MODEL is: YACHT.BOAT.TYPE.MODEL You can use these elements in any combination that preserves their hierarchical order to distinguish the MODEL field in YACHTS from the MODEL field in another domain such as OWNERS. When DATATRIEVE encounters a qualified field name, it searches the context stack for the first match of the name you specify. For example, if you use BOAT.MODEL in a record selection expression, DATATRIEVE searches the context stack for the first valid occurrence of the name BOAT and searches the branches of the hierarchy under BOAT for the first valid occurrence of the name MODEL. The success of the search is not jeopardized because you omit the group field name TYPE from the qualified name MODEL. DATATRIEVE searches the entire hierarchy under BOAT until it finds the first valid occurrence of TYPE. When an intermediary group field name is omitted, DATATRIEVE searches the hierarchy according to the order in which the fields of the record were defined. Fully qualified field names are adequate when working with two or more domains that share elementary or group field names, or both. However, when you are working with two record streams from the same domain, you must further qualify the field name with a context variable. This extra qualification is especially necessary when dealing with lists in hierarchical records. Name Recognition and Single Record Context A-9 Suppose you want to display information about all builders who build boats with more than one type of rig. YACHT is the given name of the record associated with the domain YACHTS. The field tree of YACHT has the structure: YACHTS 01 BOAT 03 TYPE 06 MANUFACTURER 06 MODEL 03 SPECIFICATIONS 06 RIG 06 LENGTH_OVER_ALL 06 DISPLACEMENT 06 BEAM 06 PRICE You can print the desired information with nested FOR loops. For each boat from the outer FOR statement, you want DATATRIEVE to loop through all the boats and find all the ones with the same builder. For each one it finds, you want it to compare its rig with the rig of the boat from the outer loop. Then you want to separate out the ones for which the rigs are not the same. At first, you might be tempted to use the following statement to produce the desired list: DTR> SET NO PROMPT@] DTR> FOR YACHTS@] CON> FOR YACHTS WITH BUILDER = BUILDER AND@] CON> RIG NE RIG@] CON> PRINT BUILDER, RIG, RIG@] DTR> After a long search for records, DATATRIEVE displays no records. The problem is that the preceding syntax asks DATATRIEVE to look for a boat with a rig that is not equal to itself - an obvious contradiction. Both of the fields named RIG resolve to the record stream formed by the second FOR statement. The name BUILDER also resolves to the same record stream. When you enter this statement, DATATRIEVE takes the first record from YACHTS but does not look at any of the values in its fields. Then it looks at every record in YACHTS and discovers that for everyone of them, the name of the builder equals itself, but that no rig is not equal to itself. Thus every record in YACHTS fails to meet the condition set by the statement. DATATRIEVE then takes the second record in YACHTS and once again goes through all the boats, finding that the two values are always equal to themselves and thus fail to meet the impossible demands of the statement. And so it goes for each record: two comparisons for 113 times 113 records, and no records meet the self-contradictory conditions. A-10 Name Recognition and Single Record Context The problem is how to get DATATRIEVE to look at the builder and rig of the outer FOR statement when making the comparison. The context variable provides one solution: DTR> FOR A IN YACHTStlli) CON> FOR YACHTS WITH BUILDER = A.BUILDER AND RIG NE A.RIGtlli) CON> PRINT BUILDERt A.RIGt RIGtlli) MANUFACTURER RIG RIG AMERICAN AMERICAN CHALLENGER SLOOP MS SLOOP MS SLOOP KETCH PEARSON PEARSON KETCH KETCH SLOOP SLOOP DTR> In this case, the use of the context variable A forces DATATRIEVE to look to the record stream formed by the outer FOR statement. At the same time, DATATRIEVE recognizes the unqualified names, RIG and BUILDER, in the context established by the most recent RSE: the one in the second FOR statement. The conditions in the second FOR statement are no longer impossible, and information from 62 records is displayed. The way DATATRIEVE treats the unqualified names in this example illustrates another rule for context resolution: the left-hand member of a Boolean expression must resolve to the record selection expression of which it is a part. If you start the Boolean expression in the second FOR statement with A.BUILDER, DATATRIEVE tells you that A.BUILDER is undefined or used out of context. You can add a second context variable in the previous example to make sure the resolution of the names is explicitly stated: DTR> FOR A IN YACHTStlli) CON> FOR B IN YACHTS WITH B.BUILDER = A.BUILDER AND B.RIG NE A.RIGtlli) CON> PRINT B.BUILDERt A.RIGt B.RIGtlli) You gain two advantages by specifying the second context variable: clarity of representation and certainty that DATATRIEVE will display an error message if you make a syntax error. Using the second context variable, however, does not allow you to violate the rule for resolving field names on the left side of Boolean expressions. A.1.3 The Left Context Stack for Assignment Statements When you make assignment statements at DATATRIEVE command level or as part of STORE or MODIFY statements, DATATRIEVE must assign values to the field or variable you intend. It uses the left context stack to associate the values you supply with the fields and variables you want the values assigned to. Blocks on the left context stack are for records and variables that you can update. Name Recognition and Single Record Context A-11 Whenever DATATRIEVE begins to process a statement, the left context stack contains the global variables you have declared and not released. Any local variables you declare in compound statements are also on the left context stack. The local variables are removed when the statement in which you declared them ends. Local and global variables are on both stacks. Each type of variable has a value that can be assigned to a field or another variable; hence, they are on the right context stack. Both can be updated with new values you assign them; hence, they are on the left context stack. Context blocks for a record you want to modify is also on both context stacks. The record has a value you can use in Boolean expressions and assignment statements. You can update that value in a MODIFY statement. Because a field is on both stacks at the same time, you can use the old value of the field to calculate the newvalue. You can use the following form of assignment statement: DTR> MODIFY USING PRICE = PRICE * 1.100 DTR> DATATRIEVE retrieves the old value of PRICE associated with the name on the right context stack and multiplies the old PRICE by a constant. It then associates that value with the name PRICE on the left context stack and updates the value of the PRICE field. When you enter a STORE statement, the only context block for the new record is on the left context stack. No record exists yet, and, of course, no values are associated with fields of a record. The fields can only receive values. However, as soon as DATATRIEVE associates a value with a field, you can move that value to the right context stack and use it on the right side of assignment statements. You can make this shift before you finish assigning values to all the fields of the new record. In fact, you can use the values of new fields to calculate the values DATATRIEVE stores in other new fields in the same record. To shift newly stored values to the right context stack, include a context variable with the domain name when you enter the STORE statement: DTR> STORE A IN YACHTS USING • • • Then in the USING clause, you use the context variable to qualify the names of any field whose value you want to use on the right side of an assignment statement: DTR> STORE A IN YACHTS USINGOO CON> BEGIN(BITJ CON> F1 = l.Ialue-expressionOO CON> F2 = l.Ialue-expressionOO CON) F3 A.F1+A.F2ru CON> ENOru DTR> A-12 Name Recognition and Single Record Context The context variable allows you to associate a field name on the right context stack with its new value as soon as you assign the value to the field. You cannot, however, use a field name on the right side of an assignment statement until you have assigned a value to the field. A.1.4 Examples of Context Variables in STORE and MODIFY Statements You can combine STORE and MODIFY statements to keep an audit trail of modifications made to records in a domain and to change statistical records when you store new records. To form an audit trail you need a domain for the audit records. This domain can use the same record definition as the original domain, but it must have its own domain definition and its own data file. Here is a simple example: DTR> SHOW AUDIT_YACHTSru DOMAIN AUDIT_YACHTS USING YACHT ON AUD_YACHT; DTR> FOR A IN YACHTS MODIFY USINGru CON> BEGINru CON> BUILDER *.BUILDERru CON> MODEL *.MODELru CON> RIG = *.RIGru CON> LOA = *.LOAru CON> DISP = *.WEIGHTru CON> BEAM = *.BEAMru CON> PRICE = *.PRICEru CON> STORE B IN AUDIT_YACHTS USINGru CON> B.BOAT = A.BOATru CON>ENDru Enter BUILDER: If you have a VERIFY USING clause in the MODIFY statement, put the STORE statement as the last statement in the VERIFY clause. If you put the VERIFY clause after the STORE statement and the VERIFY clause aborts the change, you have a record of the change, but you have not changed the record. You can also embed a MODIFY statement in a STORE statement. In this example, the embedded MODIFY statement updates a record of the last date a new record was added to the data file and records the TYPE field of the record stored. The file LAST.DAT is a sequential file with one record in it. DTR> SHOW LAST_ENTRYru DOMAIN LAST_ENTRY USING LAST_REC ON LAST.DAT; DTR> SHOW LAST_RECru RECORD LAST_REC USING 01 TOP. 03 LAST_DATE USAGE DATE. 03 TYPE PIC X(20). DTR> STORE YACHTS CON> BEGINru CON> BUILDER CON> MODEL CON> RIG = USINGru *.BUILDERru *.MODELru *.RIGru (continued on next page) Name Recognition and Single Record Context A-13 CON> LOA = *.LOA@] CON> DISP = *.WEIGHT@] CON> BEAM = *.BEAM@] CON> PRICE = *.PRICE@] CON> MODIFY LAST_ENTRY USING@] CON> BEGIN CON> LAST_DATE = "TODAY"@] CON> B.TYPE = A.TYPE@] CON> END CON>END@] Enter BUILDER: With the proper 'Use of context variables, you can also store or change data in fields shared by two or more domains. A.2 Single Record Context The DATATRIEVE statements PRINT, MODIFY, and ERASE can act on one record at a time or on an entire record stream or collection. The records on which they act are called target records. You can identify target records for these statements in four ways: • A SELECT statement identifies one target record in a collection. • The keyword ALL in the statement without an OF rse clause makes all records in a collection the targets of the statement. • An OF rse clause in the statement forms a target record stream. • The RSE clause in a FOR statement forms a stream of target records for the statement contained in the FOR loop. A.2.1 The SELECT Statement and the Single Record Context Before discussing the SELECT statement and context, a short review of facts about collections is in order. DATATRIEVE keeps a list of the collections you form with the FIND statement. The most recent one formed is always at the top of the list and is called the CURRENT collection. The only other collections on the list are the ones to which you assigned a name when you formed them. The next collection you form then becomes the new CURRENT collection. DATATRIEVE discards the old CURRENT collection unless you give it a name when you form it. With the RELEASE command, you can remove a collection from that list. If you release the CURRENT collection, the next one on the list becomes the CURRENT collection. No collection on this list, however, is represented by a block on the context stack unless you use the SELECT statement to single out one record in the collection. When you select a record in a collection, DATATRIEVE puts a block for that collection on the context stack. If every existing collection has a selected record, then DATATRIEVE keeps a block on the context stack for each of those collections. A-14 Name Recognition and Single Record Context The relative ages of the collections with selected records determine the order of context blocks for collections. The "oldest" collection with a selected record is nearest the bottom of the context stack. Because the CURRENT collection is always the "youngest," its context block, ifit has one, is nearest the top. This order of context blocks for collections establishes the order DATATRIEVE uses not only for recognizing field names as described previously, but also for identifying single target records. When you enter the most abbreviated forms of the PRINT, MODIFY, and ERASE statements, DATATRIEVE looks on the context stack for the first valid single record context to carry out the specified action. It looks for the youngest collection with a selected record and either prints the record, erases it, or changes it. The following sequence of examples illustrates the effect of the SELECT and DROP statements on single record context and the subsequent actions of the PRINT, MODIFY, and ERASE statements. Form a collection of records from the YACHTS domain, call it BIGGIES, select the third record as the target record, and display it: DTR) READY YACHTS WRITEoo DTR) FIND BIGGIES IN YACHTS WITH LOA > aooo [8 records found] DTR) SELECT 300 DTR) PRINToo MANUFACTURER GULFSTAR MODEL al RIG LENGTH Ot.IER ALL WEIGHT BEAM PRICE KETCH al 22,000 $al,350 12 DTR> Store a new record in the YACHTS domain and form a collection that consists of that one record. Later you can modify and erase this record: DTR> STORE YACHTSoo Enter MANUFACTURER: HINKLEYoo Enter MODEL: BERMUDA aOOO Enter RIG: YAWLoo En t e r LENGTH_Ot.IER_ALL: aOOO Enter DISPLACEMENT: 2000000 En t e r BEAM: 1200 Enter PRICE: 82,00000 DTR> FIND YACHTS WITH BUILDER [1 record found] DTR) "HINKLEY"oo Name Recognition and Single Record Context A-15 You now have two collections, CURRENT (the younger) and BIGGIES (the older): DTR> SHOW COLLECTIONS®] Collections: CURRENT BIGGIES DTR> SHOW CURRENT®] Collection CURRENT DOlrlai n: YACHTS NUMber of Records: No Selected Record DTR> SHOW BIGGIES®] Collection BIGGIES DOlrlain: YACHTS NUMber of Records: 8 Selected Record: 3 DTR> The CURRENT collection has no selected record, but BIGGIES still does. Consequently, when you type PRINT and press the RETURN key again, DATATRIEVE prints the record in the first valid single record context, that is, the selected record in BIGGIES: DTR> PRINT®] MANUFACTURER GULFS TAR MODEL Lll RIG LENGTH OVER ALL WEIGHT BEAM PRICE KETCH Lll 22,000 SLll,350 12 DTR> When you type SELECT and press the RETURN key, DATATRIEVE selects the first and only record in the CURRENT collection. Now when you type PRINT and press the RETURN key, the single record context has changed. Now the selected record in the CURRENT collection is the target record of the PRINT statement: DTR> SELECT®] DTR> PRINT®] MANUFACTURER HINKLEY MODEL RIG BERMUDA LlO YAWL DTR> SHOW CURRENT®] Collection CURRENT DOlrlain: YACHTS NUMber of Records: Selected Record: 1 DTR> A-16 Name Recognition and Single Record Context LENGTH OI.lER ALL WEIGHT BEAM PRICE 20,000 S82,OOO LlO 12 Now modify the PRICE of the target record and display the result. The MODIFY and PRINT statements both act on the record in the first valid single record context, that is, the selected record in the CURRENT collection: OTR> MOOIFY PRICE(ffi) Enter PRICE: 75tOOO(ffi) OTR> PRINTOO MANUFACTURER HINKLEY MOOEL RIG BERMUOA ao YAWL LENGTH OI.IER ALL WEIGHT BEAM PRICE ao $75 tOOO 20 tOOO 12, OTR> Now type ERASE and press the RETURN key. The ERASE statement also acts on the record in the first valid single record context, and the record for the HINKLEY boat is removed from the data file YACHT.DAT. Even though you erase the only record in the collection, DATATRIEVE does not discard the collection. It takes note that you have erased the selected record and removes the context block for the CURRENT collection from the context stack. You can verify the change in single record context by typing PRINT and pressing RETURN. The selected record from BIGGIES is again in the first valid single record context: OTR> ERASEOO OTR> SHOW CURRENT(ffi) Collection CURRENT OOfrlai n: YACHTS NUMber of Records: 1 Selected Record: 1 OTR> PRINTOO MANUFACTURER GULFSTAR MODEL a1 RIG KETCH LENGTH OI.IER ALL WEIGHT BEAM PRICE 22tOOO $a1 t350 a1 12 OTR> If you type MODIFY or ERASE and press the RETURN key, and no existing collection has a selected record, DATATRIEVE displays a message that there is no target record for the action you propose: OTR> ERASEOO No target record for ERASE. OTR> MODIFYOO No selected record for Modify DTR> Name Recognition and Single Record Context A-17 However, if you type PRINT and press the RETURN key, and no existing collection has a selected record, DATATRIEVE displays a message that there is no selected record and then prints out the whole collection: DTR> FIND YACHTS WITH BUILDER = IALBIN"lliIT) [3 records found] DTR> PRINT@) No record selectedt printing whole collection MODEL RIG LENGTH OVER ALL WEIGHT BEAM 78 BALLAD 1.,1 EGA SLOOP SLOOP SLOOP 28 30 27 MANUFACTURER ALBIN ALBIN ALBIN 4t200 7t278 5t070 10 10 08 PRICE $17t800 $27t500 $18t800 DTR> You can change the single record context with the DROP statement. The DROP statement removes the selected record from a collection but does not erase the record from the data file. When you type DROP and press the RETURN key, and the CURRENT collection has no selected record, DATATRIEVE displays a message on your terminal: DTR> FIND BIGGIES IN YACHTS WITH LOA > 40lliIT) [8 records found] DTR> DROPlliIT) No collection with selected record for DROP. DTR> If the CURRENT collection has a selected record, the DROP statement removes that record from the collection when you type DROP and press the RETURN key. If other collections have selected records, you must specify the collection name in the DROP statement. The CURRENT collection is BIGGIES. Select and display the first record in BIGGIES and form a new CURRENT collection of boats built by Albin: DTR> SELECT; PRINTlliIT) MANUFACTURER CHALLENGER MODEL 41 RIG LENGTH OI.IER ALL WEIGHT BEAM PRICE KETCH '41 $51 t228 DTR> FIND YACHTS WITH BUILDER [3 records found] DTR> A-18 Name Recognition and Single Record Context 28t700 = IALBIN"lliIT) 13 Now select, display, and drop the first record of the CURRENT collection. Then enter a SHOW CURRENT command to see how DATATRIEVE records the results of your actions. The SELECT statement creates a single record context for the current collection, thus the target record of the PRINT statement is the selected record in the CURRENT collection, not in BIGGIES: DTR> SELECTfBIT) DTR> PRINTfBIT) MANUFACTURER ALBIN MODEL 79 RIG LENGTH OI.IER ALL WEIGHT BEAM PRICE SLOOP 26 10 $17t900 at200 DTR> DROPfBIT) DTR> SHOW CURRENT@] Collection CURRENT Domain: YACHTS Number of Records: 3 Selected Record: 1 DTR> When you drop a selected record from a collection, you change the single record context. The context block for that collection is removed from the context stack. Consequently, when you type PRINT and press the RETURN key again, DATATRIEVE displays the selected record in BIGGIES, the record in the first valid single record context: DTR> PRINTfBIT) MANUFACTURER CHALLENGER MODEL al RIG LENGTH OI.IER ALL WEIGHT BEAM PRICE KETCH al 26t700 $51 t228 13 DTR> Like PRINT, MODIFY, and ERASE, the DROP statement acts on the record in the first valid single record context. If you type PRINT and press RETURN when you have no valid single record context, DATATRIEVE displays the whole CURRENT collection because there is no selected record in either of the two existing collections. Because you dropped one record from the CURRENT collection, it contains only two records now: DTR> PRINTfBIT) No record selectedt printing whole collection MANUFACTURER ALBIN ALBIN MODEL RIG LENGTH OI.IER WEIGHT BEAM ALL BALLAD 1.IEGA SLOOP SLOOP 30 27 7t276 5t070 10 08 PRICE $27t500 $18t600 DTR> Name Recognition and Single Record Context A-19 To show that you have not erased the record dropped from the CURRENT collection, form and display a new CURRENT collection of boats by Albin: DTR> FIND YACHTS WITH BUILDER = IALBIN"tBTI) [3 records found] DTR> PRINT ALLtBTI) MODEL RIG LENGTH OI.IER ALL WEIGHT BEAM 78 BALLAD VEGA SLOOP SLOOP SLOOP 26 30 27 MANUFACTURER ALBIN ALBIN ALBIN at200 7t276 5t070 PRICE 10 10 08 $17t800 $27t500 $18t600 DTR> A.2.2 The CURRENT Collection as Target Record Stream The preceding example shows the effect of the keyword ALL on a PRINT statement that does not contain an OF rse clause. Although DATATRIEVE acts on only one record at a time, you can identify more than one record for a single DATATRIEVE statement to act on. With the keyword ALL, you can make every record in the CURRENT collection the target of a single PRINT, MODIFY, or ERASE statement. Such a statement, however, cannot also contain an OF rse clause. If you have a CURRENT collection and type PRINT ALL and press the RETURN key, DATATRIEVE displays the whole CURRENT collection. If you have no CURRENT collection, DATATRIEVE displays a message on your terminal. To illustrate this effect, release all collections and enter the statement PRINT ALL: DTR> SHOW COLLECTIONStBTI) Collections: CURRENT BIGGIES DTR> RELEASE CURRENTt BIGGIEStBTI) DTR> SHOW COLLECTIONStBTI) No established collections. DTR> PRINT ALLtBTI) A current collection has not been established. DTR> DATATRIEVE displays the same message on your terminal when you have no CURRENT collection and you enter an ERASE ALL or MODIFY ALL statement. When you have a CURRENT collection and enter an ERASE ALL statement, DATATRIEVE removes every record in the CURRENT collection from the data file. Although frequently useful, this operation can jeopardize valuable data if you use it carelessly. A-20 Name Recognition and Single Record Context Note that if your collection contains many records and you mistakenly enter an ERASE ALL or MODIFY ALL statement, you can enter CTRL/C to prevent all the records in the CURRENT collection from being erased or changed. How many records get erased or changed under such circumstances depends on the speed with which you enter CTRL/C, the processing load on your system, and the priority of your process. The various forms of the MODIFY ALL statement change the data in each record of the CURRENT collection (see theDATATRIEVE-ll Reference Manual). Make a collection of the first three yachts with no listed price. Display the CURRENT collection, modify the PRICE to $30,000, display the results of the change, and change the price back to zero using a different form of the MODIFY ALL statement: DTR> FIND FIRST 3 YACHTS WITH PRICE [3 reeD rds found] DTR> PRINT ALLm MANUFACTURER BLOCK I + BUCCANEER BUCCANEER MODEL ao 270 320 om RIG LENGTH Ot.IER ALL WEIGHT BEAM SLOOP SLOOP SLOOP 38 27 32 RIG LENGTH Ot.lER ALL WEIGHT BEAM PRICE SLOOP SLOOP SLOOP 38 27 32 18,500 5,000 12,500 12 08 10 $30,000 $30,000 $30,000 RIG LENGTH Ot.IER ALL WEIGHT BEAM PRICE SLOOP SLOOP SLOOP 38 27 32 18,500 5,000 12,500 PRICE 12 08 10 DTR> MODIFY ALL PRICEm Enter PRICE: 30,00000 DTR> PRINT ALLm MANUFACTURER BLOCK I + BUCCANEER BUCCANEER MODEL ao 270 320 DTR> MODIFY ALL USING PRICE = 0; PRINT ALLm MANUFACTURER BLOCK I + BUCCANEER BUCCANEER MODEL ao 270 320 18,500 5,000 12,500 12 08 10 DTR> A.2.3 The OF rse Clause and Target Record Streams The OF rse clause in a PRINT, ERASE, or MODIFY statement lets you create a new context for that statement. The OF rse clause specifies a target record stream that overrides any context established for your existing collections. For each such clause, DATATRIEVE puts a new block on the context stack. When DATATRIEVE completes execution of the statement, it removes that block from the context stack. Name Recognition and Single Record Context A-21 The following example contrasts the effect of PRINT, PRINT ALL, and PRINT OF rse. (When the PRINT statement does not include a list of fields, you can omit the OF from the statement.) The record selection expression here is FIRST 3 YACHTS WITH PRICE = O. This RSE identifies a new target record stream for the PRINT statement that overrides the CURRENT collection as a target " record stream. It also overrides the single record context of the selected record in the CURRENT collection: DTR> FIND FIRST 3 YACHTS(BTIJ [3 records found] DTR> SELECT; PRINT(BTIJ MANUFACTURER ALBERG MODEL RIG LENGTH OIJER ALL WEIGHT BEAM 37 MK I I KETCH 37 12 $36,851 MODEL RIG LENGTH OI.'ER ALL WEIGHT BEAM PRICE 37 MK I I 78 BALLAD KETCH SLOOP SLOOP 37 26 30 20,000 a,200 7,276 12 10 10 $36,851 $17,800 $27,500 RIG LENGTH OVER ALL WEIGHT BEAM PRICE SLOOP SLOOP SLOOP 38 27 32 PRICE 20,000 DTR> PRINT ALL(BTIJ MANUFACTURER ALBERG ALBIN ALBIN DTR> PRINT FIRST 3 YACHTS WITH PRICE MANUFACTURER BLOCK I • BUCCANEER BUCCANEER MODEL ao 270 320 O(BTIJ 18,500 5,000 12,500 12 08 10 DTR> To reduce the risk to your data, DATATRIEVE forces you to include both keywords ALL and OF when using the OF rse clause in MODIFY and ERASE statements. Although the results are not shown here, you must type MODIFY and ERASE statements to resemble the following examples. The record selection expression used in these statements is PHONES WITH DEPT = "32T": DTR> MODIFY ALL OF PHONES WITH DEPT = 132T" DTR> MODIFY ALL DEPT OF PHONES WITH DEPT = 132T" DTR> MODIFY ALL USING DEPT = _*."NEW DEPT" OF PHONES WITH DEPT DTR> ERASE ALL OF PHONES WITH DEPT A-22 Name Recognition and Single Record Context = 132T" 132T" Unless you include an assignment statement in the USING clause ofa MODIFY statement, DATATRIEVE prompts you once to supply a value for each elementary field specified or implied in the statement. After you respond to the last of the prompts, DATATRIEVE begins to change each of the records in the CURRENT collection to correspond to the values you supplied to the prompts. You can prevent any changes from taking effect by entering CTRL/Z when responding to any of the prompts. A.2.4 FOR Statements and Target Record Streams You can use FOR statements to create target record streams for the DATATRIEVE statements that use single record context. Using FOR loops has an advantage over using target record streams formed by the OF rse clause and the target record stream formed of the CURRENT collection by the keyword ALL. The FOR statement lets you work with each record individually; you do not have to perform the same operation on all target records. By putting STORE and MODIFY statements and prompting value expressions in a FOR loop, you can act on each member of a record stream or collection one at a time. When you put a MODIFY statement in a FOR statement, DATATRIEVE prompts you once for each field in the record if you do not specify a field list or a USING clause in the MODIFY statement. This FOR statement creates a record stream of boats that have no price listed. The MODIFY statement prompts you to supply a price for each record in the record stream. You can put a unique value in the PRICE field for each boat: DTR>READY YACHTS MODIFY(@) DTR>FOR YACHTS WITH PRICE En t e r PR I CE: i2900(@) En t e r PR I CE: i5S00(@) Enter PRICE: 0 MODIFY PRICE(@) DTR> Another valuable feature of FOR loops is the complex relationships you create between record streams when you include one FOR loop inside another. Each FOR statement puts a block on the context stack. As a result, you can use the· context mechanism to transfer values between records. By putting a MODIFY statement inside two FOR statements, you can automatically update master records with the data from periodic transaction records: DTR> FOR A IN DAILY_TRANSACTIONS(@) CON> FOR B IN MASTER_DATA WITH B.ACCOUNT = A.ACCOUNT(@) MODIFY USING(@) CON> BEGIN(@) CON> MASTER_BAL MASTER_BAL WITHDRAW + DEPOSIT(@) CON> TOT_WITHDRAW TOT_WITHDRAW + WITHDRAW(@) CON> TOT_DEPOSIT TOT_DEPOSIT + DEPOSIT(@) CON> END(@) CON> DTR> Name Recognition and Single Record Context A-23 The Boolean expression in this example limits the record stream for the inner FOR statement to one record. You can also create nested FOR statements in which DATATRIEVE executes a series of statements at each level of nesting. For each owner record in the next example, DATATRIEVE asks you if you want to modify the SPECS of every boat in the YACHTS inventory built by the manufacturer of the the owner's boat. The third time through the outer loop, DATATRIEVE again begins the cycle of prompting for the boats by Albin because the third person in the OWNERS domain also owns a boat by Albin. Notice that the record changed during the second loop appears during the third: DTR>SET NO PROMPT®m DTR>FOR OWNERS®m CON>BEGIN®m CON> PRINT SKIPt BUILDERt SKIP®m CON> FOR YACHTS WITH BOAT.BUILDER = OWNER.BUILDER®m CON> BEGIN®m CON> PRINT SPECS®m CON> IF *."DO YOU WANT TO CHANGE THIS" CONT lIylI®m CON> THEN MODIFY SPECS®m CON> END®m CON>END BUILDER ALBERG RIG LENGTH Ot..IER ALL WEIGHT BEAM PRICE KETCH 37 20tOOO 12 $36tOOO Enter DO YOU WANT TO CHANGE THIS: N®m ALBIN SLOOP 26 at200 10 $17t800 Enter DO YOU WANT TO CHANGE THIS: N®m SLOOP 30 7t276 10 $27t500 Enter DO YOU WANT TO CHANGE THIS: N®m SLOOP 27 5t070 08 $18t600 Enter DO YOU WANT TO CHANGE THIS: y®m Enter RIG: KETCH®m Enter LENGTH_OI.IER_ALL: 35®m It Enter DISPLACEMENT: 17000®m Enter BEAM: 12®m Enter PRICE: 33000®m (continued on next page) A-24 Name Recognition and Single Record Context ALBIN 26 at200 10 $17t800 SLOOP Enter DO YOU WANT TO CHANGE THIS: N(@) 7t276 10 $27t500 SLOOP 30 Enter DO YOU WANT TO CHANGE THIS: N(@) 35 17tOOO 12 $33tOOO KETCH Enter DO YOU WANT TO CHANGE THIS: N(@) C&C 8t650 08 SLOOP 31 Enter DO YOU WANT TO CHANGE THIS: Execution terlrlinated b }' operator DTR) ..• ..., L.. Name Recognition and Single Record Context A-25 Index A ABORT statement in command file, 10-5 Aborting procedures, 9-12 to 9-13 Access control list adding entries to, 19-11 contents, 19-1 to 19-6 control (C) privilege, 20-2 creating, 19-6 to 19-7 deleting entries, 19-11 displaying, 19-10,20-2 execute (E) privilege, 20-2 key, 19-1 to 19-6 lock type, 19-1 to 19-6 maintaining, 19-9 to 19-11, 20-6 modify (M) privilege, 20-2 privileges, 19-4 to 19-6 processing, 19-7 to 19-9 protecting data, 19-1 read (R) privilege, 20-2 sample, 19-1F sequence number, 19-1 to 19-6 write (W) privilege, 20-2 ACL See Access control list ADT See Application Design Tool ADT command, 10-3 ADVANCED HELP command, 2-7 ALLOCATION clause, 6-6 Alphanumeric fields, 5-10 AND Boolean operator, 7-8 Application Design Tool, 4-1 defining records, 5-1 Arguments in procedures, 9-4 to 9-5 Assignment statement, 11-2 AT (@) sign executing command files, 5-3 B BEGIN-END statement, 8-3 to 8-6 BETWEEN relational operator, 7-6 Boolean expressions compound, 7-8 to 7-9 Boolean operators, 7-8 Brackets [] used as syntax prompts, 2-5 BUT Boolean operator, 7-8 c Call Interface, 1-6 Case sensitivity with relational operators, 7-5 CHANGE, 6-8 Clauses in procedures, 9-4 to 9-5 Colon (:) using to invoke procedures, 1-4 Column-page setting See SET COLUMNSYAGE command Command files, 1-4, 10-1 to 10-9 aborting, 10-5 comments, 10-3 compared with procedures, 10-1 contents, 10-3 Index-1 Command files (cont.) creating, 10-2 editing, 10-5 editing with, 16-1 in FOR and REPEAT statements, 10-8 invocation command lines, 10-4 invoking, 10-3 to 10-5 maintaining, 10-8 to 10-9 nesting, 10-7 to 10-8 restrictions on invoking, 10-4 to 10-5 sample, 10-6 to 10-7 SET ABORT/SET NO ABORT, 10-5 uses, 10-1 Commands and statements, 1-3 to 1-4 in procedures, 9-4 in QUERY.INI file, 2-2 Compound statements, 1-4,8-1 to 8-6 BEGIN-END, 8-4 to 8-6 IF-THEN-ELSE in, 8-5 in REPEAT, 8-6 in STORE, 8-5 to 8-6 FOR in, 8-3 to 8-4 BEGIN-END, 8-4 REPEAT in, 8-1 to 8-3 Compressing data dictionary, 20-4 to 20-6 COMPUTED BY clause, 5-1 Computed by clause, 5-11 CON> prompt, 2-4 Conserving memory See Optimizing workspace CONTAINING relational operator, 7-5 Context, A-I establishing, A-I to A-14 Context block content of, A-2 to A-4 existing collections, A-4 to A-6 global variables, A-4 record streams, A-5 to A-7 Context stack, A-2 to A-8 lasting changes, A-6 left assignment statements, A-II Context variables, A-8 to A-II field name qualifiers, A-8 with MODIFY statement, A-13 with STORE statement, A-13 Controlling output, 18-1 to 18-5 column width, 18-1 to 18-4 Corruption of data protection against, 19-1 CREATE DICTIONARY command, 20-1 CTRL/C, 2-6 CTRL/Z exiting from DATATRIEVE, 2-6 Index-2 CURRENT as target record stream, A-20 to A-21 D Data dictionary, 1-3 access privileges, 20-2 changing, 3-2 to 3-3 contents, 3-1 to 3-2 creating, 2-2, 3-2 default extension (.DIC), 3-2 deleting definitions in, 20-4 determining size of, 20-4 displaying, 3-3, 20-2 editing definitions, 20-1 extracting from, 20-6 to 20-7 function, 3-1 maintaining, 20-1 to 20-7 modifying, 20-2 to 20-4 objects, 20-1 optimizing disk storage, 20-4 to 20-6 QCPRS utility, 20-4 security, 19-1 to 19-11 setting, 3-3 transferring definitions, 20-1 DATATRIEVE components, 1-5 to 1-7 concepts and terms, 1-1 to 1-4 Date fields, 5-11 DDMF See Distributed Server DECLARE statement, 1-3 variable-name, 11-1 Declaring variables, 11-1 Default dictionary QUERY.DIC, 20-1 DEFINE command, 1-3 DEFINE DICTIONARY command, 3-2 to 3-3 DEFINE DOMAIN command, 1-2,4-1 to 4-2 entered interactively, 5-2 optional password, 4-2 syntax, 4-2 terminated by semicolon, 4-2 usage rules, 4-2 DEFINE FILE command, 1-2,6-3 to 6-8 optional clauses, 6-6 to 6-8 syntax, 6-3 used with sequential files, 6-4 DEFINE PROCEDURE command, 1-4,9-2 DEFINE RECORD command advantage over ADT, 5-1 DEFINE TABLE command, 12-3 DEFINEP command, 1-3 Defining alternate keys, 6-5 domains, 1-2,4-1 to 4-3 records, 5-1 to 5-18 DELETE command, 1-3, 16-5 to 16-6 removing data dictionary definition, 20-4 terminated by semicolon, 20-4 DELETEP command, 1-3 DFN> prompt, 2-4 Dictionary See Data dictionary Dictionary objects controlling access to, 19-1 to 19-11 Dictionary tables See Tables Disk space conserving with QCPRS utility, 20-4 to 20-6 Displaying established collections, 20-2 readied domains, 20-2 Distributed Server function and use of, 1-5 to 1-7 Domains access all records, 7-2 defining, 1-2,3-1,4-1 to 4-3 restructuring, 15-1 to 15-9 examples, 15-2 to 15-9 rules for naming, 4-1 sample, 2-2 views, 13-1 to 13-9 defining, 13-2 DROP statement, 1-3 DTR. TSK, 1-5 DTR> prompt, 2-4 DUP, 6-8 E EDIT command, 1-3, 10-3 EDIT_STRING clause in field definition, 5-4 Editor, 16-1 to 16-14 changing record definitions, 5-3 commands, 16-4 to 16-12 DELETE command, 16-5 to 16-6 editing procedures, 9-14 EXIT command, 16-6 INSERT command, 16-6 to 16-8 invoking, 16-1 to 16-2 line pointer, 16-2 modes, 16-2 QED> prompt, 16-3 to 16-14 QUIT command, 16-8 range specifiers, 16-3 to 16-4 Editor (cont.) REPLACE command, 16-9 to 16-10 sample editing session, 16-13 to 16-14 SUBSTITUTE command, 16-10 to 16-11 TYPE command, 16-11 to 16-12 Elementary fields defined, 5-5 to 5-6 EMPLOYEE_REC valid field names, 5-7F END-PROCEDURE clause, 9-2 END-REPORTstatement (Report Writer), 2-4 END_TABLE clause, 12-3 EQUAL relational operator, 7-4 ERASE statement, 1-3 restrictions, 6-2 Error messages, 2-5 incorrectly named fields, 5-6 located by a procedure, 9-6 to 9-7 EXIT command, 1-3,2-6,16-6 Exiting DATATRIEVE, 2-6 EXTRACT command, 1-3, 9-14, 20-3 copying record definitions, 5-3 F FAMILIES sample domain, 2-2 using list field, 5-13 using SHOWP, 20-2 Field definitions, 5-3 to 5-12 clauses, 5-10 to 5-12 clauses in, 1-2 EDIT_STRING clause, 5-4 elementary fields, 5-5 to 5-6 group fields, 5-5 to 5-6 level numbers, 5-4 to 5-6 naming fields, 5-6 PICTURE clause, 5-4 rules for writing, 5-3 to 5-12 terminated by period (.),5-4 valid field names, 5-7F Field names duplicate, 5-7 to 5-8 FILLER, 5-8 to 5-9 restrictions, 5-6 to 5-7 use of hyphens or underscores, 1-2 Fields alphanumeric, 5-10 Computed by, 5-11 date, 5-11 definition clauses, 5-10 to 5-12 PICTURE, 5-10 USAGE, 5-11 to 5-12 elementary and group, 1-2 list, 5-13 Index-3 Hierarchies (cont.) saving space, 5-13 using, 5-14 to 5-18 Hyphen (-) continuation character, 5-6 conversion to underscore (_), 1-2,4-1 in record name, 5-3 Fields (cont.) naming, 5-6 numeric, 5-11 specifying types of data, 5-10 to 5-12 Files changing structure of, 15-1 to 15-9 comparison of sequential and indexed, 6-2T defining, 1-2,6-1 to 6-8 indexed, 6-1 to 6-8 criteria for using, 6-2 defining, 6-4 sequential, 6-1 to 6-7 criteria for using, 6-2 defining, 6-3 to 6-4 FILLER fields as group field name, 5-9 FIND statement, 1-3 FINISH command, 1-3 FIRST n clause in RSE, 7-3 Flat records, 5-14F FOR statement, 8-3 creating target record streams, A-23 to A-25 FROM clause, 13-2 IF-THEN-ELSE statement, 8-5 IN relational operator, 12-5 Indexed files, 6-1 to 6-8 compared with sequential, 6-2T compressing, 20-6 defining, 6-4 multi key, 6-3 optimizing storage, 20-6 Input line prompt, 2-4 INSERT command, 16-6 to 16-8 Installation kit, 2-2 Interactive DATATRIEVE, 1-5 Invoking DATATRIEVE, 2-1 to 2-2 G K Global variables, 11-4 named in context block, A-4 GREATER~QUAL relational operator, 7-6 GREATER_THAN relational operator, 7-6 Group fields as primary key, 6-5 defined, 5-5 to 5-6 using FILLER field, 5-9 Guide mode, 2-3, 2-8 invoking, 2-8 using a question mark (?), 2-8 KEY clause, 6-4 Keys accessing dictionary objects, 19-2 defining alternate keys, 6-5 defining key fields rules for, 6-6 H HELP command, 1-3, 2-6 to 2-7 ADVANCED HELP, 2-7 Hierarchies, 14-1 to 14-12 defining, 5-13 to 5-18 eliminating empty print lines, 14-9 retrieving values sublists, 14-11 to 14-12 using ALL in nested print lists, 14-5 using FIND and SELECT statements, 14-3 using nested RSEs, 14-9 using OF rse clause, 14-5 with nested FOR loops, 14-9 Index-4 L LESS~QUAL relational operator, 7-6 LESS_THAN relational operator, 7-6 Line pointer, 16-2 Lists changing length of, 5-18 defining fixed occurrences, 5-15 to 5-16 defining variable occurrences, 5-16 to 5-17 defining with OCCURS clause, 5-13 to 5-18 nesting to form sublists, 5-17 Lists, in records See Hierarchies Local variables, 11-4 to 11-5 effect on context stack, A-7 Lock types, 19-2 M MAX clause, 5-18, 6-7 Memory, conserving See Optimizing workspace MODIFY statement, 1-3, 2-5 changing fields, 6-2 N NO CHANGE, 6-8 NO DUP, 6-8 NOT Boolean operator, 7-8 NOT EQUAL relational operator, 7-4 NOT IN relational operator, 12-5 Numeric fields, 5-11 o OCCURS clause, 5-13 to 5-18 changing list length, 5-18 defining hierarchical records, 5-14 fixed number of occurrences, 5-15 to 5-16 variable number of occurrences, 5-16 to 5-17 OCCURS FOR clause, 13-2 OF rse clause targeting record streams, A-2l to A-23 Operating systems for DATATRIEVE, 1-1 Optimizing response time, 17-6 to 17-9 with keyed access, 17-6 to 17-9 workspace, 17-5 OR Boolean operator, 7-8 Output controlling, 18-1 to 18-5 default settings, 18-1 OWNERS sample domain, 2-2 p Passwords keys, 19-2 Period in field definition, 5-4 PERSONNEL sample domain, 2-2, 2-3 record data items, 5-2F PERSONNEL-REC record level numbers, 5-4 sample record definition, 5-2F PICTURE clause, 5-10 in field definition, 5-4 Pool space See Workspace PRINT statement, 1-3 lists, 14-9 retrieving data, 2-3 Privileges assigning, 19-10 Procedures, 1-4, 9-1 to 9-16 aborting, 9-12 to 9-13 comments in, 9-5 compared with command files, 10-1 contents, 3-1,9-3 to 9-5 defining, 9-1 to 9-2 deleting, 9-15 to 9-16 displaying, 9-14 editing, 9-14 to 9-15 in compound statements, 9-10 to 9-12 invoking, 9-2 to 9-3 locating errors, 9-5 to 9-7 maintaining, 9-13 to 9-16 nesting, 9-8 to 9-10 samples, 9-7 to 9-8 SET ABORT/SET NO ABORT, 9-12 to 9-13 Prompting value expressions for storing and modifying values, 2-5 Prompts CON>, 2-4 DFN>, 2-4 DTR>,2-4 RW>, 2-4 syntax, 2-5 Protecting dictionary tables, 12-9 Q QCPRS utility conserving disk space, 20-4 to 20-6 data dictionary compression, 20-4 defaults, 20-5 improving performance, 20-4 invoked by Digital Command Language, 20-5 QED> prompt, 16-3 to 16-14 Query names specifying, 5-12 QUERY.DIC default dictionary, 20-1 QUERY.INI file, 2-2 sample, 2-3 SET DICTIONARY in, 2-3 SET GUIDE in, 2-3 QUERY-HEADER clause, 5-10 QUERY~AME clause, 5-10 Question mark (?) used in Guide mode, 2-8 QUIT command, 16-8 Index-5 QXTR utility, 20-6 to 20-7 creating command files, 20-6 transferring data dictionary objects, 20-6 R READY command gaining access to domains, 1-3 retrieving data, 2-3 Record definition changing, 15-1 to 15-9 contents, 3-1 field definitions within, 5-3 to 5-12 steps in writing, 5-1 to 5-18 using OCCURS clause, 5-14 VALID IF clause, A-8 Record selection expression, 7-1 to 7-10 accessing records, 7-2 ALL clause, 7-2 Boolean expressions, 7-4 to 7-6 definition, 7-1 FIRST n clause, 7-1 to 7-3 limiting the number, 7-3 retrieving field values, 5-8 SORTED BY clause, 7-1, 7-9 to 7-10 tables, 7-7 WITH clause, 7-1, 7-4 to 7-9 record selection expression tables, 12-5 Record stream, 7-1 sorting by field values, 7-9 to 7-10 Record streams context block, A-5 to A-7 Records comparing, 7-4 to 7-6 defining, 1-2, 5-1 to 5-18 field definitions within, 5-3 to 5-12 field level numbers, 5-4 to 5-6 specifying names, 5-2 to 5-3 with variable length list, 5-16 to 5-17 deleting, 6-2 example data items, 5-2F fiat,5-14F grouping by table reference, 7-7 in range of values, 7-6 to 7-7 hierarchical, 5-14 to 5-18 limiting access, 13-3 limiting fields in a, 13-3 modifying, 6-2 rules for naming, 5-3 sample definition, 5-2F Index-6 Records (cont.) selecting conditional expressions, 7-4 REDEFINE command changing domain definitions, 15-2 to 15-9 REDEFINES clause, 5-10 Relational operators, 7-4 to 7-8 summary of, 7-7T RELEASE command, 1-3 Remote Terminal Interface, 1-6 to 1-7 REPEAT statement, 8-1 to 8-3 REPLACE command, 16-9 to 16-10 REPORT statement, 1-3 retrieving data, 2-3 to 2-4 Response time reducing with QCPRS utility, 20-4 Restructuring domains examples, 15-1 to 15-9 Retrieving data, 2-3 to 2-4 RMS facility capabilities, 6-1 to 6-3 RSE See Record selection expression RW> prompt, 2-4 s Sample editing session, 16-13 to 16-14 Security dictionary definitions, 19-1 to 19-11 Semicolon with DEFINE DOMAIN command, 4-2 with DELETE command, 20-4 Sequence numbers, 19-2 Sequential files, 6-1 to 6-7 compared with indexed, 6-2T defining, 6-3 to 6-4 SET ABORT command, 10-5, 18-4 effect on ABORT statement, 18-4 SET COLUMNS_PAGE command, 18-1 to 18-4 SET command terminal control, 1-3 SET DICTIONARY command, 3-3 in QUERY.INI file, 2-3 SET GUIDE command, 2-8, 10-3 in QUERY.INI file, 2-3 SET NO ABORT command, 10-5 SET PROMPT command, 18-4 to 18-5 SET TERMINAL command, 18-1 SHOW ALL command, 20-2 SHOW command, 1-3,2-2 with domains, 4-3 SHOW DICTIONARY command, 3-2 to 3-3 SHOW TABLES command, 12-7 SHOWP command, 1-3 SIGN clause, 5-10 Single record context, A-14 SORT statement, 1-3 SORTED BY clause, 7-9 to 7-10 Specifying domain names DEFIN.E DOMAIN command, 4-1 to 4-2 Startup banner, 2-1 Statements See Commands and statements STORE statement, 1-3,2-5 Sublists , 5-17 . retrieving values, 14-11 to 14-12 SUBSTITUTE command, 16-10 to 16-11 SUM statement, 1-3 SUPERSEDE clause, 6-7 System security using access control lists, 19-1 to 19-11 T Tables, 12-1 to 12-9 and workspace, 12-7 code/translation strings, 1-4, 12-1 to 12-6 creating, 12-3 to 12-4 defining, 3-1 defining and using, 12-4 deleting, 12-9 displaying, 12-7 displaying contents, 12-7 to 12-8 editing, 12-3 to 12-4, 12-8 functions and uses of, 1-4 !F-THEN-ELSE statement, 12-5 to 12-6 In a record selection expression, 12-5 maintaining, 12-9 protecting, 12-9 sample, 12-1 to 12-2 using IN relational operator, 12-4 VALID IF clause, 12-6 validating data, 12-6 VIA value expression, 12-6 to 12-7 WITH in, 12-5 Task size, reducing See Optimizing workspace TYPE command, 16-11 to 16-12 U UIC See User identification code Underscore (_), 1~2, 4-1 in record name, 5-3 USAGE clause, 5-10, 5-11 to 5-12 User identification code, 3-3 keys, 19-2 to 19-3 v VALID IF clause, 5-10 in record definition, A-8 Variables, 11-1 to 11-9 as counters, 11-6 to 11-9 declaring, 11-1 global, 11-4 local, 11-4 to 11-5 storing values, 11-2 to 11-6 VERIFY clause in STORE statement, A-8 VIA value expression, 12-6 to 12-7 View domains, 13-1 to 13-9 combining data, 13-4 to 13-5 containing a list, 13-7 to 13-9 defining, 13-2 limiting record access, 13-3 using, 13-6 to 13-9 w WHILE statement, 11-9 Workspace, 12-7 defined, 17-1 optimizing use of, 17-5 v YACHTS sample domain, 2-2, 2-4 access all records, 7-2 comparing records, 7-4 to 7-6 SET COLUMNS-PAGE command 18-2 to 18-4 ' Index-7 How to Order Additional Documentation If you live in: Call: or Write: New Hampshire, Alaska 603-884-6660 Digital Equipment Corp. P.O. Box CS2008 Nashua, NH 03061-2698 Continental USA, Puerto Rico, Hawaii 1-800-258-1710 Same as above. Canada (Ottawa-Hull) 613-234-7726 Digital Equipment Corp. 940 Belfast Road Ottawa, Ontario K1G 4C2 Attn: P&SG Business Manager or approved distributor Canada (British Columbia) 1-800-267-6146 Same as above. Canada (All other) 112-800-267 -6146 Same as above. All other areas Digital Equipment Corp. Peripherals & Supplies Centers P&SG Business Manager c/o DIGITAL's local subsidiary Note: Place prepaid orders from Puerto Rico with the local DIGITAL subsidiary (phone 809-754-7575). Place internal orders with the Software Distribution Center, Digital Drive, Westminster, MA 01473-0471. Reader's Comments DATATRIEVE-11 User's Guide AA-X023B-TK Please use this postage-paid form to comment on this manual. If you require a written reply to a software problem and are eligible to receive one under Software Performance Report (SPR) service, submit your comments on an SPR form. Thank you for your assistance. I rate this manual's: Accuracy (software works as manual says) Completeness (enough information) Clarity (easy to understand) Organization (structure of subject matter) Figures (useful) Examples (useful) Index (ability to find topic) Page layout (easy to find information) Excellent Good Fair Poor 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 I would like to see more/less What I like best about this manual is What I like least about this manual is I found the following errors in this manual: Page Description Additional comments or suggestions to improve this manual: I am using Version _ _ _ of the software this manual describes. Name/Title Dept. Date Company Mailing Address Phone - Do Not Tear - Fold Here and Tape -------------------n-llr-------;~;;~--- II BUSINESS REPLY MAIL FIRST CLASS PERMIT NO. 33 MAYNARD MASS. POSTAGE WILL BE PAID BY ADDRESSEE DIGITAL EQUIPMENT CORPORATION Corporate User Publications-Spit Brook ZK01-3/J35 110 SPIT BROOK ROAD NASHUA, NH 03062-9987 11111. 1111. 11.11 .11 •• 111.11.111 1.111 1•• 1. 1••• 1.1111 I - Do Not Tear - Fold Here if Mailed in the United States Reader's Comments DATATRIEVE-11 User's Guide AA-X023B- TK Please use this postage-paid form to comment on this manual. If you require a written reply to a software problem and are eligible to receive one under Software Performance Report (SPR) service, submit your comments on an SPR form. Thank you for your assistance. I rate this manual's: Accuracy (software works as manual says) Completeness (enough information) Clarity (easy to understand) Organization (structure of subject matter) Figures (useful) Examples (useful) Index (ability to find topic) Page layout (easy to find information) Excellent Good Fair Poor 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 I would like to see more/less What I like best about this manual is What I like least about this manual is I found the following errors in this manual: Page Description ; Additional comments or suggestions to improve this manual: I am using Version _ _ _ of the software this manual describes. Name/Title Dept. Date Company Mailing Address Phone - Do Not Tear - Fold Here and Tape -------------------n-llr-------;~;;~--- II BUSINESS REPLY MAIL FIRST CLASS PERMIT NO. 33 MAYNARD MASS. POSTAGE WILL BE PAID BY ADDRESSEE DIGITAL EQUIPMENT CORPORATION Corporate User Publications-Spit Brook ZK01-3/J35 110 SPIT BROOK ROAD NASHUA, NH 03062-9987 11111.1111.1111 •• 11111.1.11.1 .. 1.1111 •• 1. 1••• 1.1111 I - Do Not Tear - Fold Here if Mailed in the United States
Home
Privacy and Data
Site structure and layout ©2025 Majenko Technologies