getRecordsFromCursor

JSON DB "getRecordsFromCursor" action retrieves records from a cursor created by a "getRecords..." action

The "getRecordsFromCursor" action efficiently retrieves records from the recordset of a previously opened cursor. A cursor can jump to the beginning or end of the recordset, skip forward or backward, and retrieve records forward or backward. This action works for all FairCom products that include the FairCom database engine.

A cursor always remembers its position; thus, you can repeatedly call "getRecordsFromCursor" to retrieve additional records starting where the cursor left off. This approach makes pagination easy to implement.

A cursor is created by a call to a "getRecords..." action. All "getRecords..." actions (except for "getRecordsByIds") let you set a "returnCursor" property to true, which causes them to create a cursor and return a reference to it in the "cursorId" property. You must use this "cursorId" property in the "getRecordsFromCursor" action to retrieve records from the cursor.

To free resources on the server, you must call "closeCursor" when you no longer need a cursor.

The server automatically closes a cursor when you do not retrieve records within the number of seconds specified by the "idleCursorTimeoutSeconds" property in the "createSession" and "alterSession" actions. When you call the "getRecordsFromCursor" action, the server resets the timeout. You can set "idleCursorTimeoutSeconds" to -1 to prevent a session's cursors from timing out, but you must not fail to call "closeCursor" when you no longer need it.

 

Request examples

For a list and detailed description of the common properties in an action request message, see JSON Action request.

Minimal

{
  "action": "getRecordsFromCursor",
  "params": {
    "cursorId": "replaceWithCursorIdFromGetRecords",
    "fetchRecords": 1
  },
  "authToken": "replaceWithAuthTokenFromCreateSession"
}
 
 

Maximal

{
  "api": "db",
  "apiVersion": "1.0",
  "requestId": "2",
  "action": "getRecordsFromCursor",
  "params": {
    "cursorId": "replaceWithCursorIdFromGetRecords",
    "startFrom": "beforeFirstRecord",
"id": 2084,
"bookmark": "000000FF",
"fixedLengthCharFormat": "sql", "skipRecords": 3, "fetchRecords": 2 }, "responseOptions": {
"includeBookmarks": false, "binaryFormat": "hex", "dataFormat": "objects", "numberFormat": "string", "includeFields": [], "excludeFields": [] }, "debug": "max", "authToken": "replaceWithAuthTokenFromCreateSession" }
 
 

 

Response examples

Minimal

{
  "result": {
    "dataFormat": "objects",
    "binaryFormat": "hex",
    "fields": [
      {
        "name": "id",
        "type": "bigint",
        "length": null,
        "scale": null,
        "defaultValue": null,
        "nullable": false,
        "primaryKey": 1,
        "autoValue": "incrementOnInsert"
      },
      {
        "name": "changeId",
        "type": "bigint",
        "length": null,
        "scale": null,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "changeId"
      },
      {
        "name": "name",
        "type": "varchar",
        "length": 30,
        "scale": null,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      },
      {
        "name": "ranking",
        "type": "smallint",
        "length": null,
        "scale": null,
        "defaultValue": null,
        "nullable": false,
        "primaryKey": 0,
        "autoValue": "none"
      },
      {
        "name": "birthDate",
        "type": "date",
        "length": null,
        "scale": null,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      },
      {
        "name": "playerNumber",
        "type": "number",
        "length": 32,
        "scale": 6,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      },
      {
        "name": "livedPast2000",
        "type": "bit",
        "length": null,
        "scale": null,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      },
      {
        "name": "earnings",
        "type": "money",
        "length": 32,
        "scale": 4,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      },
      {
        "name": "favoriteSaying",
        "type": "varchar",
        "length": 500,
        "scale": null,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      }
    ],
    "data": [
      {
        "birthDate": "1963-02-17",
        "changeId": 1291366,
        "earnings": 1700000000,
        "favoriteSaying": "There is no 'i' in team but there is in win.",
        "id": 1,
        "livedPast2000": true,
        "name": "Michael Jordan",
        "playerNumber": 23,
        "ranking": 1
      }
    ],
    "primaryKeyFields": [
      "id"
    ],
    "changeIdField": "changeId",
    "moreRecords": true,
    "requestedRecordCount": 1,
    "returnedRecordCount": 1
  },
  "errorCode": 0,
  "errorMessage": "",
  "authToken": "replaceWithAuthTokenFromCreateSession"
}
 
 

