Product Documentation

FairCom ISAM for C

Previous Topic

Next Topic


Perform operations on one or more groups of records (extended version).

Short Name



ISAM function


COUNT ctDECL DoBatchXtd(FILNO keyno, pVOID request, pVOID bufptr, VRLEN bufsiz, ULONG mode);


The DoBatchXtd() function expands batch processing functionality. It supports the same parameters as the DoBatch function, however, the mode parameter is of type ULONG instead of UCOUNT. With this function, the following additional capabilities are defined for the mode parameter:

  • BAT_LKEY - Batch read in key decreasing order
  • BAT_LOK_ONE - Only locks the record during the record read. In V12 and later, BAT_LOK_ONE is active when BAT_PHYS and/or BAT_RET_REC or BAT_RET_FIX are part of the batch request mode. Other retrieval strategies, such as BAT_RET_POS, cannot be used with BAT_LOK_ONE (the batch request will fail with BTRQ_ERR, 430).
  • BAT_LOK_BLK - Converts BAT_LOK_RED and BAT_LOK_WRT to blocking read and write locks, respectively
  • BAT_PHYS - Batch read in physical order (e.g., read records in the physical order stored within the data file). This mode does not require an index.
  • BAT_RET_BLK - Return a contiguous block of records
  • BAT_RET_RAW - Turns off the conversion of record images, key values, and record positions returned by a batch retrieval call
  • BAT_RNGE - Batch read under control of range definition from ALCRNG()
  • BAT_INS - Batch record insertion into the target file. See Batch Record Insertion.
  • BAT_INP_RAW - Turns off the conversion of record images, key values, and record positions passed to a batch function
  • BAT_CLSE - When a BAT_PKEY, BAT_RNGE, BAT_GKEY, BAT_LKEY or BAT_PHYS request exhausts all the entries, either in the first call to BATSETX() or in subsequent calls, the batch will be closed immediately, and sysiocod will be set to BTNO_COD
  • BAT_UPD - The batch update call sends a series of record images and the filno parameter corresponds to a unique key index. See Batch Update Operations.
  • BAT_UPD_KEY - The record images are preceded by the key value that uniquely identifies the record to be rewritten or added. See Batch Update Operations.
  • BAT_EXTENSIONS - Use batch extended capabilities. It is available only for BAT_GET requests. If used, it must be the value of mode. Additional “modes” can be defined in the PKEYREQ2 as required.
  • BAT_UPD_KEPSRL: The batch update call preserves the original record serial number.
  • BAT_BTBZ_ERR - On BTBZ_ERR return the minimum buffer size in the bavail member of PKEYREQ.
  • BAT_REVERSE - The batch retrieval call returns results in reverse order.
  • BAT_AUGFIX - Do not specify record length in the batch buffer for variable length files having the ctAugmentedFixed mode active since all records have the same fixed size.

Before calling DoBatchXtd() with a request value of BAT_RNGE, a call must be made to ALCRNG() to establish the range criteria. After this, calls to DoBatchXtd() behave just as they would for BAT_PKEY except that the records selected satisfy the range criteria established by the call to ALCRNG(). The siglen and target members of the PKEYREQ structure are ignored by the BAT_RNGE option.

Calls to DoBatchXtd() with BAT_PHYS use a request block comprised of 5 LONG integers. The first three are the standard btotal, bavail and breturn from the PKEYREQ structure. The last two are the high-order and low-order 4-byte record positions. For the first call to DoBatchXtd(), these last two LONG integers specify the starting position for the physical retrieval. On return from the first and subsequent calls to DoBatchXtd(), these last two LONG integers specify the next record location (i.e., the physical record position following the last record included in the output buffer).

Note: This next record position is returned for informational purposes. It is not used on a subsequent call (BAT_NXT) to retrieve additional records. The starting point for the next batch is maintained internally within the batch structure.

BAT_LOK_ONE only holds a record lock while the record is read. The behavior of BAT_LOK_ONE is not explicitly controlled by BAT_PHYS but rather implicitly upon the batch strategy requested. BAT_LOK_ONE is active when BAT_PHYS and/or BAT_RET_REC or BAT_RET_FIX are part of the batch request mode. Other retrieval strategies such as BAT_RET_POS cannot be used with BAT_LOK_ONE, and the batch request will fail with FairCom DB error BTRQ_ERR (430), request is a NULL pointer.

BAT_RET_BLK can only be used with a retrieval request using BAT_PHYS or with BAT_INS. When used with retrieval, the records are returned as a contiguous block, as if they had been cut out of the data file. Fixed length records run uninterrupted, and each variable-length record is preceded by a 10-byte record header.

Calls to DoBatchXtd() with BAT_EXTENSIONS can be used to perform record filtering, column filtering, range operation, partial key requests and other features without preliminary calls that may require client/server interaction. It also resets any filters and ranges once the batch is closed. It uses a request block in the form of a PKEYREQ2 structure which has the following members:



ULONG batchmode;

The batch mode that would have been passed to the DoBatchXtd function.

ULONG batchmode2;

Further batch modes.

LONG btotal;


LONG bavail;


LONG breturn;


COUNT siglen;

The significant key len (target/utarget size in bytes) used to send range criteria together with the batch avoiding C/ roundtrips.

COUNT nsegs;

