Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 17 » MobiLink - Server Administration » MobiLink events » Synchronization events

download_cursor table event

A data script that defines a cursor to select rows to download and insert and update in the given table in the remote database.


In SQL scripts, you can specify event parameters by name or with a question mark. Using question marks has been deprecated. Use named parameters instead. You cannot mix names and question marks within a script. If you use question marks, the parameters must be in the order shown below and are optional only if no subsequent parameters are specified (for example, you must use parameter 1 if you are going to use parameter 2). If you use named parameters, you can specify any subset of the parameters in any order.

Parameter name for SQL scripts Description Order (deprecated for SQL)


TIMESTAMP. The last download time for the table.


s.remote_id VARCHAR(128). The MobiLink remote ID. You can only reference the remote ID if you are using named parameters. Not applicable


VARCHAR(128). The MobiLink user name.


s.script_version VARCHAR(128). Optional IN parameter to specify that the MobiLink server passes the script version string used for the current synchronization to this parameter. Question marks cannot be used to specify this parameter. Not applicable
Default action



The MobiLink server uses the script to open a read-only cursor to fetch a list of rows to download to the remote database.

You can have one download_cursor script for each table in the remote database.

To optimize performance of the download stage of synchronization to UltraLite clients, when the range of primary key values is outside the current rows on the device, you should order the rows in the download cursor by primary key. Downloads of large reference tables, for example, can benefit from this optimization.

Each download_cursor script must contain a SELECT statement or a call to a procedure that returns a result set. The MobiLink server uses this statement to define a cursor in the consolidated database.

The script must select all columns that correspond to the columns in the corresponding table in the remote database. The columns in the consolidated database can have different names than the corresponding columns in the remote database, but they must be of compatible types.

The columns must be selected in the order that the corresponding columns are defined in the remote database.

To avoid downloading unnecessary rows, consider using timestamp-based downloads. When using timestamp-based downloads, include a line similar to the following in the WHERE clause of your download_cursor script:

AND last_modified >= {ml s.last_table_download}

This script must be implemented in SQL. For Java or .NET processing of rows, use direct row handling.

If you are considering using READPAST table hints in download_cursor scripts because you are doing lots of updates that affect download performance, consider using snapshot isolation for downloads instead. The READPAST table hint can cause problems if used in download_cursor scripts. When using timestamp-based downloads, the READPAST hint can cause rows to be missed, and can cause a row to never be downloaded to a remote database. For example:

  • A row is added to the consolidated database and committed. The row has a last_modified column with a time of yesterday.

  • The same row is updated but not committed.

  • A remote database with a last_download time of last week synchronizes.

  • A download_cursor script attempts to select the row using READPAST, and skips the row.

  • The transaction that updated the row is rolled back. The next last download time for the remote is advanced to today.

From this point on, the row is never downloaded unless it is updated. A possible workaround is to implement a generate_next_last_download_timestamp or modify_next_last_download_timestamp script and set the last download time to be the start time of the oldest open transaction.

SQL example

The following example comes from an Oracle installation, although the statement is valid against all supported databases. This example downloads all rows that have been changed since the last time the user downloaded data, and that match the user name in the emp_name column.

CALL ml_add_table_script( 
  'SELECT order_id, 
   FROM ULOrder 
   WHERE last_modified >= {ml s.last_table_download} 
    AND emp_name = {ml s.username}' )