Maximal

{
  "result": {
    "dataFormat": "objects",
    "binaryFormat": "hex",
    "fields": [
      {
        "name": "id",
        "type": "bigint",
        "length": null,
        "scale": null,
        "defaultValue": null,
        "nullable": false,
        "primaryKey": 1,
        "autoValue": "incrementOnInsert"
      },
      {
        "name": "changeId",
        "type": "bigint",
        "length": null,
        "scale": null,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "changeId"
      },
      {
        "name": "name",
        "type": "varchar",
        "length": 30,
        "scale": null,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      },
      {
        "name": "ranking",
        "type": "smallint",
        "length": null,
        "scale": null,
        "defaultValue": null,
        "nullable": false,
        "primaryKey": 0,
        "autoValue": "none"
      },
      {
        "name": "birthDate",
        "type": "date",
        "length": null,
        "scale": null,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      },
      {
        "name": "playerNumber",
        "type": "number",
        "length": 32,
        "scale": 6,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      },
      {
        "name": "livedPast2000",
        "type": "bit",
        "length": null,
        "scale": null,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      },
      {
        "name": "earnings",
        "type": "money",
        "length": 32,
        "scale": 4,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      },
      {
        "name": "favoriteSaying",
        "type": "varchar",
        "length": 500,
        "scale": null,
        "defaultValue": null,
        "nullable": true,
        "primaryKey": 0,
        "autoValue": "none"
      }
    ],
    "data": [
      {
        "birthDate": "1940-10-23",
        "changeId": "1291366",
        "earnings": "115000000",
        "favoriteSaying": "Everything is practice.",
        "id": "4",
        "livedPast2000": true,
        "name": "Pele",
        "playerNumber": "10",
        "ranking": "4"
      },
      {
        "birthDate": "1961-01-26",
        "changeId": "1291366",
        "earnings": "1720000",
        "favoriteSaying": "You miss 100 percent of the shots you never take.",
        "id": "5",
        "livedPast2000": true,
        "name": "Wayne Gretzky",
        "playerNumber": "99",
        "ranking": "5"
      }
    ],
    "primaryKeyFields": [
      "id"
    ],
    "changeIdField": "changeId",
    "moreRecords": true,
    "requestedRecordCount": 2,
    "returnedRecordCount": 2
  },
  "requestId": "2",
  "debugInfo": {
    "request": {
      "api": "db",
      "action": "getRecordsFromCursor",
      "params": {
        "cursorId": "cursorId",
        "startFrom": "beforeFirstRecord",
        "skipRecords": 3,
        "fetchRecords": 2
      },
      "apiVersion": "1.0",
      "requestId": "2",
      "responseOptions": {
        "binaryFormat": "hex",
        "dataFormat": "objects",
        "numberFormat": "string",
        "includeFields": [],
        "excludeFields": []
      },
      "debug": "max",
      "authToken": "replaceWithAuthTokenFromCreateSession"
    },
    "serverSuppliedValues": {
      "databaseName": null,
      "ownerName": null
    },
    "errorData": {
      "errorData": null
    },
    "warnings": []
  },
  "errorCode": 0,
  "errorMessage": "",
  "authToken": "replaceWithAuthTokenFromCreateSession"
}
 
 

 

Properties

Request properties ("params")

Property Description Default Type Limits (inclusive)

bookmark

or

_bookmark_

The "bookmark" (or in some cases "_bookmark_") property designates a universal record identifier (aka bookmark). You can always use a bookmark to identify a record, even when the table lacks a primary key. 

 

The "bookmark" value is used when "startFrom": "bookmark", in which case the user will receive records starting from the value specified by the "bookmark" property (this does not apply to "_bookmark_"). This allows applications to quickly jump to a specific record and retrieve it along with its surrounding data.

 

Using "bookmark" to position the starting record:

{
  "api": "db",
  "action": "getRecordsFromCursor",
  "params": {
    "cursorId": "replaceWithCursorIdFromGetRecords",
    "startFrom": "bookmark",
    "bookmark": "000000FF",
    "skipRecords": -3,
    "fetchRecords": 6
  },
  "responseOptions": {
    "includeBookmarks": true,
    "dataFormat":     "objects"
  },
  "authToken": "replaceWithAuthTokenFromCreateSession"
}
Optional with default of "" string 0 to 2048 bytes

cursorId

The "cursorId" property specifies a unique cursor identifier returned by the server.

  • The "getRecordsFromCursor" action uses it to quickly and efficiently retrieve paginated records.
  • Setting a zero-length "cursorId" in the request is invalid.
  • It is not returned when "returnCursor" is false.

Important Do not assume the "cursorId" is a number embedded in a string.

Required - No default value

string 0 to 225 bytes

fetchRecords

The "fetchRecords" property specifies which direction the server will fetch records. A positive integer fetches that number of records forward. A negative integer fetches that number of records backward. 

  • A value of zero is an error because it does not fetch any records.
  • Fetching around 10,000 records at a time may be the most efficient way to transfer large numbers of records.
  • Larger numbers may cause network delays and slow processing on the client. Smaller numbers require more client-server round trips.
Optional with default of null integer -2147483648 to 2147483647

fixedLengthCharFormat

The "fixedLengthCharFormat" property controls how the "getRecords" actions return values from fields with the "char" data type (CT_FSTRING), which is FairCom's fixed-length string field. It does not apply to other field types, such as "varchar", "lvarchar", "binary", "varbinary", and "lvarbinary".

 

For more details, see "fixedLengthCharFormat"

Optional with default "sql" string

"sql"

"trimTrailingSpaces"

"trimTrailingPadding"

id

The "id" property is a unique identifier automatically generated by the server. In JSON, you may use an integer number or a string containing an integer number. The server automatically generates the "id" when you create an object such as a label or thing and stores it in the table as an integer. You cannot alter the "id" value. If your application needs to specify a specific numeric identifier for a label, use the "enum" property. You can use the "id" or "thingName" properties to identify and look up a thing.

 

Automatically generated by the server integer

0 to 2147483647

0 to 9223372036854770000 in the Thing API

skipRecords

The "skipRecords" property specifies the number of records to skip over when paginating the results. It is used with "maxRecords" to paginate the results. If the value is not null or omitted, the server returns results from the beginning. If it is > 0, the server skips over the specified number of records and returns results starting from that point up until it returns the maximum number of results as defined by "maxRecords". Optional with default of 0 integer 0 to 9223372036854775807

startFrom

The "startFrom" property sets the cursor to a known position.

 

In "getRecordsByTable" and "getRecordsFromCursor" only, when "startFrom": "id" or "startFrom": "bookmark", the user will receive records starting from the value specified by the "id" or "bookmark" property. 

Optional with default of "currentPosition" string

"currentPosition"

"beforeFirstRecord"

"afterLastRecord"

"id"

"bookmark"

 

Response properties ("result")

Property Description Type Limits (inclusive)

binaryFormat

The "binaryFormat" property designates the format of binary values embedded in JSON strings. See binaryFormat for more details.  string One of the following: "base64", "hex", or "byteArray".

changeIdField

This property's value designates the name of the field used for change-tracking functionality if you are not using the "changeId" field for change tracking.

"createTable" automatically creates the "changeId" field to hold the change tracking number used for optimistic locking. Using the "changeId" field for optimistic locking is a best practice.

However, if you use the name "changeId" for another purpose, you can use the "changeIdField" property to designate a different field as the change tracking number field.

string 1 to 64 bytes

cursorid

The "cursorId" property is a unique identifier returned by the server.

  • The "getRecordsFromCursor" action uses it to quickly and efficiently retrieve paginated records.
  • It is not returned when "returnCursor" is false.

Important Do not assume the "cursorId" is a number embedded in a string.

string 0 to 255 bytes

data