The number of segments in range, used to send range criteria together with the batch, avoiding C/ roundtrips. Set this value != 0 to perform a range request. It implies BAT_RNGE.

COUNT nfields;

The number of entries in fieldmask when instead of retrieving the entire record, only the selected field needs to be retrieved .

pTEXT target;

The partial key target or lower-range target if the range is in use. In standalone it must point to a buffer as large as the key.

pTEXT utarget;

The upper-range target if the range is in use.

pNINT operators;

The operators array for range.

pULONG fldmask;

The array of field number DODA position. The code assumes that they are in order as they appear in the record. That is, the field relative position cannot be changed.

pTEXT filter;

The filter expression to apply when retrieving records.

LONG bstartoffh;

The starting offset (high word) for BAT_PHYS.

LONG bstartoff;

The starting offset (low word) for BAT_PHYS.

Available batchmode2:

  • BAT_EXT_CHANGEBAT - on first call bavail member of the pKEYREQ2 request contains the batch number for automatic changebatch
  • BAT_EXT_FLTR_OUT - return the number of records filtered out by record filter in the first 4 bytes of the batch buffer. The returned value is the number of records filtered out in composing the batch buffer returned with the current call.

The parameters for a BAT_INS call are treated differently than for other DoBatchXtd() calls. The request parameter points to an array of 5 LONG integers (just as in a call to retrieve records using BAT_RET_BLK) and BAT_INS assumes that these five LONGs are immediately followed by a buffer containing the records to be inserted, where bufsiz specifies the size of this additional buffer in bytes. Ordinarily, bufsiz specifies the size of the output buffer pointed to by bufptr. bufptr is ignored in calls for BAT_INS. Also, only the 3rd of the 5 LONG integers (breturn) is used on input: it specifies the number of records in the buffer following the 5 LONG integers. On return from a BAT_INS call, only the DoBatchXtd() return value is significant.

Exactly one of BAT_RET_REC or BAT_RET_BLK must be OR-ed with BAT_INS to specify how the records are organized. Presumably, one would use BAT_RET_BLK if the records were retrieved using BAT_RET_BLK, and BAT_RET_REC if they were retrieved with BAT_RET_REC. When BAT_RET_REC is in use, each record is preceded by its 4 or 8-byte record location (that is ignored by BAT_INS) and then its (4-byte) length.

For transaction controlled files, the batch insertion operation is treated as all-or-nothing operation. If no explicit transaction is started, each BAT_INS call with start and end its own transaction.

Note: Even if an explicit transaction is started, each call to BAT_INS is treated independently through save points. One failed BAT_INS call does not invalidate prior or subsequent BAT_INS calls.

BATSETX Handling of Undersized Buffer Improved in V11

Calls to BATSETX did not return expected results with a small buffer. In some cases an application that used a buffer too small to hold the first record to be returned would not have an error indication. Logic has been modified to correct this situation.

Note: It is not unusual for a buffer to be too small to hold all the records being requested by the batch. However, when the first record does not fit, no record will be returned and no progress will be made on the batch request. Another call to BATSETX will need to be made with a larger buffer.

In V11 and later, a new mechanism has been provided to return the buffer size required to avoid the BTBZ_ERR. This new behavior only occurs if the BATSETX call that failed with BTBZ_ERR has BAT_BTBZ_ERR OR-ed into the BATSETX mode parameter. For example, the following BATSETX call would behave as usual if no BTBZ_ERR was returned, but the second LONG integer return value (request[1]) would have the minimum buffer size requirement for the subsequent BATSETX call to succeed (instead of bavail):

LONG request[5] = {0};

pVOID buffer[8192];

NINT rc;

rc = BATSETX(datno,request,buffer,8192,BAT_GET | BAT_PHYS |



See FairCom DB Error Codes for a complete listing of valid FairCom DB error values.

Example Use of DoBatchXtd()

The following pseudo-code shows a strategy for using DoBatchXtd retrievals from one file to load into another file with the same record format.

ULONG batmode;

LONG irq[8192];

pPKEYREQ pirq = (pPKEYREQ) irq;

COUNT retval;





** start batch retrieval at current ISAM position. [Can start at any

** legitimate record offset.]


irq[4] = GETCURP(src_datno);/* low order word */

irq[3] = ctGETHGH();/* high order word */


** first batch [0] retrieval


retval = BATSETX(src_datno,pirq,irq+5,

(VRLEN) sizeof(irq) - 5 * sizeof(LONG),batmode);


** prepare batmode for subsequent retrievals


batmode &= ~BAT_GET;

batmode |= BAT_NXT;


do {

printf("\nstatus=%d tot=%ld avl=%ld ret=%ld nxthw=%lx nxtlw=%lx",



if (retval)



** switch to batch [1] for insertion



if (BATSETX(dest_datno,pirq,0x1,

sizeof(irq) - 5 * sizeof(LONG),

BAT_INS | (batmode & (BAT_RET_REC | BAT_RET_BLK))))


printf("\nBATSETX BAT_INS: %d\n",isam_err);


} else

printf("\nBATSETX BAT_INS: success");


retval = BATSETX(src_datno,pirq,irq + 5,

(VRLEN) sizeof(irq) - 5 * sizeof(LONG),

BAT_NXT /*batmode*/);

} while (1);






See also: