# ISAM Statements > [HTML Version](isamstatements.htm) **ISAM #ch, code, key** **Parameters** _ch_ ([Num](num.htm.md)) \[in\] Channel number specified in the OPEN statement for the file. Note that a single channel is used for the combination of the IDA and the primary IDX. Secondary IDX files have their own channels. _key _ ([String](string.htm.md)) \[in/out\] A symbolic key _code_ ([Num](num.htm.md)) \[in\] A numeric code 1-8 indicating the operation to perform. | **Code** | **Operation** | **Description** | |------|------|------| | 1 | Lookup | Searches the IDX file associated with CH for the specified KEY. If not found, returns ERF(ch) = 33. Else returns ERF(ch) = 0 and sets the relative record number variable (from the OPEN statement) to match the found record. | | 2 | Get Next | Performs a get-next operation based on index position left by the previous 1, 2, or 7 statement. Sets the relative record number variable to match the fund record. Sets ERF(ch) to 38 if no more keys in sequence. KEY is not used. Generally superseded by code 7. | | 3 | Add Key | Adds the specified key to the index, associating it with the record number currently stored in the record number variable. | | 4 | Delete Key | Deletes the specified key from the index. | | 5 | Add Record | Allocates/assigns a new record in the IDA file, returning its relative record number in the record number variable. Must be followed by a WRITE\{L\} #ch, rec statement to actually write the record data to the file. | | 6 | Delete Record | Deletes the record specified by the relative record number variable from the IDA file (adding it back to the deleted record chain so that it may be reused). | | 7 | Get Next | Same as code 2 except returns the found next key in the KEY variable. | | 8 | Get Previous | A-Shell extension, added in 6.1.1344.0. Reverse of code 7. Returns ERF(ch) = 38 if no more keys (i.e. when you hit the start of the index). | **Error processing** Each of the ISAM statements returns a status which you should check using the [ERF()](filefunctions.htm.md) function. The range of values is given in the table below: | **ERF() value** | **Meaning** | |------|------| | 32 | Illegal ISAM statement code | | 33 | Key not found during key lookup | | 34 | Duplicate key during attempt to add key. Note that duplicate keys not supported by ISAM 1.x. | | 35 | IDX is corrupted and must be recreated. | | 36 | IDX file full. You've disabled the auto-expand feature (see NOAUTOX option), the disk is full, or you've reached the maximum limit of 4 billion IDX blocks. | | 37 | IDA file full. You've disabled the auto-expand feature (see NOAUTOX), the disk is full, or you've reached the maximum limit of 4 billion records.) | | 38 | End of file reached during get-next key operation, or start of file reached during get-previous key operation | | 39 | Illegal ISAM sequence. See File Locking below. | **File Locking** You must employ some kind of file locking system when allowing multi-user access to ISAM files (i.e. when the files are opened in INDEXED rather than INDEXED'EXCLUSIVE mode). Unlike ISAM-A, ISAM 1.x provides you the latitude (and responsibility) to implement the locking system. However, when [LOKSER](lokser_sp.htm.md) is enabled, it will be used and certain rules will be enforced with violations resulting in ERF(ch) returning error 39. The following table summarizes the ISAM / LOKSER behavior and rules: | **Stmt Code** | **Operation** | **Primary IDX** | **Secondary IDX** | |------|------|------|------| | 1, 2, 7, 8 | Locate record by key | Locked automatically and remains locked on return | Locked automatically during operation but unlocked on return | | 3 | Add key | Must be locked initially (typically from a previous locate record operation). Unlocked on return | Locked automatically during operation; unlocked on return | | 4 | Delete Key | Must be locked initially and remains locked on return | Locked automatically during operation; unlocked on return | | 5 | Add Data Rec | Must be locked initially; remains locked on return | Not applicable | | 6 | Delete Data Rec | Must be locked initially; remains locked on return | Not applicable | | READ | read data | Must be locked initially; unlocked on return | Not applicable | | READL | read/lock (for update) | Must be locked initially; remains locked on return | Not applicable | | WRITE | write/update data | Must be locked initially; unlocked on return. | Not applicable | | WRITEL | write new data | Must be locked initially; remains locked on return. (Normally followed by Add Key which unlocks) | Not applicable | | LOCK | Lock primary index | Locked by operation | Not applicable | | UNLOKR | Unlock record and/or index | Unlocked by operation (no harm if already unlocked) | Not applicable | **Examples** The following samples illustrate some typical operations on an ISAM file with a single primary IDX. For simplicity, all the examples use a generic routine called ISAM'ERROR for any unexpected errors. The routine should always start with an UNLOKR #CH to make sure the file isn't left in a locked state. **Add Record:** ISAM #CH, 1, KEY \! lookup key IF ERF(CH) = 0 THEN ? "Record already exists" UNLOKR #CH ELSEIF ERF(CH) # 33 THEN \! any state other than not-found GOTO ISAM'ERROR ELSE ISAM #CH, 5, KEY \! add a data record IF ERF(CH) # 0 THEN GOTO ISAM'ERROR ELSE WRITEL #CH, REC \! write the data ISAM #CH, 3, KEY \! add the key IF ERF(CH) # 0 THEN GOTO ISAM'ERROR ENDIF ENDIF ENDIF **Delete Record:** ISAM #CH, 1, KEY \! lookup key IF ERF(CH) = 33 THEN ? "Record doesn't exist" UNLOKR #CH ELSEIF ERF(CH) # 0 THEN GOTO ISAM'ERROR ELSE READL #CH, REC \! read/lock the record ISAM #CH, 4, KEY \! delete key IF ERF(CH) # 0 THEN GOTO ISAM'ERROR ELSE ISAM #CH, 6, KEY \! delete the data record IF ERF(CH) # 0 THEN GOTO ISAM'ERROR ENDIF ENDIF ENDIF **Read Record:** ISAM #CH, 1, KEY \! lookup key IF ERF(CH) = 0 THEN \! if found ... READ #CH, REC \! read rec (unlocks index) ELSE \! else ? "Key ";KEY;" not found" \! UNLOKR #CH \! manually unlock index ENDIF **Subtopics** -