The "data" property contains a response message. Its contents are defined by the action. It is an empty array when no results are available. The following is an example of the data property from a code package action.

  "result": {
    "data": [
      {
        "codeId": 6,
        "databaseName": "faircom",
        "ownerName": "admin",
        "codeName": "convertAndCategorizeTemperature",
        "codeVersion": 1,
        "clonedCodeId": 1,
        "codeStatus": "active",
        "codeLanguage": "javascript",
        "serviceName": "javascript",
        "codeType": "module",
        "description": "optional new description",
        "metadata": {},
        "createdBy": "ADMIN",
        "createdOn": "2025-08-25T21:48:38.109",
        "updatedBy": "ADMIN",
        "updatedOn": "2025-08-25T21:48:38.109",
        "comment": "Cloned from convertTemperature",
        "codeFormat": "utf8"
      },
    ]
array of objects The action determines its contents.

dataFormat

The "dataFormat" property (case-insensitive) defines the format of the "data" property. The default for "dataFormat" can be changed during a "createSession" action by assigning a different value to the "dataFormat" property in "defaultResponseOptions".

  • "dataFormat" in the response shows the client how the server formatted the "data" property.
    • Possible values include:
      • "arrays"
        • This is the default and causes the server to return results as an array of arrays, which is the most efficient.
      • "objects"
        • This returns results as an array of objects. This is less efficient but is simpler to generate, read, and troubleshoot.
string

"autoDetect"

"arrays"

"objects"

fields

The "fields" property is an array of objects. Each object in the array defines a field by specifying its properties.

 

"fields": [
  {
    "autoValue": "none",
    "name": "name",
    "type": "varchar",
    "length": 50,
    "scale": null,
    "defaultValue": null,
    "nullable": false
  }
]
array

"autoTimestamp"

"autoValue"

"primaryKey"
"name"
"type"
"length"
"scale"
"defaultValue"
"nullable"

 

updateRecords and deleteRecords only: 

"bookmark"

fields

.autoValue

The "autoValue" property indicates when and how the server automatically sets the field value. See autoValue for more details.  string

"none"

"incrementOnInsert"

"timestampOnInser"

"timestampOnUpdate"

"timestampOnUpdateAndInsert"

"changeid"

 

Some actions only:

"bookmark"

fields

.defaultValue

The "defaultValue" property specifies the default value of a field. string 0 to 65,500 bytes

fields

.length

Identifies the length of the field. integer 1 to 65500 

fields

.name

The "name" property is the name of a label or field. 

The "group" and "name" properties combined uniquely identify each label. The "createLabel" and "alterLabel" actions return an error if the "group" and "name" properties do not create a unique label name.

The "id" property also uniquely identifies each label so you can rename a label's group and name without breaking "id" references to the label.

 

string 1 to 64 bytes

fields

.nullable

"nullable" identifies whether a field can contain a NULL value. Boolean

true

false

fields

.primaryKey

When > 0, the "primaryKey" property identifies the ordinal position of the field within the table's primary key. integer 0 to 32

fields

.scale

If the type is "number" or "money", the "scale" property identifies the number of places to the right of the decimal point,. integer 0 to 32

fields

.type

Identifies the type of the field. See Data types. string

"bit"

"tinyint"

"smallint"

"integer"

"bigint"

"real"

"float"

"number"

"money"

"date"

"time"

"timestamp"

"char"

"varchar"

"lvarchar"

"binary"

"varbinary"

"lvarbinary"

"json"

moreRecords

The "moreRecords" property indicates if there are more records that match the filters in the request.  Boolean

true

false

primaryKeyFields

This property specifies the fields of the table’s primary key when multiple fields are combined to form the primary key.

Note The best practice is not to use the "primaryKeyFields" or "primaryKey" properties, so the "createTable" action will automatically create a primary key field named "id" with a unique index named "id_pk".

The order of fields in this property is the order of fields in the primary key index. The "fields" property contains the name and type of each field that is specified in the "primaryKeyFields" array. 

A primary key with multiple fields has an index named "pk". If you specify just one field, the index is named "<fieldname>_pk".

If only one field is used as the primary key, the "primaryKey" property defines the primary key.

Note The "primaryKeyFields" and "primaryKey" properties cannot be used together.

 

Example

"primaryKeyFields": [
  "a",
  "b",
  "c"
],
"fields": [
  {
    "name": "a",
    "type": "tinyint"
  },
  {
    "name": "b",
    "type": "smallint"
  },
  {
    "name": "c",
    "type": "integer"
  }
]
array an array

requestedRecordCount

The "requestedRecordCount" property is a signed, 32-bit integer set by the server in response to the "getRecordsFromCursor" method.

  • It makes it easy to know how many records were requested in the last call to "getRecordsFromCursor".
  • An application can use "requestedRecordCount" in conjunction with "returnedRecordCount" to determine if fewer records were returned than requested, which occurs when the cursor reaches the end of the recordset.
integer

0 to 2147483647

returnedRecordCount

The "returnedRecordCount" is a 32-bit integer set by the server in response to the "getRecordsFromCursor" method.

  • It makes it easy to know how many records were returned from the last call to "getRecordsFromCursor".
  • An application can use "returnedRecordCount" in conjunction with "requestedRecordCount" to determine if fewer records were returned than requested, which occurs when the cursor reaches the end of the recordset.
integer

0 to 2147483647

totalRecordCount

The "totalRecordCount" property contains the total available number of records that can be returned from a query.

  • The "totalRecordCount" is set to -1, when the server does not know the total record count.
  • A very fast way to get the total number of records in a table is to call the "getRecordsByTable" method without applying a "tableFilter". This immediately returns the count without reading and counting records.
  • For most methods, the server does not calculate "totalRecordCount" because calculating it requires walking all records in the query, which may take a significant amount of time.
  • When the result is returned as a cursor, "totalRecordCount" is the total number of records that the cursor can traverse.
    • This does not apply to cursor responses.
  • When the result returns records directly, "totalRecordCount" is the total number of records that can be retrieved – not necessarily the number of records returned.
integer

-1 to 99999999999999999999999999999999

 

How to use a cursor

Each call to the "getRecordsFromCursor" can use the "fetchRecords", "skipRecords", and "startFrom", properties to reset the cursor position, skip records, fetch one or more records, or do all of the above.

To fetch forwards, assign a positive integer number to "fetchRecords".

To fetch backward, assign a negative integer number to "fetchRecords".

To skip forwards, assign a positive integer number to "skipRecords".

To skip backward, assign a negative integer number to "skipRecords".

To reset a cursor to the beginning of the recordset, set the "startFrom" property to "beforeFirstRecord".

To reset a cursor to the end of the recordset, set the "startFrom" property to "afterLastRecord".

 

Cursor recipes

Note Some cursors are forward only, such as cursors returned from the "getRecordsFromTable" action when querying a table containing variable-length records. 

If you attempt to use a negative number for "fetchRecords" and "skipRecords" on a forward-only cursor, the "getRecordsFromCursor" returns error 48

If you need to fetch records backward, create a cursor based on an index, such as "getRecordsByIndex", "getRecordsByPartialKeyRange", "getRecordsInKeyRange", and "getRecordsStartingAtKey".

 

Troubleshooting

When you receive a cursor error that stops the cursor from working, reset the cursor position by calling "getRecordsFromCursor" with the "startFrom" property set to "beforeFirstRecord" or "afterLastRecord".

Error examples that require you to reset the cursor position:

719: Can't move to previous record in table

14703 - JSONNAV_INTERNAL_ERROR, JSONNAV_NOTYET_PARAM - A JSON Action internal error was encountered. Report this to FairCom.

Return the next ten records

Call this code repeatedly to return another ten records.

{
  "api": "db",
  "action": "getRecordsFromCursor",
  "params": {
    "fetchRecords": 10,
    "cursorId": "replaceWithValidCursorId"
    },
  "authToken": "replaceWithAuthTokenFromCreateSession"
}
Return the previous ten records

Call this code repeatedly to return another ten records.

{
  "api": "db",
  "action": "getRecordsFromCursor",
  "params": {
    "fetchRecords": -10,
    "cursorId": "replaceWithValidCursorId"
    },
  "authToken": "replaceWithAuthTokenFromCreateSession"
}
Return the first ten records

This code always returns the first ten records.

{
    "api": "db",
    "action": "getRecordsFromCursor",
    "params": {
        "startFrom": "beforeFirstRecord",
        "fetchRecords": 10,
        "cursorId": "replaceWithValidCursorId"
    },
    "authToken": "replaceWithAuthTokenFromCreateSession"
}
Tail the table

This code always returns the last ten records in forward order.

{
    "api": "db",
    "action": "getRecordsFromCursor",
    "params": {
        "startFrom": "afterLastRecord",
        "skipRecords": -11,
        "fetchRecords": 10,
        "cursorId": "replaceWithValidCursorId"
    },
    "authToken": "replaceWithAuthTokenFromCreateSession"
}
Return the last ten records in backward order

This code always returns the last ten records in backward order.

{
    "api": "db",
    "action": "getRecordsFromCursor",
    "params": {
        "startFrom": "afterLastRecord",
        "fetchRecords": -10,
        "cursorId": "replaceWithValidCursorId"
    },
    "authToken": "replaceWithAuthTokenFromCreateSession"
}
Return next ten records in backward order

Call this code repeatedly to return another ten records.

{
    "api": "db",
    "action": "getRecordsFromCursor",
    "params": {
        "skipRecords": 10,
        "fetchRecords": -10,
        "cursorId": "replaceWithValidCursorId"
    },
    "authToken": "replaceWithAuthTokenFromCreateSession"
}
Return previous ten records in forward order

Call this code repeatedly to return another ten records.

{
    "api": "db",
    "action": "getRecordsFromCursor",
    "params": {
        "skipRecords": -10,
        "fetchRecords": 10,
        "cursorId": "replaceWithValidCursorId"
    },
    "authToken": "replaceWithAuthTokenFromCreateSession"
}
Move cursor ten records forward without fetching records

Call this code repeatedly to skip the cursor.

{
    "api": "db",
    "action": "getRecordsFromCursor",
    "params": {
        "skipRecords": 10,
        "cursorId": "replaceWithValidCursorId"
    },
    "authToken": "replaceWithAuthTokenFromCreateSession"
}
Return the thousandth record

This code always returns the thousandth record in the table.

{
    "api": "db",
    "action": "getRecordsFromCursor",
    "params": {
        "startFrom": "beforeFirstRecord",
        "skipRecords": 1000,
        "fetchRecords": 1,
        "cursorId": "replaceWithValidCursorId"
    },
    "authToken": "replaceWithAuthTokenFromCreateSession"
}

 

Additional information

  • The following actions create forward-only cursors:
    • "getRecordsFromTable" creates a cursor that moves forward through every record in the table.
    • "getRecordsUsingSQL" creates a cursor that moves forward through every record returned by the SQL query.
    • If you receive error 48 when using negative numbers for skip or fetch, it indicates the cursor is forward-only. A table cursor cannot skip or fetch backward when the table contains variable-length records. If you need to fetch records backward, create a cursor based on an index, such as "getRecordsByIndex", "getRecordsByPartialKeyRange", "getRecordsInKeyRange", and "getRecordsStartingAtKey".
  • The following actions create bidirectional cursors:
    • "getRecordsByIndex" creates a cursor that moves forward or backward through every record in the index.
    • "getRecordsStartingAtKey" creates a cursor that moves forward or backward through every record in the index starting with the closest match to the key.
    • "getRecordsByPartialKeyRange" creates a cursor that moves forward or backward through every record in the index that matches the partial key.
    • "getRecordsInKeyRange" creates a cursor that moves forward or backward through every record in the index within the specified key range.
  • A cursor is always positioned before or after a record, and the fetch direction determines the cursor position.
    • When fetching forward, the cursor is positioned before a record to retrieve the record on its way forward.
    • When fetching backward, the cursor is positioned after the current record to retrieve the record on its way backward.
    • When a cursor is positioned before the first record, it cannot be moved backward.
    • When a cursor is positioned after the last record, it cannot be moved forward.
  • Calling "getRecordsFromCursor" with an expired or closed cursor, returns an error response.