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

SQL Anywhere 11.0.1 (日本語) » Mobile Link - サーバ管理 » Mobile Link イベント » 同期イベント

 

download_cursor テーブル・イベント

ダウンロードして、リモート・データベースで挿入または更新するローを選択するためのカーソルを定義します。

パラメータ

次の表の説明では、SQL データ型を示します。Java または .NET でスクリプトを作成する場合、適切なデータ型を使用してください。SQL データ型と Java データ型SQL データ型と .NET データ型を参照してください。

SQL スクリプトでは、名前または疑問符を使用してイベント・パラメータを指定できますが、スクリプト内に名前と疑問符を混在させることはできません。疑問符を使用する場合、パラメータは以下に示す順に指定する必要があり、後続のパラメータが指定されていない場合のみ省略可能です (たとえば、パラメータ 2 を使用する場合は、パラメータ 1 を使用してください)。名前付きパラメータを使用する場合は、パラメータの任意のサブセットを任意の順に指定できます。

SQL スクリプトのパラメータ名

説明

順序

s.last_table_download

TIMESTAMP。テーブルの最後のダウンロード時刻。

1

s.remote_id VARCHAR(128)。Mobile Link リモート ID。名前付きパラメータを使用している場合のみ、リモート ID を参照できます。 適用不可

s.username

VARCHAR(128)。Mobile Link ユーザ名。

2

デフォルトのアクション

なし

備考

Mobile Link サーバは読み込み専用のカーソルを開き、それを使用してリモート・データベースにダウンロードするローのリストをフェッチします。このスクリプトには、適切な SELECT 文を含めてください。

リモート・データベースのテーブルごとに、download_cursor スクリプトを 1 つ指定できます。

Ultra Light クライアントに対する同期のダウンロード処理のパフォーマンスを最適化するには、プライマリ・キー値の範囲がデバイスで指定されている現在のローの外側にある場合に、ダウンロード・カーソル内のローをプライマリ・キー順に並べてください。たとえば、大きいリファレンス・テーブルをダウンロードする場合は、このような最適化による利点が得られます。

各 download_cursor スクリプトには、SELECT 文か、SELECT 文を含むプロシージャの呼び出しが必要です。Mobile Link サーバは、SELECT 文を使用して統合データベース内でカーソルを定義します。

スクリプトでは、対応するリモート・データベース内のテーブルのカラムに対応するすべてのカラムを選択します。統合データベース内のカラムは、対応するリモート・データベースのカラムとは異なる名前にできますが、互換性のある型にしてください。

カラムは、対応するカラムがリモート・データベース内で定義されている順序に従って選択します。

download_cursor ではカスケード削除ができることに注意してください。そのため、データベースからレコードを削除できます。

不要なローのダウンロードを防ぐために、download_cursor スクリプトの WHERE 句に次の行を追加してください。

AND last_table_download > '1900/1/1'

Java アプリケーションと .NET アプリケーションの場合、このスクリプトは有効な SQL を返します。

ダウンロード・パフォーマンスに影響を与える大量の更新を行っているので、download_cursor スクリプトで READPAST テーブル・ヒントの使用を検討している場合は、代わりにダウンロードのスナップショット・アイソレーションの使用を検討してください。READPAST テーブル・ヒントは、download_cursor スクリプトで使用すると問題を引き起こす可能性があります。タイムスタンプベースのダウンロードを使用している場合は、READPAST ヒントによってローが失われ、1 つのローが一度もリモート・データベースにダウンロードされなくなる可能性があります。次に例を示します。

  • 1 つのローが統合データベースに追加され、コミットされます。そのローの last_modified カラムは、昨日の日時になっています。

  • 同じローが更新されますが、コミットはされません。

  • last_download の値が先週の日時になっているリモート・データベースと同期されます。

  • download_cursor スクリプトは READPAST を使用してローを選択しようとして、そのローをスキップします。

  • ローを更新したトランザクションはロールバックされます。リモートに対する次の最終ロード時間は今日に進められます。

この時点から、このローは更新されないかぎりダウンロードされません。回避方法として、modify_next_last_download_timestamp スクリプトを実装して、最終ダウンロード時刻を一番最初に開いたトランザクションの開始時間に設定する方法が考えられます。

参照
SQL の例

次の例は Oracle インストール環境の場合を示していますが、文はサポートされているすべてのデータベースに対して有効です。この例は、前回データをダウンロードした後に変更されたローのうち、emp_name カラム内のユーザ名と一致するローをすべてダウンロードします。

CALL ml_add_table_script( 
  'Lab',
  'ULOrder',
  'download_cursor',
  'SELECT order_id, 
    cust_id, 
    prod_id, 
    emp_id, 
    disc, 
    quant, 
    notes, 
    status
   FROM ULOrder 
   WHERE last_modified >= {ml s.last_table_download} 
    AND emp_name = {ml s.username}' )
Java の例

次の Mobile Link システム・プロシージャ・コールは、スクリプト・バージョン ver1 を同期するときに、downloadCursor という Java メソッドを download_cursor テーブル・イベント用のスクリプトとして登録します。

CALL ml_add_java_table_script(
   'ver1',
   'ULCustomer',
   'download_cursor',
   'ExamplePackage.ExampleClass.downloadCursor ' )

次に示すのは、サンプルの Java メソッド downloadCursor です。このメソッドは、last_modified カラムが最終ダウンロード時刻より遅い場合に、SQL 文をダウンロード・ローに返します。

public String downloadCursor( 
  java.sql.Timestamp ts, 
  String user )  {
  return( "SELECT cust_id, cust_name FROM ULCustomer 
             WHERE last_modified >= ' " 
   + ts + " ' ");
}
.NET の例

次の Mobile Link システム・プロシージャ・コールは、スクリプト・バージョン ver1 とテーブル table1 を同期するときに、DownloadCursor という .NET メソッドを download_cursor テーブル・イベント用のスクリプトとして登録します。

CALL ml_add_dnet_table_script(
 'ver1', 
 'table1', 
 'download_cursor',
 'TestScripts.Test.DownloadCursor'
)

次に示すのは、サンプルの .NET メソッド DownloadCursor です。このメソッドは、テンポラリ・テーブルに rows.txt というファイルの内容を設定します。その結果、Mobile Link によって、テンポラリ・テーブルのローがリモート・データベースに送信されます。これは SQL Anywhere 統合データベース用の構文です。

public string DownloadCursor( 
  DateTime ts, 
  string user ) {
  DBCommand stmt   = curConn.CreateCommand();
  StreamReader input  = new StreamReader( "rows.txt" );
  string sql    = input.ReadLine();
  stmt.CommandText = "DELETE FROM dnet_dl_temp";
  stmt.ExecuteNonQuery();
  while( sql != null ){
    stmt.CommandText = "INSERT INTO dnet_dl_temp VALUES " + sql;
    stmt.ExecuteNonQuery();
    sql = input.ReadLine();
  }
  return( "SELECT * FROM dnet_dl_temp" );
}